]> git.tdb.fi Git - libs/datafile.git/commitdiff
Use standard smart pointers for memory management
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Dec 2023 21:10:08 +0000 (23:10 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 10 Dec 2023 22:45:10 +0000 (00:45 +0200)
Collection and related classes now use std::unique_ptr to make ownership
transfers explicit.

27 files changed:
Build
source/builtinsource.cpp
source/builtinsource.h
source/collection.cpp
source/collection.h
source/collectionsource.h
source/directorysource.cpp
source/directorysource.h
source/dynamicobjectloader.h
source/input.cpp
source/input.h
source/loader.cpp
source/loader.h
source/output.cpp
source/output.h
source/packsource.cpp
source/packsource.h
source/parser.cpp
source/parser.h
source/rawdata.cpp
source/rawdata.h
source/writer.cpp
source/writer.h
tool/packer.cpp
tool/packer.h
tool/tool.cpp
tool/tool.h

diff --git a/Build b/Build
index d934f3f35da60135ad1eed2a406438f227e127f7..5e962e65896b7dded06365323b4fa6ba68878350 100644 (file)
--- a/Build
+++ b/Build
@@ -8,7 +8,7 @@ package "mspdatafile"
 
        build_info
        {
-               standard CXX "c++11";
+               standard CXX "c++14";
        };
 
        library "mspdatafile"
index 5645467bbb682075d9dc840fca094a797dfa29b0..836d15d92f45b9218601faebb9be8f78af71c4ce 100644 (file)
@@ -43,11 +43,11 @@ void BuiltinSource::load(Collection &coll, const CollectionItemTypeBase &type, c
        }
 }
 
-IO::Seekable *BuiltinSource::open(const string &name) const
+unique_ptr<IO::Seekable> BuiltinSource::open(const string &name) const
 {
        auto i = objects.find(name);
        if(i!=objects.end())
-               return new IO::Memory(i->second.data, i->second.size);
+               return make_unique<IO::Memory>(i->second.data, i->second.size);
 
        return nullptr;
 }
index 5224286e600e370567f472997d19802ad1e8e86c..1a78b14b1c8f297895f816046d68fadc9d30ab72 100644 (file)
@@ -28,7 +28,7 @@ public:
        bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override;
        NameList get_names(const CollectionItemTypeBase &) const override;
        void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override;
-       IO::Seekable *open(const std::string &) const override;
+       std::unique_ptr<IO::Seekable> open(const std::string &) const override;
 };
 
 } // namespace DataFile
