|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r55690 - in sandbox/fmhess: boost/generic_ptr libs/generic_ptr/test
From: fmhess_at_[hidden]
Date: 2009-08-20 15:54:10
Author: fmhess
Date: 2009-08-20 15:54:09 EDT (Thu, 20 Aug 2009)
New Revision: 55690
URL: http://svn.boost.org/trac/boost/changeset/55690
Log:
Added support for passing a custom allocator to generic_ptr::cloning
constructor.
Text files modified:
sandbox/fmhess/boost/generic_ptr/cloning.hpp | 96 ++++++++++++++++++++++++++++++----------
sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp | 10 +++
2 files changed, 81 insertions(+), 25 deletions(-)
Modified: sandbox/fmhess/boost/generic_ptr/cloning.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/cloning.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/cloning.hpp 2009-08-20 15:54:09 EDT (Thu, 20 Aug 2009)
@@ -23,13 +23,13 @@
#include <boost/mpl/identity.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/clone_allocator.hpp>
-#include <boost/scoped_ptr.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/swap.hpp>
+#include <memory>
namespace boost
{
@@ -86,9 +86,10 @@
virtual ~clone_factory_impl_base() {}
virtual GenericVoidPointer get_pointer() = 0;
virtual clone_factory_impl_base* make_clone() = 0;
+ virtual void delete_self() = 0;
};
- template<typename GenericPointer, typename Cloner>
+ template<typename GenericPointer, typename Cloner, typename Allocator>
class clone_factory_impl: public
clone_factory_impl_base
<
@@ -96,9 +97,17 @@
>
{
public:
- clone_factory_impl(GenericPointer p, Cloner c):
+ typedef typename Allocator::template rebind<clone_factory_impl>::other allocator_type;
+
+ clone_factory_impl(GenericPointer p, Cloner c, allocator_type a):
cloner(c),
- px(cloner.allocate_clone(p))
+ px(cloner.allocate_clone(p)),
+ allocator(a)
+ {}
+ clone_factory_impl(const clone_factory_impl &other):
+ cloner(other.cloner),
+ px(cloner.allocate_clone(other.px)),
+ allocator(other.allocator)
{}
~clone_factory_impl()
{
@@ -116,11 +125,31 @@
}
virtual clone_factory_impl* make_clone()
{
- return new clone_factory_impl(px, cloner);
+ clone_factory_impl *result = allocator.allocate(1);
+ try
+ {
+ allocator.construct(result, clone_factory_impl(px, cloner, allocator));
+ }
+ catch(...)
+ {
+ allocator.deallocate(result, 1);
+ throw;
+ }
+ return result;
+ }
+ virtual void delete_self()
+ {
+ // need to local copy of allocator, since original will be destroyed by destructor
+ allocator_type local_allocator(allocator);
+ local_allocator.destroy(this);
+ local_allocator.deallocate(this, 1);
}
private:
+ clone_factory_impl & operator=(const clone_factory_impl &other); // could be implemented if we needed it
+
Cloner cloner;
GenericPointer px;
+ allocator_type allocator;
};
template<typename GenericVoidPointer>
@@ -129,20 +158,39 @@
public:
clone_factory(): _impl()
{}
- template<typename T, typename Cloner>
- clone_factory(T p, Cloner c): _impl(new clone_factory_impl<T, Cloner>(p, c))
- {}
+ template<typename T, typename Cloner, typename Allocator>
+ clone_factory(T p, Cloner c, Allocator a): _impl(0)
+ {
+ typedef clone_factory_impl<T, Cloner, Allocator> impl_type;
+ typename impl_type::allocator_type allocator(a);
+ impl_type *storage = allocator.allocate(1);
+ try
+ {
+ allocator.construct(storage, impl_type(p, c, allocator));
+ }
+ catch(...)
+ {
+ allocator.deallocate(storage, 1);
+ throw;
+ }
+ _impl = storage;
+ }
clone_factory(const clone_factory &other): _impl(other._impl->make_clone())
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
clone_factory(clone_factory && other)
{
- swap(other);
+ _impl = other._impl;
+ other._impl = 0;
}
#endif
+ ~clone_factory()
+ {
+ if(_impl) _impl->delete_self();
+ }
GenericVoidPointer get_pointer()
{
- if(_impl.get() == 0) return GenericVoidPointer();
+ if(_impl == 0) return GenericVoidPointer();
return _impl->get_pointer();
}
void swap(clone_factory &other)
@@ -152,7 +200,7 @@
private:
clone_factory& operator=(const clone_factory &); // could be implemented and made public if we needed it
- scoped_ptr<clone_factory_impl_base<GenericVoidPointer> > _impl;
+ clone_factory_impl_base<GenericVoidPointer> *_impl;
};
template<typename T>
void swap(clone_factory<T> &a, clone_factory<T> &b)
@@ -193,6 +241,7 @@
}
private:
void * storage() {return boost::addressof(_storage);}
+
boost::aligned_storage<sizeof(T), boost::alignment_of<T>::value> _storage;
bool _allocated;
};
@@ -228,7 +277,8 @@
_clone_factory
(
typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
- default_cloner<typename pointer_traits<U>::value_type>()
+ default_cloner<typename pointer_traits<U>::value_type>(),
+ std::allocator<void>()
),
px
(
@@ -248,7 +298,8 @@
_clone_factory
(
typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
- default_cloner<typename pointer_traits<U>::value_type>()
+ default_cloner<typename pointer_traits<U>::value_type>(),
+ std::allocator<void>()
),
px
(
@@ -259,17 +310,13 @@
)
{}
#endif // BOOST_NO_SFINAE
- template<typename U, typename Deleter>
- cloning
- (
- U p,
- Deleter d
- ):
+ template<typename U, typename Cloner>
+ cloning(U p, Cloner c):
_clone_factory
(
typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
- d,
- default_cloner<typename pointer_traits<U>::value_type>()
+ c,
+ std::allocator<void>()
),
px
(
@@ -279,12 +326,13 @@
>(_clone_factory.get_pointer())
)
{}
- template<typename U, typename Deleter, typename Cloner>
- cloning(U p, Deleter d, Cloner c):
+ template<typename U, typename Cloner, typename Allocator>
+ cloning(U p, Cloner c, Allocator a):
_clone_factory
(
typename generic_ptr::rebind<T, typename pointer_traits<U>::value_type>::other(p),
- c
+ c,
+ a
),
px
(
Modified: sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp (original)
+++ sandbox/fmhess/libs/generic_ptr/test/cloning_test.cpp 2009-08-20 15:54:09 EDT (Thu, 20 Aug 2009)
@@ -12,6 +12,7 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/generic_ptr/cloning.hpp>
#include <boost/generic_ptr/null_deleter.hpp>
+#include <memory>
class X_base
{
@@ -137,7 +138,14 @@
X *x0 = new X();
BOOST_TEST(X::instances == 1);
{
- boost::generic_ptr::cloning<X*> cp0(x0, boost::generic_ptr::null_deleter(), null_cloner());
+ boost::generic_ptr::cloning<X*> cp0(x0, null_cloner());
+ BOOST_TEST(X::instances == 1);
+ boost::generic_ptr::cloning<X*> cp1 = cp0;
+ BOOST_TEST(X::instances == 1);
+ }
+ BOOST_TEST(X::instances == 1);
+ {
+ boost::generic_ptr::cloning<X*> cp0(x0, null_cloner(), std::allocator<int>());
BOOST_TEST(X::instances == 1);
boost::generic_ptr::cloning<X*> cp1 = cp0;
BOOST_TEST(X::instances == 1);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk