|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54666 - in sandbox/cloneable: boost/cloneable boost/cloneable/detail libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-07-05 04:32:00
Author: cschladetsch
Date: 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
New Revision: 54666
URL: http://svn.boost.org/trac/boost/changeset/54666
Log:
about to refactor instance<>
Text files modified:
sandbox/cloneable/boost/cloneable/base.hpp | 7 ++-
sandbox/cloneable/boost/cloneable/detail/create_new.hpp | 15 +++++++
sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp | 2 +
sandbox/cloneable/boost/cloneable/forward_declarations.hpp | 31 +++++++++++++--
sandbox/cloneable/boost/cloneable/instance.hpp | 79 +++++++++++++++++++++++++++++++++++----
sandbox/cloneable/libs/cloneable/test/tests.cpp | 9 ++++
6 files changed, 127 insertions(+), 16 deletions(-)
Modified: sandbox/cloneable/boost/cloneable/base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/base.hpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -30,11 +30,12 @@
{
typedef Derived derived_type;
typedef Base base_type;
- typedef DefaultCtorTag default_constructable_type;
+ typedef DefaultCtorTag default_constructable_type, construction_tag_type;
typedef base<derived_type, base_type, default_constructable_type> this_type;
virtual this_type *create_new(abstract_allocator &alloc) const
{
+ // TODO: deal with conversion from bases with unknown_construction_tag
return detail::create_new<Derived, DefaultCtorTag>::given(this, alloc, alignment);
}
};
@@ -51,8 +52,8 @@
template <class T>
struct get_default_construction_tag : if_<is_nil<T>, default_construction_tag, T> { };
- typedef is_convertible<A *, detail::ctag *> a_is_tag;
- typedef is_convertible<B *, detail::ctag *> b_is_tag;
+ typedef is_convertible<A *, detail::tag *> a_is_tag;
+ typedef is_convertible<B *, detail::tag *> b_is_tag;
typedef typename if_<
is_nil<A>
Modified: sandbox/cloneable/boost/cloneable/detail/create_new.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/create_new.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/create_new.hpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -37,7 +37,22 @@
throw no_default_construction();
}
};
+
+ // TODO: deal with conversion from bases with unknown_construction_tag
+ template <class Derived>
+ struct create_new<Derived, unknown_construction_tag>
+ {
+ template <class Self, class Alloc>
+ static Derived *given(Self *self, Alloc &alloc, size_t alignment)
+ {
+ abstract_allocator::pointer bytes = alloc.allocate_bytes(sizeof(Derived), alignment);
+ Derived *ptr = reinterpret_cast<Derived *>(bytes);
+ ptr->Self::self_ptr = ptr;
+ new (ptr->Self::self_ptr) Derived(Derived());
+ return ptr;
+ }
+ };
} // namespace detail
} // namespace cloneable
Modified: sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/make_clone_allocator.hpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -91,6 +91,8 @@
using detail::make_clone_allocator;
+ typedef make_clone_allocator<default_allocator> default_clone_allocator;
+
} // namespace cloneable
} // namespace boost
Modified: sandbox/cloneable/boost/cloneable/forward_declarations.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/forward_declarations.hpp (original)
+++ sandbox/cloneable/boost/cloneable/forward_declarations.hpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -29,12 +29,26 @@
/// wish to use a custom base type
struct base_type;
- namespace detail { struct ctag { }; }
+ typedef base_type default_base_type;
+
+ namespace detail
+ {
+ struct tag { };
+
+ template <size_t N>
+ struct bit_tag : tag
+ {
+ BOOST_STATIC_CONSTANT(size_t, bit = (1<<N));
+ };
+ }
+
+ struct any_derived_tag : detail::bit_tag<0> { };
+ struct any_base_tag : detail::bit_tag<1> { };
/// {@ tags to inform about default-constructability
- struct default_construction_tag : detail::ctag, mpl::true_ {};
- struct no_default_construction_tag : detail::ctag, mpl::false_ {};
- struct unknown_construction_tag : detail::ctag {};
+ struct default_construction_tag : detail::bit_tag<2> {};
+ struct no_default_construction_tag : detail::bit_tag<3> {};
+ struct unknown_construction_tag : detail::bit_tag<4> {};
/// @}
/// provides a set of pure-virtual methods for allocation, de-allocation, and cloning
@@ -57,6 +71,15 @@
>
struct base;
+ template <
+ class Derived = any_derived_tag
+ , class Base = typename Derived::base_type
+ , class Alloc = default_allocator
+ , class Ctor = typename Derived::construction_tag_type
+ >
+ struct instance;
+
+
/// an adaptor for an existing class.
///
/// this is a type that can be used correctly in an homogenous container,
Modified: sandbox/cloneable/boost/cloneable/instance.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/instance.hpp (original)
+++ sandbox/cloneable/boost/cloneable/instance.hpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -26,7 +26,8 @@
allocator_type *alloc;
public:
- instance_base(allocator_type *al = 0) : alloc(al) { }
+ instance_base(allocator_type *al = 0)
+ : alloc(al) { }
bool has_allocator() const
{
@@ -62,6 +63,7 @@
typedef Abstract abstract_type;
typedef Derived derived_type;
typedef detail::mixin<derived_type, base_type> is_derived_type;
+ typedef instance_common<Abstract, Derived, Base, Alloc> this_type;
protected:
derived_type *ptr;
@@ -70,6 +72,22 @@
instance_common(derived_type *p = 0) : ptr(p) { }
instance_common(allocator_type &a, derived_type *p = 0) : parent_type(&a), ptr(p) { }
+ this_type clone() const
+ {
+ if (empty())
+ return this_type(get_allocator());
+ return this_type(get_allocator(), to_abstract()->clone_as<derived_type>(get_allocator()));
+ }
+
+ template <class Ty>
+ instance_common<base<Ty,Base, unknown_construction_tag>, Derived, Base, Alloc> clone() const
+ {
+ typedef instance_common<base<Ty,Base, unknown_construction_tag>, Derived, Base, Alloc> that_type;
+ if (empty())
+ return that_type(get_allocator());
+ return that_type(get_allocator(), to_abstract()->clone_as<Ty>(get_allocator()));
+ }
+
void allocate()
{
if (!has_allocator())
@@ -87,16 +105,40 @@
cloneable::release(ptr, get_allocator());
ptr = 0;
}
+ template <class A0>
+ void construct(A0 a0)
+ {
+ allocate();
+ new (to_derived()) derived_type(a0);
+ }
+ template <class A0, class A1>
+ void construct(A0 a0, A1 a1)
+ {
+ allocate();
+ new (to_derived()) derived_type(a0, a1);
+ }
+ template <class A0, class A1, class A2>
+ void construct(A0 a0, A1 a1, A2 a2)
+ {
+ allocate();
+ new (to_derived()) derived_type(a0, a1, a2);
+ }
const std::type_info &get_type() const
{
return typeid(derived_type);
}
+
bool exists() const
{
return ptr != 0;
}
+ bool empty() const
+ {
+ return ptr == 0;
+ }
+
base_type *to_base() const
{
return ptr;
@@ -107,9 +149,7 @@
}
derived_type *to_derived() const
{
- if (!ptr)
- return 0;
- return ptr;//->is_derived_type::self_ptr;
+ return ptr;
}
derived_type &derived_ref()
@@ -134,12 +174,20 @@
template <class Derived, class Base, class Alloc, class Ctor>
struct instance : instance_common<base<Derived,Base,Ctor>, Derived, Base, Alloc>
{
- typedef base<Derived,Base,Ctor> abstract_type;
+ typedef abstract_base<Base> abstract_base_type;
+ typedef base<Derived,Base,Ctor> base_type;
typedef instance_common<abstract_type, Derived, Base, Alloc> parent_type;
+ typedef instance<Derived, Base, Alloc, Ctor> this_type;
public:
instance() { }
+ instance(allocator_type &al)
+ : parent_type(al
+ , detail::create_new<Derived, Ctor>::given(to_abstract(), al, abstract_type::alignment))
+ {
+ }
+
template <class Other, class Ctor2>
instance(const instance<Other,Base,Alloc,Ctor2> &other)
: parent_type(dynamic_cast<derived_type *>(other.to_base()))
@@ -147,9 +195,17 @@
if (other.has_allocator())
parent_type::set_allocator(other.get_allocator());
}
- instance(allocator_type &al)
- : parent_type(al
- , detail::create_new<Derived, Ctor>::given(to_abstract(), al, abstract_type::alignment))
+
+ instance(base_type *ptr)
+ : parent_type(dynamic_cast<derived_type *>(ptr))
+ {
+ }
+ instance(abstract_base_type *ptr)
+ : parent_type(dynamic_cast<derived_type *>(ptr))
+ {
+ }
+ instance(abstract_base_type *abst, allocator_type &al)
+ : parent_type(al, dynamic_cast<derived_type *>(abst))
{
}
template <class A0>
@@ -170,7 +226,12 @@
allocate();
new (to_derived()) derived_type(a0, a1, a2);
}
-
+ this_type clone() const
+ {
+ if (empty())
+ return this_type(get_allocator());
+ return this_type(get_allocator(), to_abstract()->clone_as<derived_type>(get_allocator()));
+ }
};
} // namespace cloneable
Modified: sandbox/cloneable/libs/cloneable/test/tests.cpp
==============================================================================
--- sandbox/cloneable/libs/cloneable/test/tests.cpp (original)
+++ sandbox/cloneable/libs/cloneable/test/tests.cpp 2009-07-05 04:31:59 EDT (Sun, 05 Jul 2009)
@@ -471,6 +471,15 @@
}
};
+BOOST_AUTO_TEST_CASE(test_instance)
+{
+ //make_clone_allocator<std::allocator<char> > alloc;
+ //instance<T2> ins(alloc, 3.14f, 42, "spam");
+ //instance<T2> copy = ins.clone();
+ //BOOST_ASSERT(ins.exists() && ins->str == "spam");
+ //BOOST_ASSERT(copy.exists() && copy->str == "spam");
+}
+
BOOST_AUTO_TEST_CASE(test_vector)
{
// this uses the base type for the contained elements as a region tag for a monotonic allocator.
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