index e1c25ddc914e6afd0f2be1b8e4ef198846c5c209..b9b17f43f831b4d326949884fc8685679d58726f 100644 (file)
@@ -7,12 +7,6 @@ using namespace std;
 namespace Msp {
 namespace DataFile {
 
-Collection::~Collection()
-{
-       for(CollectionItemTypeBase *t: types)
-               delete t;
-}
-
 void Collection::add_var(const string &name, const CollectionItemTypeBase *type, const Variant &var)
 {
        insert_unique(items, name, var);
@@ -100,17 +94,17 @@ unsigned Collection::get_status(const string &name, const CollectionItemTypeBase
 
 CollectionItemTypeBase *Collection::get_type(const CollectionItemTypeBase &type) const
 {
-       for(CollectionItemTypeBase *t: types)
+       for(const auto &t: types)
                if(t->is_same_type(type))
-                       return t;
+                       return t.get();
        return nullptr;
 }
 
 CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const
 {
-       for(CollectionItemTypeBase *t: types)
+       for(const auto &t: types)
                if(t->check_item_type(var))
-                       return t;
+                       return t.get();
        return nullptr;
 }
 
@@ -119,10 +113,10 @@ void Collection::add_source(const CollectionSource &s)
        sources.push_back(&s);
 }
 
-IO::Seekable *Collection::open_raw(const string &name) const
+unique_ptr<IO::Seekable> Collection::open_raw(const string &name) const
 {
        for(const CollectionSource *s: sources)
-               if(IO::Seekable *io = s->open(name))
+               if(unique_ptr<IO::Seekable> io = s->open(name))
                        return io;
 
        return nullptr;
@@ -164,17 +158,11 @@ void Collection::set_fallback(Collection *f)
 Collection::Loader::Loader(Collection &c):
        coll(c)
 {      
-       for(const CollectionItemTypeBase *t: coll.types)
+       for(const auto &t: coll.types)
                t->add_to_loader(*this);
 }
 
 
-CollectionItemTypeBase::~CollectionItemTypeBase()
-{
-       for(ExtractorBase *e: extractors)
-               delete e;
-}
-
 void CollectionItemTypeBase::set_keyword(const string &k)
 {
        kwd = k;
index 3a4bf9dde6ac961fb5a4d3516854ba36eed1caae..ad665235d94199904e6f63de5b9676c7fb894fe6 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef MSP_DATAFILE_COLLECTION_H_
 #define MSP_DATAFILE_COLLECTION_H_
 
+#include <memory>
 #include <type_traits>
 #include <msp/core/attributes.h>
 #include <msp/core/maputils.h>
 #include <msp/core/noncopyable.h>
-#include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "loader.h"
 #include "meta.h"
@@ -73,11 +73,10 @@ public:
                template<typename T, typename S>
                void item(const std::string &n)
                {
-                       RefPtr<T> it = new T;
+                       std::unique_ptr<T> it = std::make_unique<T>();
                        ItemLoader<T> ldr(*it, coll);
                        load_sub_with(ldr);
-                       coll.add<S>(n, it.get());
-                       it.release();
+                       coll.add<S>(n, std::move(it));
                }
        };
 
@@ -87,34 +86,24 @@ public:
 private:
        using ItemMap = std::map<std::string, Variant>;
 
-       std::vector<CollectionItemTypeBase *> types;
+       std::vector<std::unique_ptr<CollectionItemTypeBase>> types;
        ItemMap items;
        std::vector<const CollectionSource *> sources;
        Collection *fallback = nullptr;
 
 public:
-       virtual ~Collection();
+       virtual ~Collection() = default;
 
        /** Adds an object into the collection.  The name must not pre-exist.  The
        collection takes ownership of the object. */
        template<typename T>
-       void add(const std::string &name, T *item)
+       void add(const std::string &name, std::unique_ptr<T> item)
        {
                if(!item)
                        throw std::invalid_argument("Collection::add(item)");
 
                using NCT = typename std::remove_cv<T>::type;
-               RefPtr<NCT> ptr(item);
-               try
-               {
-                       add_var(name, get_type<NCT>(name), ptr);
-               }
-               catch(...)
-               {
-                       // Avoid deleting the object
-                       ptr.release();
-                       throw;
-               }
+               add_var(name, get_type<NCT>(name), std::shared_ptr<T>(std::move(item)));
        }
 
        /// Gets a typed object from the collection.
@@ -234,7 +223,7 @@ private:
                        return get_status(name, *type);
 
                ItemMap::const_iterator i = items.find(name);
-               return (i!=items.end() && i->second.has_type<RefPtr<T> >());
+               return (i!=items.end() && i->second.has_type<std::shared_ptr<T>>());
        }
 
 public:
@@ -253,11 +242,11 @@ public:
        template<typename T>
        const std::string &get_name(T *d) const
        {
-               using RPNCT = RefPtr<typename std::remove_cv<T>::type>;
+               using PNCT = std::shared_ptr<typename std::remove_cv<T>::type>;
 
                for(const auto &kvp: items)
-                       if(kvp.second.has_type<RPNCT>())
-                               if(kvp.second.value<RPNCT>().get()==d)
+                       if(kvp.second.has_type<PNCT>())
+                               if(kvp.second.value<PNCT>().get()==d)
                                        return kvp.first;
        
                // XXX Need better exception class
@@ -296,7 +285,7 @@ public:
        /** Opens a raw resource, without interpreting it as object data.  Null is
        returned if no such file is found.  The caller must dispose of the returned
        object when done with it. */
-       IO::Seekable *open_raw(const std::string &) const;
+       std::unique_ptr<IO::Seekable> open_raw(const std::string &) const;
 
 private:
        void gather_names_from_sources(std::list<std::string> &, const CollectionItemTypeBase &) const;
@@ -346,13 +335,10 @@ protected:
 
        std::string kwd;
        std::vector<std::string> suffixes;
-       std::vector<ExtractorBase *> extractors;
+       std::vector<std::unique_ptr<ExtractorBase>> extractors;
 
        CollectionItemTypeBase() = default;
-public:
-       virtual ~CollectionItemTypeBase();
 
-protected:
        void set_keyword(const std::string &);
        void add_suffix(const std::string &);
 public:
@@ -369,8 +355,8 @@ public:
        template<typename T>
        bool can_extract() const
        {
-               for(ExtractorBase *e: extractors)
-                       if(dynamic_cast<Extractor<T> *>(e))
+               for(const auto &e: extractors)
+                       if(dynamic_cast<Extractor<T> *>(e.get()))
                                return true;
                return false;
        }
@@ -378,8 +364,8 @@ public:
        template<typename T>
        T *extract(const Variant &var) const
        {
-               for(ExtractorBase *e: extractors)
-                       if(Extractor<T> *ex = dynamic_cast<Extractor<T> *>(e))
+               for(const auto &e: extractors)
+                       if(Extractor<T> *ex = dynamic_cast<Extractor<T> *>(e.get()))
                                return &ex->extract(var);
                return 0;
        }
@@ -398,10 +384,10 @@ private:
        struct Extractor: CollectionItemTypeBase::Extractor<B>
        {
                B &extract(const Variant &var) const override
-               { return *var.value<RefPtr<T> >(); }
+               { return *var.value<std::shared_ptr<T>>(); }
        };
 
-       std::function<T *(const std::string &)> create_func;
+       std::function<std::unique_ptr<T> (const std::string &)> create_func;
        std::vector<std::function<void(const std::string &, T &)>> notify_funcs;
 
 public:
@@ -441,7 +427,7 @@ public:
        template<typename B>
        CollectionItemType &base()
        {
-               extractors.push_back(new Extractor<B>);
+               extractors.push_back(std::make_unique<Extractor<B>>());
                return *this;
        }
 
@@ -456,7 +442,7 @@ public:
        { return dynamic_cast<const CollectionItemType<T> *>(&other); }
 
        bool check_item_type(const Variant &var) const override
-       { return var.has_type<RefPtr<T> >(); }
+       { return var.has_type<std::shared_ptr<T>>(); }
 
        void add_to_loader(Collection::Loader &) const override
        { }
@@ -468,9 +454,9 @@ public:
        {
                if(!create_func)
                        throw std::runtime_error("no creator");
-               T *obj = create_func(name);
+               std::unique_ptr<T> obj = create_func(name);
                if(obj)
-                       coll.add(name, obj);
+                       coll.add(name, move(obj));
        }
 
        void load_item(Collection &, Parser &, const std::string &) const override
@@ -480,7 +466,7 @@ public:
 
        void notify_item(const std::string &name, const Variant &var) const override
        {
-               RefPtr<T> obj = var.value<RefPtr<T> >();
+               std::shared_ptr<T> obj = var.value<std::shared_ptr<T>>();
                for(const auto &n: notify_funcs)
                        n(name, *obj);
        }
@@ -496,11 +482,10 @@ public:
 
        void load_item(Collection &coll, Parser &parser, const std::string &name) const override
        {
-               RefPtr<T> obj = new T;
+               std::unique_ptr<T> obj = std::make_unique<T>();
                Collection::ItemLoader<T> ldr(*obj, coll);
                ldr.load(parser);
-               coll.add(name, obj.get());
-               obj.release();
+               coll.add(name, std::move(obj));
        }
 };
 
@@ -508,20 +493,19 @@ public:
 template<typename T>
 T &Collection::extract(const Variant &var) const
 {
-       if(!var.has_type<RefPtr<T> >())
+       if(!var.has_type<std::shared_ptr<T>>())
                if(CollectionItemTypeBase *type = get_type_for_item(var))
                        if(T *item = type->extract<T>(var))
                                return *item;
 
-       return *var.value<RefPtr<T> >();
+       return *var.value<std::shared_ptr<T>>();
 }
 
 template<typename T>
 typename CollectionItemTypeChooser<T>::Type &Collection::add_type()
 {
-       typename CollectionItemTypeChooser<T>::Type *type = new typename CollectionItemTypeChooser<T>::Type;
-       types.push_back(type);
-       return *type;
+       types.emplace_back(std::make_unique<typename CollectionItemTypeChooser<T>::Type>());
+       return static_cast<typename CollectionItemTypeChooser<T>::Type &>(*types.back());
 }
 
 template<typename T>
@@ -537,16 +521,16 @@ typename CollectionItemTypeChooser<T>::Type &Collection::modify_type()
 template<typename T>
 CollectionItemTypeBase *Collection::get_type(const std::string &name) const
 {
-       for(CollectionItemTypeBase *t: types)
-               if(dynamic_cast<CollectionItemType<T> *>(t))
-                       return t;
+       for(const auto &t: types)
+               if(dynamic_cast<CollectionItemType<T> *>(t.get()))
+                       return t.get();
        CollectionItemTypeBase *type = nullptr;
-       for(CollectionItemTypeBase *t: types)
+       for(const auto &t: types)
                if(t->can_extract<T>())
                {
                        if(!name.empty() && t->match_name(name))
-                               return t;
-                       type = t;
+                               return t.get();
+                       type = t.get();
                }
        return type;
 }
index e2757a073432e83407a87c3cd336df882172e638..10f71baa41e48d3adce1c080141ebaa36db740ac 100644 (file)
@@ -2,6 +2,7 @@
 #define COLLECTIONSOURCE_H_
 
 #include <list>
+#include <memory>
 #include <string>
 #include <msp/io/seekable.h>
 #include "mspdatafile_api.h"
@@ -38,7 +39,7 @@ public:
 
        /** Opens a raw resource.  The caller is responsible for deleting the
        returned object when done with it. */
-       virtual IO::Seekable *open(const std::string &) const = 0;
+       virtual std::unique_ptr<IO::Seekable> open(const std::string &) const = 0;
 };
 
 } // namespace DataFile
index 7e1e438a2a49ab1ed87996ca87b806eb3e8dc18e..a933977a8535f2d35d2f914a825f993c9ba0d840 100644 (file)
@@ -40,11 +40,11 @@ void DirectorySource::load(Collection &coll, const CollectionItemTypeBase &type,
        }
 }
 
