[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