[mathic] 47/62: Replaced uses of std::auto_ptr with std::unique_ptr. Also got rid of ElementDeleter, since it is no longer relevant now that std::unique_ptr exists.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Wed Apr 1 11:36:23 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository mathic.

commit 2e756b20bb303b26819217f5ffbb8534a054f0ef
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Tue Feb 5 13:09:03 2013 +0100

    Replaced uses of std::auto_ptr with std::unique_ptr. Also got rid of ElementDeleter, since it is no longer relevant now that std::unique_ptr exists.
---
 Makefile.am                  |   2 +-
 src/mathic.h                 |   1 -
 src/mathic/CliParser.cpp     |  20 +++----
 src/mathic/CliParser.h       |   6 +-
 src/mathic/ColumnPrinter.cpp |  12 +---
 src/mathic/ColumnPrinter.h   |   3 +-
 src/mathic/ElementDeleter.h  | 138 -------------------------------------------
 src/mathic/HelpAction.cpp    |   2 +-
 src/mathic/NameFactory.h     |  24 ++++----
 9 files changed, 29 insertions(+), 179 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 3c12478..d942ec5 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,7 +45,7 @@ mathicB_include_HEADERS = src/mathic/Action.h src/mathic/Geobucket.h	\
   src/mathic/NameFactory.h src/mathic/display.h							\
   src/mathic/PackedKDTree.h src/mathic/DivFinder.h src/mathic/stdinc.h	\
   src/mathic/DivList.h src/mathic/StlSet.h src/mathic/DivMask.h			\
-  src/mathic/StringParameter.h src/mathic/ElementDeleter.h				\
+  src/mathic/StringParameter.h				\
   src/mathic/Timer.h src/mathic/error.h src/mathic/TourTree.h			\
   src/mathic/BitTriangle.h \
   src/mathic/PairQueue.h \
diff --git a/src/mathic.h b/src/mathic.h
index 982188a..2e92538 100755
--- a/src/mathic.h
+++ b/src/mathic.h
@@ -3,7 +3,6 @@
 // utilities
 #include "mathic/Timer.h"
 #include "mathic/ColumnPrinter.h"
-#include "mathic/ElementDeleter.h"
 #include "mathic/error.h"
 
 // other data structures
diff --git a/src/mathic/CliParser.cpp b/src/mathic/CliParser.cpp
index 6e6af75..e45b457 100644
--- a/src/mathic/CliParser.cpp
+++ b/src/mathic/CliParser.cpp
@@ -10,15 +10,11 @@ namespace mathic {
     typedef void* Dummy;
     typedef NameFactory<Dummy> ParamNames;
     ParamNames makeParamNames(std::vector<CliParameter*> params) {
-      struct HoldsFunction { // work around for no local functions in old C++
-        static std::auto_ptr<Dummy> dummyCreate() {
-          return std::auto_ptr<Dummy>(0);
-        }
-      };
-
       ParamNames names("option");
-      for (size_t i = 0; i < params.size(); ++i)
-        names.registerProduct(params[i]->name(), HoldsFunction::dummyCreate);
+      for (size_t i = 0; i < params.size(); ++i) {
+        const auto makeNull = [](){return std::unique_ptr<Dummy>();};
+        names.registerProduct(params[i]->name(), makeNull);
+      }
       return names;
     }
   }