-IO::Seekable *DirectorySource::open(const string &name) const
+unique_ptr<IO::Seekable> DirectorySource::open(const string &name) const
 {
        FS::Path file;
        if(lookup_file(name, file))
-               return new IO::BufferedFile(file.str());
+               return make_unique<IO::BufferedFile>(file.str());
 
        return nullptr;
 }
index df1fc1f1b3279d3d54aba18317f607ac6ce96600..7e2066b6e0fd41613d238306b46fa04ad9299d35 100644 (file)
@@ -24,7 +24,7 @@ public:
        bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override;
        NameList get_names(const CollectionItemTypeBase &) const override;
        void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override;
-       IO::Seekable *open(const std::string &) const override;
+       std::unique_ptr<IO::Seekable> open(const std::string &) const override;
 
        bool lookup_file(const std::string &, FS::Path &) const;
 };
index fd4e153edaae60dd00a467901c43faed28432ba0..43c4b1fedf82e9f7a06d0c716879a91de30b4fca 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_DYNAMICOBJECTLOADER_H_
 #define MSP_DATAFILE_DYNAMICOBJECTLOADER_H_
 
+#include <memory>
 #include <msp/core/typeregistry.h>
 #include "collection.h"
 #include "except.h"
@@ -31,23 +32,21 @@ protected:
        using TypeRegistry = Msp::TypeRegistry<CreateObject, DynamicObjectLoader &>;
 
        Collection *coll = nullptr;
-       T *object = nullptr;
+       std::unique_ptr<T> object = nullptr;
 private:
-       Loader *obj_loader = nullptr;
-       void (*store_func)(Collection &, const std::string &, T *) = nullptr;
+       std::unique_ptr<Loader> obj_loader = nullptr;
+       void (*store_func)(Collection &, const std::string &, std::unique_ptr<T>) = nullptr;
 
        static ActionMap shared_actions;
 
 protected:
        DynamicObjectLoader(Collection *);
-public:
-       ~DynamicObjectLoader() { delete object; delete obj_loader; }
 
 private:
        void init_actions() override;
 
 public:
-       T *get_object() { T *o = object; object = 0; return o; }
+       std::unique_ptr<T> get_object() { return std::move(object); }
        T *store_object(Collection &, const std::string &);
 
 protected:
@@ -55,10 +54,10 @@ protected:
 
 private:
        template<typename U>
-       typename std::enable_if<NeedsCollection<typename U::Loader>::value, typename U::Loader *>::type create_object_loader(U &obj) const;
+       typename std::enable_if<NeedsCollection<typename U::Loader>::value, std::unique_ptr<typename U::Loader>>::type create_object_loader(U &obj) const;
 
        template<typename U>
