Boost logo

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