@@ -32,22 +28,22 @@ namespace mathic {
 
   CliParser::CliParser(): _actions("action") {}
 
-  std::auto_ptr<Action> CliParser::createActionWithPrefix(
+  std::unique_ptr<Action> CliParser::createActionWithPrefix(
     const std::string& prefix
   ) {
     return createWithPrefix(_actions, prefix);
   }
 
-  std::auto_ptr<Action> CliParser::parse(int argc, char** argv) {
+  std::unique_ptr<Action> CliParser::parse(int argc, char** argv) {
     std::vector<std::string> commandLine(argv, argv + argc);
     return parse(commandLine);
   }
 
-  std::auto_ptr<Action> CliParser::parse
+  std::unique_ptr<Action> CliParser::parse
     (const std::vector<std::string>& commandLine) {
     if (commandLine.empty())
       throwError<UnknownNameException>("No action specified.");
-    std::auto_ptr<Action> action = createActionWithPrefix(commandLine[0]);
+    std::unique_ptr<Action> action = createActionWithPrefix(commandLine[0]);
 
     std::vector<CliParameter*> params;
     action->pushBackParameters(params);
diff --git a/src/mathic/CliParser.h b/src/mathic/CliParser.h
index 22fcb42..29ede1a 100644
--- a/src/mathic/CliParser.h
+++ b/src/mathic/CliParser.h
@@ -26,9 +26,9 @@ namespace mathic {
     const std::string& helpPreMessage() const {return _helpPreMessage;}
     const std::string& helpPostMessage() const {return _helpPostMessage;}
 
-    std::auto_ptr<Action> parse(int argc, char** argv);
-    std::auto_ptr<Action> parse(const std::vector<std::string>& commandLine);
-    std::auto_ptr<Action> createActionWithPrefix(const std::string& prefix);
+    std::unique_ptr<Action> parse(int argc, char** argv);
+    std::unique_ptr<Action> parse(const std::vector<std::string>& commandLine);
+    std::unique_ptr<Action> createActionWithPrefix(const std::string& prefix);
 
   private:
     NameFactory<Action> _actions;
diff --git a/src/mathic/ColumnPrinter.cpp b/src/mathic/ColumnPrinter.cpp
index 6e51b39..c889883 100755
--- a/src/mathic/ColumnPrinter.cpp
+++ b/src/mathic/ColumnPrinter.cpp
@@ -25,12 +25,6 @@ namespace mathic {
 	}
   }
 
-  ColumnPrinter::~ColumnPrinter() {
-	for (std::vector<Col*>::iterator it = _cols.begin();
-		 it != _cols.end(); ++it)
-	  delete *it;
-  }
-
   void ColumnPrinter::setPrefix(const std::string& prefix) {
 	_prefix = prefix;
   }
@@ -38,13 +32,13 @@ namespace mathic {
   std::ostream& ColumnPrinter::addColumn(bool flushLeft,
 								const std::string& prefix,
 								const std::string& suffix) {
-	std::auto_ptr<Col> col(new Col());
+	std::unique_ptr<Col> col(new Col());
 	col->prefix = prefix;
 	col->suffix = suffix;
 	col->flushLeft = flushLeft;
 
-	_cols.push_back(0);
-	_cols.back() = col.release(); // push_back didn't throw, so safe to release
+	_cols.emplace_back(std::move(col));
+
     return _cols.back()->text;
   }
 
diff --git a/src/mathic/ColumnPrinter.h b/src/mathic/ColumnPrinter.h
index 5c46458..128c8e4 100755
--- a/src/mathic/ColumnPrinter.h
+++ b/src/mathic/ColumnPrinter.h
@@ -12,7 +12,6 @@ namespace mathic {
   class ColumnPrinter {
   public:
 	ColumnPrinter(size_t columnCount = 0);
-	~ColumnPrinter();
 
 	void setPrefix(const std::string& prefix);
 	std::ostream& addColumn(
@@ -78,7 +77,7 @@ namespace mathic {
 	  bool flushLeft;
       std::vector<std::pair<size_t, char> > repeatToEndOfLine;
 	};
-	std::vector<Col*> _cols;
+	std::vector<std::unique_ptr<Col>> _cols;
 	std::string _prefix;
   };
 
diff --git a/src/mathic/ElementDeleter.h b/src/mathic/ElementDeleter.h
deleted file mode 100755
index 9de80ab..0000000
--- a/src/mathic/ElementDeleter.h
+++ /dev/null
@@ -1,138 +0,0 @@
-#ifndef MATHIC_ELEMENT_DELETER_GUARD
-#define MATHIC_ELEMENT_DELETER_GUARD
-
-#include "stdinc.h"
-#include <memory>
-
-namespace mathic {
-  // The purpose of this class is to call delete on the elements of a
-  // standard library container which holds pointers. It removes the
-  // elements from the container as they are being deleted, but it does
-  // not delete the container itself. Do not use this class to
-  // deallocate a vector of built-in arrays, since those require
-  // deallocation using delete[] rather than delete.
-  //
-  // This can be a convenience when coding, but the real purpose is to
-  // avoid memory leaks in the face of an exception being thrown. When a
-  // standard library container goes out of scope, its destructor is
-  // called, but the destructor does not deallocate pointer elements, so
-  // they will leak unless special care is taken to avoid that, such as
-  // using this class.
-  //
-  // The most straight-forward solution may seem to use
-  // e.g. vector<auto_ptr<T>> in place of vector<T*>, but this does not
-  // work because storing auto_ptr<T> in a standard library container is
-  // never safe (look this up on the internet to get the details).
-  //
-  // The reference counting smart pointer class shared_ptr from Boost or
-  // TR1 would solve this issue even better by using
-  // vector<shared_ptr<T>> instead of vector<T*>, but that would require
-  // a dependency on Boost or on having a very recent compiler which
-  // incorporates TR1.
-  //
-  // TODO: make an AutoVector that wraps std::vector instead of or as a
-  // supplement to this class.
-  //
-  // Container::value_type is required to be a pointer type.
-  template<class Container>
-  class ElementDeleter {
-   public:
-    // Only the constructor can attach an ElementDeleter to a container,
-    // and this helps ensure (but does not guarantee) the precondition
-    // of the destructor of ElementDeleter.
-    ElementDeleter(Container& container): _container(&container) {
-    }
-
-    // Calls deleteElements() and shares its precondition.
-    ~ElementDeleter() {
-      deleteElements();
-    }
-
-    // Call release() to prevent this ElementDeleter from manipulating
-    // the container in any way.
-    void release() {
-      _container = 0;
-    }
-
-    // If release has been called, this method does nothing. Otherwise
-    // the container must still be valid, and then delete is called on
-    // each element of the array and clear is called on the container.
-    void deleteElements() {
-      if (_container == 0)
-        return;
-
-      // The code below may seem obviously correct, but it is a
-      // non-trivial fact that it works in the face of exceptions.
-      //
-      // First of all, we are allowed to assume that destructors do not
-      // throw exceptions, so the loop will run to completion.
-      //
-      // Normally clear() *can* throw an exception according to the
-      // standard (which is weird), but if the copy constructor and
-      // assignment operator do not throw exceptions, then it does
-      // not. In our case, we require the element type to be a pointer
-      // type, so for this reason only do we know that clear will not
-      // throw an exception. Thus we do not have to worry about leaving
-      // around a container full of invalid pointers if clear() should
-      // throw an exception.
-
-      typename Container::iterator end = _container->end();
-      typename Container::iterator it = _container->begin();
-      for (; it != end; ++it)
-        delete *it;
-      _container->clear();
-    }
-
-   private:
-    Container* _container;
-  };
-
-  // exceptionSafePushBack is designed to work around the fact that this
-  // code can leak memory:
-  //
-  //   vector<int*> vec;
-  //   ElementDeleter<vector<int*> > elementDeleter(vec);
-  //   auto_ptr<int> p(new int());
-  //   vec.push_back(p.release())
-  //
-  // This is because push_back can fail by throwing a bad_alloc, and at
-  // that point the pointer in p has already been released, so that
-  // pointer is now lost and hence the memory is leaked.
-  //
-  // This can be fixed by replacing
-  //
-  //   vec.push_back(p.release())
-  //
-  // by
-  //
-  //   vec.push_back(0);
-  //   vec.back() = p.release();
-  //
-  // but this is annoying and looks quite strange. It is much clearer to
-  // write
-  //
-  //   exceptionSafePushBack(vec, p);
-  //
-  template<class Container, class Element>
-  void exceptionSafePushBack(Container& container, std::auto_ptr<Element> pointer) {
-    container.push_back(0);
-    container.back() = pointer.release();
-  }
-
-  // Serves the same purpose as exceptionSafePushBack, except that this
-  // overload will simply ignore an exception without propagating it.
-  // Thus if there is not enough memory to add the element to the container,
-  // the element will simply get deleted and the container will remain
-  // unchanged. This works well if e.g. adding an element to a cache, where
-  // it is no great problem if the element gets deleted rather than added.
-  template<class Container, class Element>
-  void noThrowPushBack(Container& container, std::auto_ptr<Element> pointer) throw () {
-    try {
-      exceptionSafePushBack(container, pointer);
-    } catch (const std::bad_alloc&) {
-      // Ignore the exception.
-    }
-  }
-}
-
-#endif
diff --git a/src/mathic/HelpAction.cpp b/src/mathic/HelpAction.cpp
index 70e3bf1..6a40d8a 100755
--- a/src/mathic/HelpAction.cpp
+++ b/src/mathic/HelpAction.cpp
@@ -97,7 +97,7 @@ namespace mathic {
     _parser->pushBackRegisteredActionNames(names);
     for (std::vector<std::string>::const_iterator it = names.begin();
          it != names.end(); ++it) {
-      std::auto_ptr<Action> action(_parser->createActionWithPrefix(*it));
+      std::unique_ptr<Action> action(_parser->createActionWithPrefix(*it));
       printer[0] << action->name() << '\n';
 	  printer[1] << action->shortDescription() << '\n';
     }
diff --git a/src/mathic/NameFactory.h b/src/mathic/NameFactory.h
index 0eb210b..afe9111 100755
--- a/src/mathic/NameFactory.h
+++ b/src/mathic/NameFactory.h
@@ -2,11 +2,11 @@
 #define MATHIC_NAME_FACTORY_GUARD
 
 #include "stdinc.h"
+#include "error.h"
 #include <vector>
 #include <string>
 #include <algorithm>
 #include <memory>
-#include "error.h"
 
 namespace mathic {
   /** A NameFactory takes a name and then creates an instance of a class
@@ -23,17 +23,17 @@ namespace mathic {
      generated in general. Used for error messages. */
     NameFactory(const char* abstractName): _abstractName(abstractName) {}
 
-    typedef std::auto_ptr<AbstractProduct> (*FactoryFunction)();
+    typedef std::unique_ptr<AbstractProduct> (*FactoryFunction)();
     void registerProduct(const std::string& name, FactoryFunction function);
 
     /** Calls the function registered to the parameter name and returns
      the result. Returns null if name has not been registered. */
-    std::auto_ptr<AbstractProduct>
+    std::unique_ptr<AbstractProduct>
       createNullOnUnknown(const std::string& name) const;
 
     /** Calls the function registered to the parameter name and returns
      the result. Throws an exception if name has not been registered. */
-    std::auto_ptr<AbstractProduct> create(const std::string& name) const;
+    std::unique_ptr<AbstractProduct> create(const std::string& name) const;
 
     /** Inserts into names all registered names that have the indicated
      prefix in lexicographic increasing order. */
@@ -74,7 +74,7 @@ namespace mathic {
    creates the actual product that has name equal to the indicated
    prefix. Exceptions thrown are as for uniqueNamesWithPrefix(). */
   template<class AbstractProduct>
-  std::auto_ptr<AbstractProduct> createWithPrefix
+  std::unique_ptr<AbstractProduct> createWithPrefix
   (const NameFactory<AbstractProduct>& factory, const std::string& prefix);
 
   /** Returns the unique product name that has the indicated prefix, or
@@ -96,18 +96,18 @@ namespace mathic {
   // to being templates.
 
   template<class AbstractProduct>
-  std::auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
+  std::unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
   createNullOnUnknown(const std::string& name) const {
     for (const_iterator it = _pairs.begin(); it != _pairs.end(); ++it)
       if (it->first == name)
         return it->second();
-    return std::auto_ptr<AbstractProduct>();
+    return std::unique_ptr<AbstractProduct>();
   }
 
   template<class AbstractProduct>
-  std::auto_ptr<AbstractProduct> NameFactory<AbstractProduct>::
+  std::unique_ptr<AbstractProduct> NameFactory<AbstractProduct>::
   create(const std::string& name) const {
-    std::auto_ptr<AbstractProduct> product = createNullOnUnknown(name);
+    std::unique_ptr<AbstractProduct> product = createNullOnUnknown(name);
     if (product.get() == 0)
       throwError<UnknownNameException>(
         "Unknown " + abstractProductName() + " \"" + name + "\".");
@@ -153,15 +153,15 @@ namespace mathic {
     (NameFactory<AbstractProduct>& factory, const std::string& name) {
     // work-around for no local functions in old C++
     struct HoldsFunction {
-      static std::auto_ptr<AbstractProduct> createConcreteProduct() {
-        return std::auto_ptr<AbstractProduct>(new ConcreteProduct());
+      static std::unique_ptr<AbstractProduct> createConcreteProduct() {
+        return std::unique_ptr<AbstractProduct>(new ConcreteProduct());
       }
     };
     factory.registerProduct(name, HoldsFunction::createConcreteProduct);
   }
 
   template<class AbstractProduct>
-  std::auto_ptr<AbstractProduct> createWithPrefix
+  std::unique_ptr<AbstractProduct> createWithPrefix
   (const NameFactory<AbstractProduct>& factory, const std::string& prefix) {
     return factory.createNullOnUnknown(uniqueNameWithPrefix(factory, prefix));
   }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathic.git



More information about the debian-science-commits mailing list