-       typename std::enable_if<!NeedsCollection<typename U::Loader>::value, typename U::Loader *>::type create_object_loader(U &obj) const;
+       typename std::enable_if<!NeedsCollection<typename U::Loader>::value, std::unique_ptr<typename U::Loader>>::type create_object_loader(U &obj) const;
 
 protected:
        virtual const TypeRegistry &get_type_registry() const = 0;
@@ -87,9 +86,8 @@ T *DynamicObjectLoader<T, C>::store_object(Collection &c, const std::string &nam
        if(!store_func)
                throw std::logic_error("no store function");
 
-       T *o = object;
-       store_func(c, name, object);
-       object = 0;
+       T *o = object.get();
+       store_func(c, name, std::move(object));
        return o;
 }
 
@@ -104,18 +102,18 @@ void DynamicObjectLoader<T, C>::type(const Symbol &t)
 
 template<typename T, typename C>
 template<typename U>
-typename std::enable_if<NeedsCollection<typename U::Loader>::value, typename U::Loader *>::type DynamicObjectLoader<T, C>::create_object_loader(U &obj) const
+typename std::enable_if<NeedsCollection<typename U::Loader>::value, std::unique_ptr<typename U::Loader>>::type DynamicObjectLoader<T, C>::create_object_loader(U &obj) const
 {
        if(!coll)
                throw no_collection(typeid(U));
-       return new typename U::Loader(obj, *coll);
+       return std::make_unique<typename U::Loader>(obj, *coll);
 }
 
 template<typename T, typename C>
 template<typename U>
-typename std::enable_if<!NeedsCollection<typename U::Loader>::value, typename U::Loader *>::type DynamicObjectLoader<T, C>::create_object_loader(U &obj) const
+typename std::enable_if<!NeedsCollection<typename U::Loader>::value, std::unique_ptr<typename U::Loader>>::type DynamicObjectLoader<T, C>::create_object_loader(U &obj) const
 {
-       return new typename U::Loader(obj);
+       return std::make_unique<typename U::Loader>(obj);
 }
 
 
@@ -123,11 +121,10 @@ template<typename T, typename C>
 template<typename U>
 void DynamicObjectLoader<T, C>::CreateObject<U>::operator()(const std::string &, DynamicObjectLoader &ldr) const
 {
-       U *obj = new U;
-       ldr.object = obj;
-       ldr.obj_loader = ldr.create_object_loader<U>(*obj);
+       ldr.object = std::make_unique<U>();
+       ldr.obj_loader = ldr.create_object_loader<U>(static_cast<U &>(*ldr.object));
        ldr.add_auxiliary_loader(*ldr.obj_loader);
-       ldr.store_func = [](Collection &c, const std::string &n, T *o){ c.add(n, static_cast<U *>(o)); };
+       ldr.store_func = [](Collection &c, const std::string &n, std::unique_ptr<T> o){ c.add(n, std::unique_ptr<U>(static_cast<U *>(o.release()))); };
 }
 
 } // namespace DataFile
index 4496439fcd393d3898dba41c8d48a0fcba2c245c..1482e09a6efaf3674bf829513cce0d27831434a5 100644 (file)
@@ -1,6 +1,8 @@
 #include <msp/io/zlibcompressed.h>
 #include "input.h"
 
+using namespace std;
+
 namespace Msp {
 namespace DataFile {
 
@@ -8,15 +10,10 @@ Input::Input(IO::Base &i):
        in(&i)
 { }
 
-Input::~Input()
-{
-       delete compressed;
-}
-
 void Input::set_decompress()
 {
-       compressed = new IO::ZlibCompressed(*in, IO::M_READ);
-       in = compressed;
+       compressed = make_unique<IO::ZlibCompressed>(*in, IO::M_READ);
+       in = compressed.get();
 }
 
 int Input::get()
index 7f4dd7b988a3b988911797cde037ab733658e84e..c335ecc24ca44c09c6b1ec6722f4f466a387508d 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_INPUT_H_
 #define MSP_DATAFILE_INPUT_H_
 
+#include <memory>
 #include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 
@@ -11,13 +12,12 @@ class Input: private NonCopyable
 {   
 private:
        IO::Base *in = nullptr;
-       IO::Base *compressed = nullptr;
+       std::unique_ptr<IO::Base> compressed;
        unsigned line = 1;
        int next = -1;
 
 public:
        Input(IO::Base &); 
-       ~Input();
 
        void set_decompress();
        int get();
index 75638a6b50ff3532083b253bb0f98a49f7a5a6c0..afd803b21d1fe0661c5ca5ed3c65fcc2a85ccc9c 100644 (file)
@@ -167,20 +167,13 @@ void Loader::set_actions(ActionMap &a)
                init_actions();
 }
 
-void Loader::add(const string &kwd, LoaderAction *act)
+void Loader::add(const string &kwd, unique_ptr<LoaderAction> act)
 {
        if(!actions)
                actions = &local_actions;
 
        StatementKey key(kwd, act->get_signature());
-       ActionMap::iterator i = actions->find(key);
-       if(i!=actions->end())
-       {
-               delete i->second;
-               i->second = act;
-       }
-       else
-               (*actions)[key] = act;
+       (*actions)[key] = move(act);
 }
 
 void Loader::add_auxiliary_loader(Loader &ldr)
@@ -218,7 +211,7 @@ LoaderAction *Loader::find_action(const StatementKey &key) const
                int m = signature_match(key.signature, i->first.signature);
                if(m>match)
                {
-                       act = i->second;
+                       act = i->second.get();
                        match = m;
                }
        }
@@ -261,12 +254,5 @@ const string &Loader::get_keyword() const
        return cur_st->keyword;
 }
 
-
-Loader::ActionMap::~ActionMap()
-{
-       for(const auto &kvp: *this)
-               delete kvp.second;
-}
-
 } // namespace DataFile
 } // namespace Msp
index 59ebc2304c96cce8bb32f01c2199457b1b107278..0cab090184ec1f06fdece29e548a2625a3b88a3d 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef MSP_DATAFILE_LOADER_H_
 #define MSP_DATAFILE_LOADER_H_
 
-#include <type_traits>
+#include <memory>
 #include <map>
+#include <type_traits>
 #include <msp/io/file.h>
 #include "loaderaction.h"
 #include "meta.h"
@@ -38,11 +39,7 @@ See also classes ObjectLoader and CollectionObjectLoader in objectloader.h.
 class MSPDATAFILE_API Loader: private NonCopyable
 {
 protected:
-       class MSPDATAFILE_API ActionMap: public std::map<StatementKey, LoaderAction *>, private NonCopyable
-       {
-       public:
-               ~ActionMap();
-       };
+       using ActionMap = std::map<StatementKey, std::unique_ptr<LoaderAction>>;
 
 private:
        ActionMap local_actions;
@@ -104,41 +101,41 @@ protected:
        /** Adds a keyword that is loaded by calling a function. */
        template<typename L>
        void add(const std::string &k, void (L::*func)())
-       { add(k, new LoaderFunc0<L>(func)); }
+       { add(k, std::make_unique<LoaderFunc0<L>>(func)); }
 
        template<typename L, typename A0>
        void add(const std::string &k, void (L::*func)(A0))
-       { add(k, new LoaderFunc1<L, A0>(func)); }
+       { add(k, std::make_unique<LoaderFunc1<L, A0>>(func)); }
 
        template<typename L, typename... Args>
        void add(const std::string &k, void (L::*func)(Args...))
-       { add(k, new LoaderFuncN<L, Args...>(func)); }
+       { add(k, std::make_unique<LoaderFuncN<L, Args...>>(func)); }
 
        /** Adds a keyword that is loaded by calling a function with a bound
        first argument. */
        template<typename L, typename B0, typename... Args>
        void add(const std::string &k, void (L::*func)(B0, Args...), const typename std::remove_reference<B0>::type &b0)
-       { add(k, new LoaderFuncNBound1<L, B0, Args...>(func, b0)); }
+       { add(k, std::make_unique<LoaderFuncNBound1<L, B0, Args...>>(func, b0)); }
 
        template<typename L, typename B0, typename... Args>
        void add(const std::string &k, void (L::*func)(B0, Args...), B0 &&b0)
-       { add(k, new LoaderFuncNBound1<L, B0, Args...>(func, std::forward<B0>(b0))); }
+       { add(k, std::make_unique<LoaderFuncNBound1<L, B0, Args...>>(func, std::forward<B0>(b0))); }
 
        /** Adds a keyword that is loaded into a member of the loaded object. */
        template<typename L, typename T0>
        void add(const std::string &k, T0 L::*p0)
-       { add(k, new LoadValue1<L, T0>(p0)); }
+       { add(k, std::make_unique<LoadValue1<L, T0>>(p0)); }
 
        template<typename L, typename T0, typename T1>
        void add(const std::string &k, T0 L::*p0, T1 L::*p1)
-       { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
+       { add(k, std::make_unique<LoadValue2<L, T0, T1>>(p0, p1)); }
 
        /** Adds a keyword that is recognized but ignored. */
        void add(const std::string &k)
-       { add(k, new LoaderDiscard); }
+       { add(k, std::make_unique<LoaderDiscard>()); }
 
 private:
-       void add(const std::string &, LoaderAction *);
+       void add(const std::string &, std::unique_ptr<LoaderAction>);
 
 protected:
        void add_auxiliary_loader(Loader &);
@@ -185,7 +182,7 @@ followed by any extra arguments.
 template<typename T, typename... Args>
 void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &&... args)
 {
-       RefPtr<IO::Seekable> in = coll.open_raw(fn);
+       std::unique_ptr<IO::Seekable> in = coll.open_raw(fn);
        if(!in)
                throw IO::file_not_found(fn);
 
@@ -201,7 +198,7 @@ public Loader class.  Any extra arguments are passed to the Loader constructor.
 template<typename T, typename C, typename... Args>
 typename std::enable_if<!NeedsCollection<typename T::Loader>::value>::type load(T &obj, C &coll, const std::string &fn, Args &&... args)
 {
-       RefPtr<IO::Seekable> in = coll.open_raw(fn);
+       std::unique_ptr<IO::Seekable> in = coll.open_raw(fn);
        if(!in)
                throw IO::file_not_found(fn);
 
index 46d270ad7263ae5d88e656918bfe02b7528e09e8..5388716e77b682a245240b66c59773c5da9f4183 100644 (file)
@@ -10,15 +10,10 @@ Output::Output(IO::Base &o):
        out(&o)
 { }
 
-Output::~Output()
-{
-       delete compressed;
-}
-
 void Output::set_compressed()
 {
-       compressed = new IO::ZlibCompressed(*out, IO::M_WRITE);
-       out = compressed;
+       compressed = make_unique<IO::ZlibCompressed>(*out, IO::M_WRITE);
+       out = compressed.get();
 }
 
 size_t Output::put(char c)
index 4a4bc81f00377b2006aa7b15faf2452d8774e809..351e29209d5647407e495dbf51533302aa2eb9df 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_OUTPUT_H_
 #define MSP_DATAFILE_OUTPUT_H_
 
+#include <memory>
 #include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 
@@ -11,11 +12,10 @@ class Output: private NonCopyable
 {
 private:
        IO::Base *out = nullptr;
-       IO::Base *compressed = nullptr;
+       std::unique_ptr<IO::Base> compressed;
 
 public:
        Output(IO::Base &);
-       ~Output();
 
        void set_compressed();
 
index 0fb64843b305edd8839a4e93bf1bb04c9c3f33de..84cdebd933accac92bc28bfad524ffd307505727 100644 (file)
@@ -138,7 +138,7 @@ void PackSource::load(Collection &coll, const CollectionItemTypeBase &type, cons
 
        const File &file = i->second->get_file();
 
-       RefPtr<IO::Base> in = file.open();
+       unique_ptr<IO::Base> in = file.open();
        Parser parser(*in, file.get_full_name());
        if(file.is_collection())
        {
@@ -149,11 +149,11 @@ void PackSource::load(Collection &coll, const CollectionItemTypeBase &type, cons
                type.load_item(coll, parser, name);
 }
 
-IO::Seekable *PackSource::open(const string &fn) const
+unique_ptr<IO::Seekable> PackSource::open(const string &fn) const
 {
        auto i = files.find(fn);
        if(i!=files.end())
-               return i->second->open().release();
+               return i->second->open();
 
        return nullptr;
 }
@@ -216,15 +216,15 @@ PackSource::File::File(const File &other, const Pack &p):
                objects.push_back(Object(o, *this));
 }
 
-RefPtr<IO::Seekable> PackSource::File::open() const
+unique_ptr<IO::Seekable> PackSource::File::open() const
 {
        if(pack.get_io())
                // TODO Performance may be poor without buffering
-               return new IO::Slice(*pack.get_io(), pack.get_base_offset()+offset, length);
+               return make_unique<IO::Slice>(*pack.get_io(), pack.get_base_offset()+offset, length);
        else
        {
                IO::BufferedFile *io_file = new IO::BufferedFile(pack.get_filename());
-               IO::Slice *io_slice = new IO::Slice(*io_file, pack.get_base_offset()+offset, length);
+               unique_ptr<IO::Slice> io_slice = make_unique<IO::Slice>(*io_file, pack.get_base_offset()+offset, length);
                io_slice->signal_deleted.connect(sigc::bind(sigc::ptr_fun(delete_io), io_file));
                return io_slice;
        }
index c30e8f625cc53c18f3bfcea7126ed42a49f37892..16d72adf8cbed9983a0286014a59706c019a1896 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef MSP_DATAFILE_PACKSOURCE_H_
 #define MSP_DATAFILE_PACKSOURCE_H_
 
+#include <memory>
 #include <msp/core/noncopyable.h>
-#include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "mspdatafile_api.h"
 #include "objectloader.h"
@@ -90,7 +90,7 @@ private:
                File(const Pack &, const std::string &);
                File(const File &, const Pack &);
 
-               RefPtr<IO::Seekable> open() const;
+               std::unique_ptr<IO::Seekable> open() const;
                const std::string &get_filename() const { return filename; }
                FileInfo get_info() const;
                std::string get_full_name() const;
@@ -154,7 +154,7 @@ public:
        bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override;
        NameList get_names(const CollectionItemTypeBase &) const override;
        void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override;
-       IO::Seekable *open(const std::string &) const override;
+       std::unique_ptr<IO::Seekable> open(const std::string &) const override;
 };
 
 } // namespace DataFile
index e0ad8547e84e93124e2704e851ccaceaf8615af2..3dfd9ae345d8b23107b080168a5a7a899bbb134a 100644 (file)
@@ -18,15 +18,12 @@ Parser::Parser(IO::Base &i, const string &s):
 {
        char c = in.peek();
        if(c=='{' || c=='[')
-               mode = new JsonParser(in, src);
+               mode = make_unique<JsonParser>(in, src);
        else
-               mode = new TextParser(in, src);
+               mode = make_unique<TextParser>(in, src);
 }
 
-Parser::~Parser()
-{
-       delete mode;
-}
+Parser::~Parser() = default;
 
 Statement Parser::parse(bool raw)
 {
@@ -64,17 +61,13 @@ void Parser::process_control_statement(const Statement &st)
 {
        if(st.keyword=="__bin")
        {
-               delete mode;
-               mode = new BinaryParser(in, src);
+               mode = make_unique<BinaryParser>(in, src);
 
                while(in.peek()=='\n')
                        in.get();
        }
        else if(st.keyword=="__text")
-       {
-               delete mode;
-               mode = new TextParser(in, src);
-       }
+               mode = make_unique<TextParser>(in, src);
        else if(st.keyword=="__z")
                in.set_decompress();
        else if(st.keyword=="__src")
index 84ba9de32e1350d6f9bcb2ac2c452995fee4d9b0..0b87296c7b311bf2d240364a42794ff9edeeab76 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_PARSER_H_
 #define MSP_DATAFILE_PARSER_H_
 
+#include <memory>
 #include <string>
 #include <msp/core/noncopyable.h>
 #include "input.h"
@@ -27,7 +28,7 @@ private:
        std::string main_src;
        std::string src;
        bool good = true;
-       ParserMode *mode = nullptr;
+       std::unique_ptr<ParserMode> mode;
 
 public:
        Parser(IO::Base &i, const std::string &s);
index a8eb5f13fa712dfeed600f3f73cc5a9e6f349f22..7b6a01949523c3e9cf019238f6f7ff10e5b225d6 100644 (file)
@@ -15,9 +15,6 @@ const char RawData::signature[4] = { 'M', 'D', 'R', 1 };
 RawData::~RawData()
 {
        delete[] owned_data;
-       delete compressed;
-       if(in_owned)
-               delete in;
 }
 
 bool RawData::detect_signature(const std::string &sig)
@@ -30,13 +27,12 @@ void RawData::open_file(Collection &coll, const string &fn)
        if(in)
                throw logic_error("input already exists");
 
-       RefPtr<IO::Base> opened = coll.open_raw(fn);
+       unique_ptr<IO::Base> opened = coll.open_raw(fn);
        if(!opened)
                throw IO::file_not_found(fn);
 
        open_io(*opened, fn);
-       opened.release();
-       in_owned = true;
+       owned_in = move(opened);
 }
 
 void RawData::open_io(IO::Base &i, const string &fn)
@@ -60,7 +56,7 @@ void RawData::open_io(IO::Base &i, const string &fn)
        src_name = fn;
        in = &i;
        if(flags&COMPRESSED)
-               compressed = new IO::ZlibCompressed(*in, IO::M_READ);
+               compressed = make_unique<IO::ZlibCompressed>(*in, IO::M_READ);
 }
 
 void RawData::load()
@@ -81,7 +77,7 @@ void RawData::load_into(void *buffer)
 
        data = static_cast<char *>(buffer);
 
-       IO::Base *src = (compressed ? compressed : in);
+       IO::Base *src = (compressed ? compressed.get() : in);
        size_t pos = 0;
        while(pos<size)
        {
@@ -91,8 +87,7 @@ void RawData::load_into(void *buffer)
                pos += len;
        }
 
-       if(in_owned)
-               delete in;
+       owned_in.reset();
        in = nullptr;
 }
 
index c17f907b52fd015d63f077029036dec00a36a7c6..d66259f0ba5432835b03e5c2b5a9e6852c0704cc 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_RAWDATA_H_
 #define MSP_DATAFILE_RAWDATA_H_
 
+#include <memory>
 #include <string>
 #include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
@@ -20,9 +21,9 @@ private:
        };
 
        std::string src_name;
+       std::unique_ptr<IO::Base> owned_in;
        IO::Base *in = nullptr;
-       bool in_owned = false;
-       IO::Base *compressed = nullptr;
+       std::unique_ptr<IO::Base> compressed;
        std::size_t size = 0;
        char *data = nullptr;
        char *owned_data = nullptr;
index bb3ff5e9a413cae4eeff64748d0257aacc357b29..832ac12d49a1be92eddcd8cb00c176c456f8f72c 100644 (file)
@@ -11,13 +11,10 @@ namespace DataFile {
 
 Writer::Writer(IO::Base &o):
        out(o),
-       mode(new TextWriter(out))
+       mode(make_unique<TextWriter>(out))
 { }
 
-Writer::~Writer()
-{
-       delete mode;
-}
+Writer::~Writer() = default;
 
 void Writer::write(const Statement &st)
 {
@@ -39,11 +36,10 @@ void Writer::set_binary(bool b)
 
        mode->write(st);
 
-       delete mode;
        if(binary)
-               mode = new BinaryWriter(out);
+               mode = make_unique<BinaryWriter>(out);
        else
-               mode = new TextWriter(out);
+               mode = make_unique<TextWriter>(out);
 }
 
 void Writer::set_compressed()
index 05ab369f439e3d94bf3d94e5a2a6b04364c9b914..a3c5257fd4b1a0a91253f092ec6f8a727bea7aa9 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_DATAFILE_WRITER_H_
 
 #include <map>
+#include <memory>
 #include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 #include "mspdatafile_api.h"
@@ -20,7 +21,7 @@ class MSPDATAFILE_API Writer: private NonCopyable
 {
 private:
        Output out;
-       WriterMode *mode = nullptr;
+       std::unique_ptr<WriterMode> mode;
        bool binary = false;
 
 public:
index 3f175d91e5fb8230f00dc73238e25965ca1dd88d..dddf81dd5f8c2fd5ddc9148a097f405b73d49667 100644 (file)
@@ -17,7 +17,7 @@ Packer::Packer(DataTool &t):
        tmp_file(tempfile(tmp_path))
 { }
 
-IO::BufferedFile *Packer::tempfile(FS::Path &out_fn)
+unique_ptr<IO::BufferedFile> Packer::tempfile(FS::Path &out_fn)
 {
        FS::Path tmpdir = FS::get_temp_dir();
 
@@ -26,7 +26,7 @@ IO::BufferedFile *Packer::tempfile(FS::Path &out_fn)
                try
                {
                        FS::Path filename = tmpdir/format("mspdatatool.%d", i);
-                       IO::BufferedFile *file = new IO::BufferedFile(filename.str(), IO::M_RDWR, IO::File::C_NEW);
+                       unique_ptr<IO::BufferedFile> file = make_unique<IO::BufferedFile>(filename.str(), IO::M_RDWR, IO::File::C_NEW);
                        out_fn = filename;
                        return file;
                }
@@ -39,7 +39,7 @@ IO::BufferedFile *Packer::tempfile(FS::Path &out_fn)
 
 Packer::~Packer()
 {
-       delete tmp_file;
+       tmp_file.reset();
        FS::unlink(tmp_path);
 }
 
@@ -103,7 +103,7 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob
 {
        DataFile::Parser parser(in, fn);
 
-       DataFile::Writer *writer = tool.create_writer(out);
+       unique_ptr<DataFile::Writer> writer = tool.create_writer(out);
 
        bool collection = FS::extpart(fn)==".mdc";
        while(parser)
@@ -128,7 +128,6 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob
                }
        }
        writer->write(DataFile::Statement("__end"));
-       delete writer;
 }
 
 void Packer::transfer_raw_data(IO::Base &in, const string &fn, IO::Base &out)
@@ -161,7 +160,7 @@ void Packer::create_pack(const string &fn)
        {
                mem.seek(0, IO::S_BEG);
 
-               DataFile::Writer *writer = tool.create_writer(mem);
+               unique_ptr<DataFile::Writer> writer = tool.create_writer(mem);
 
                for(list<DataFile::Statement>::const_iterator i=directory.begin(); i!=directory.end(); ++i)
                        writer->write(*i);
@@ -169,7 +168,7 @@ void Packer::create_pack(const string &fn)
                        base_offset = mem.tell();
                writer->write((DataFile::Statement("base_offset"), base_offset));
                writer->write(DataFile::Statement("__end"));
-               delete writer;
+               writer.reset();
 
                unsigned dir_size = mem.tell();
                if(dir_size<=base_offset)
index 141a2a1058dc1323ec1d6fc63e35c9e8e5e69dbe..4e370de0987a8f06c42501a5dd8fb2c0c9b2f5e4 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef PACKER_H_
 #define PACKER_H_
 
+#include <memory>
 #include <string>
 #include <msp/datafile/statement.h>
 #include <msp/io/buffered.h>
@@ -21,14 +22,14 @@ private:
 
        DataTool &tool;
        Msp::FS::Path tmp_path;
-       Msp::IO::BufferedFile *tmp_file = nullptr;
+       std::unique_ptr<Msp::IO::BufferedFile> tmp_file;
        std::list<Msp::DataFile::Statement> directory;
        unsigned dir_alloc = 0;
 
 public:
        Packer(DataTool &);
 private:
-       static Msp::IO::BufferedFile *tempfile(Msp::FS::Path &);
+       static std::unique_ptr<Msp::IO::BufferedFile> tempfile(Msp::FS::Path &);
 public:
        ~Packer();
 
index cf34474338e5c63fe7ae07139e0822ebdd3e0c68..a6b094475946cc9e6b56759c5c9c473f0df30711 100644 (file)
@@ -74,12 +74,12 @@ int DataTool::main()
 
 void DataTool::do_transfer()
 {
-       IO::Base *out = open_output(out_fn);
-       DataFile::Writer *writer = create_writer(*out);
+       unique_ptr<IO::Base> out = open_output(out_fn);
+       unique_ptr<DataFile::Writer> writer = create_writer(*out);
 
        for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
        {
-               IO::Base *in = open_input(*i);
+               unique_ptr<IO::Base> in = open_input(*i);
                DataFile::Parser parser(*in, *i);
 
                while(parser)
@@ -88,30 +88,21 @@ void DataTool::do_transfer()
                        if(st.valid && (!st.control || st.keyword=="__src" || debug))
                                writer->write(st);
                }
-
-               delete in;
        }
-
-       delete writer;
-       delete out;
 }
 
 void DataTool::do_compile()
 {
-       IO::Base *out = open_output(out_fn);
-       DataFile::Writer *writer = create_writer(*out);
+       unique_ptr<IO::Base> out = open_output(out_fn);
+       unique_ptr<DataFile::Writer> writer = create_writer(*out);
 
        Compiler compiler(*writer);
        for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
        {
-               IO::Base *in = open_input(*i);
+               unique_ptr<IO::Base> in = open_input(*i);
                DataFile::Parser parser(*in, *i);
                compiler.load(parser);
-               delete in;
        }
-
-       delete writer;
-       delete out;
 }
 
 void DataTool::do_pack()
@@ -131,8 +122,8 @@ void DataTool::do_unpack()
        list<DataFile::PackSource::FileInfo> files = source.list_files();
        for(list<DataFile::PackSource::FileInfo>::const_iterator i=files.begin(); i!=files.end(); ++i)
        {
-               IO::Seekable *in = source.open(i->name);
-               IO::Base *out = open_output(i->name);
+               unique_ptr<IO::Seekable> in = source.open(i->name);
+               unique_ptr<IO::Base> out = open_output(i->name);
                char buf[16384];
                while(1)
                {
@@ -141,41 +132,38 @@ void DataTool::do_unpack()
                        if(len<sizeof(buf))
                                break;
                }
-               delete in;
-               delete out;
        }
 }
 
 void DataTool::do_generate_builtin()
 {
-       IO::Base *out = open_output(out_fn);
+       unique_ptr<IO::Base> out = open_output(out_fn);
        BuiltinGenerator generator(*out);
        generator.begin(builtin_ns);
        for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
                generator.add_file(*i);
        generator.end(builtin_module);
-       delete out;
 }
 
-IO::Base *DataTool::open_output(const string &fn)
+unique_ptr<IO::Base> DataTool::open_output(const string &fn)
 {
        if(fn=="-")
-               return new IO::Buffered(IO::cout);
+               return make_unique<IO::Buffered>(IO::cout);
        else
-               return new IO::BufferedFile(fn, IO::M_WRITE);
+               return make_unique<IO::BufferedFile>(fn, IO::M_WRITE);
 }
 
-IO::Base *DataTool::open_input(const string &fn)
+unique_ptr<IO::Base> DataTool::open_input(const string &fn)
 {
        if(fn=="-")
-               return new IO::Buffered(IO::cin);
+               return make_unique<IO::Buffered>(IO::cin);
        else
-               return new IO::BufferedFile(fn, IO::M_READ);
+               return make_unique<IO::BufferedFile>(fn, IO::M_READ);
 }
 
-DataFile::Writer *DataTool::create_writer(IO::Base &out)
+unique_ptr<DataFile::Writer> DataTool::create_writer(IO::Base &out)
 {
-       DataFile::Writer *writer = new DataFile::Writer(out);
+       unique_ptr<DataFile::Writer> writer = make_unique<DataFile::Writer>(out);
        if(compress)
                writer->set_compressed();
        if(binary)
index 2012429714b311d1f45ac72ad0a3788fd20bfcf0..f14658ba77416ebd902734fb860d4f74ad8b300d 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef TOOL_H_
 #define TOOL_H_
 
+#include <memory>
 #include <string>
 #include <msp/core/application.h>
 #include <msp/datafile/writer.h>
@@ -31,11 +32,11 @@ private:
        void do_pack();
        void do_unpack();
        void do_generate_builtin();
-       Msp::IO::Base *open_output(const std::string &);
-       Msp::IO::Base *open_input(const std::string &);
+       std::unique_ptr<Msp::IO::Base> open_output(const std::string &);
+       std::unique_ptr<Msp::IO::Base> open_input(const std::string &);
 public:
        bool is_compressed() const { return compress; }
-       Msp::DataFile::Writer *create_writer(Msp::IO::Base &);
+       std::unique_ptr<Msp::DataFile::Writer> create_writer(Msp::IO::Base &);
 };
 
 #endif