Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54615 - in sandbox/cloneable: boost/cloneable boost/cloneable/detail libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-07-03 18:05:38


Author: cschladetsch
Date: 2009-07-03 18:05:37 EDT (Fri, 03 Jul 2009)
New Revision: 54615
URL: http://svn.boost.org/trac/boost/changeset/54615

Log:
added sequence_container_base<>

Text files modified:
   sandbox/cloneable/boost/cloneable/abstract_base.hpp | 15 +-
   sandbox/cloneable/boost/cloneable/detail/container_base.hpp | 185 ++++++++++++++++++++++++++++++++++++++++
   sandbox/cloneable/boost/cloneable/list.hpp | 178 ++++----------------------------------
   sandbox/cloneable/boost/cloneable/vector.hpp | 147 +++++--------------------------
   sandbox/cloneable/libs/cloneable/test/tests.cpp | 29 +++--
   5 files changed, 257 insertions(+), 297 deletions(-)

Modified: sandbox/cloneable/boost/cloneable/abstract_base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/abstract_base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/abstract_base.hpp 2009-07-03 18:05:37 EDT (Fri, 03 Jul 2009)
@@ -59,7 +59,6 @@
                 template <class Base>
                 struct abstract_base : virtual Base
                 {
- typedef Base element_type;
                         typedef Base base_type;
                         typedef abstract_base<Base> this_type;
 
@@ -139,14 +138,16 @@
                         }
                         */
 
+ friend bool operator==(const abstract_base &left, const abstract_base &right)
+ {
+ return static_cast<const base_type &>(left) == static_cast<const base_type &>(right);
+ }
+ friend bool operator<(const abstract_base &left, const abstract_base &right)
+ {
+ return static_cast<const base_type &>(left) < static_cast<const base_type &>(right);
+ }
                 };
 
-
- template <class Base>
- bool operator<(const abstract_base<Base> &left, const abstract_base<Base> &right)
- {
- return static_cast<const Base &>(left) == static_cast<const Base &>(right);
- }
         } // namespace cloneable
 
         /*

Modified: sandbox/cloneable/boost/cloneable/detail/container_base.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/detail/container_base.hpp (original)
+++ sandbox/cloneable/boost/cloneable/detail/container_base.hpp 2009-07-03 18:05:37 EDT (Fri, 03 Jul 2009)
@@ -97,6 +97,191 @@
                                 }
                         };
 
+ template <class Cont, class Base, class Alloc>
+ struct sequence_container_base : container_base<Base,Alloc>
+ {
+ typedef Cont container_type;
+ typedef container_base<Base,Alloc> parent_type;
+ using parent_type::base_type;
+ using parent_type::abstract_base_type;
+ using parent_type::allocator_type;
+ using parent_type::validate;
+ using parent_type::new_instance;
+ using parent_type::instance;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::reference reference;
+ typedef typename container_type::const_reference const_reference;
+ typedef typename container_type::iterator iterator;
+ typedef typename container_type::const_iterator const_iterator;
+
+ private:
+ container_type container;
+
+ protected:
+ const container_type &impl() const
+ {
+ return container;
+ }
+ container_type &impl()
+ {
+ return container;
+ }
+
+ public:
+ sequence_container_base()
+ : container(get_allocator())
+ {
+ }
+ sequence_container_base(allocator_type &a)
+ : parent_type(a), container(get_allocator())
+ {
+ }
+
+ size_t size() const
+ {
+ return container.size();
+ }
+
+ template <class Ty, class Fun>
+ Fun for_each(Fun fun)
+ {
+ BOOST_FOREACH(base_type &b, *this)
+ {
+ if (Ty *ptr = dynamic_cast<Ty *>(&b))
+ {
+ fun(*ptr);
+ }
+ }
+ return fun;
+ }
+
+ template <class Ty, class Fun>
+ Fun for_each(Fun fun) const
+ {
+ BOOST_FOREACH(const base_type &base, *this)
+ {
+ if (Ty *ptr = dynamic_cast<Ty *>(&base))
+ {
+ fun(*ptr);
+ }
+ }
+ return fun;
+ }
+
+ bool empty() const
+ {
+ return impl().empty();
+ }
+
+ iterator begin()
+ {
+ return impl().begin();
+ }
+ iterator end()
+ {
+ return impl().end();
+ }
+ const_iterator begin() const
+ {
+ return impl().begin();
+ }
+ const_iterator end() const
+ {
+ return impl().end();
+ }
+
+ reference back()
+ {
+ return impl().back();
+ }
+ const_reference back() const
+ {
+ return impl().back();
+ }
+ reference front()
+ {
+ return impl().front();
+ }
+ const_reference front() const
+ {
+ return impl().front();
+ }
+
+ template <class Other>
+ Other &back_as()
+ {
+ BOOST_STATIC_ASSERT(is_cloneable<Other>::value);
+ Other *ptr = dynamic_cast<Other *>(back());
+ if (ptr == 0)
+ throw std::bad_cast();
+ return *ptr;
+ }
+ template <class Other>
+ Other &front_as()
+ {
+ BOOST_STATIC_ASSERT(is_cloneable<Other>::value);
+ Other *ptr = dynamic_cast<Other *>(front());
+ if (ptr == 0)
+ throw std::bad_cast();
+ return *ptr;
+ }
+
+ // TODO: use variadic arguments or BOOST_PP to pass ctor args
+ template <class U>
+ void push_back()
+ {
+ impl().push_back(new_instance<typename validate<U>::type>().to_abstract());
+ }
+ template <class U, class A0>
+ void push_back(A0 a0)
+ {
+ impl().push_back(new_instance<typename validate<U>::type>(a0).to_abstract());
+ }
+ template <class U, class A0, class A1>
+ void push_back(A0 a0, A1 a1)
+ {
+ impl().push_back(new_instance<typename validate<U>::type>(a0,a1).to_abstract());
+ }
+ template <class U, class A0, class A1, class A2>
+ void push_back(A0 a0, A1 a1, A2 a2)
+ {
+ impl().push_back(new_instance<typename validate<U>::type>(a0,a1,a2).to_abstract());
+ }
+
+
+ template <class U>
+ void push_front()
+ {
+ impl().push_front(new_instance<typename validate<U>::type>().to_abstract());
+ }
+ template <class U, class A0>
+ void push_front(A0 a0)
+ {
+ impl().push_front(new_instance<typename validate<U>::type>(a0).to_abstract());
+ }
+ template <class U, class A0, class A1>
+ void push_front(A0 a0, A1 a1)
+ {
+ impl().push_front(new_instance<typename validate<U>::type>(a0,a1).to_abstract());
+ }
+ template <class U, class A0, class A1, class A2>
+ void push_front(A0 a0, A1 a1, A2 a2)
+ {
+ impl().push_front(new_instance<typename validate<U>::type>(a0,a1,a2).to_abstract());
+ }
+ };
+
+ template <class Cont, class Base, class Alloc>
+ bool operator==(const sequence_container_base<Cont,Base,Alloc> &left, const sequence_container_base<Cont,Base,Alloc> &right)
+ {
+ return left.size() == right.size() && std::equal(left.begin(), left.end(), right.begin());
+ }
+
+ template <class Cont, class Base, class Alloc>
+ bool operator<(const sequence_container_base<Cont,Base,Alloc> &left, const sequence_container_base<Cont,Base,Alloc> &right)
+ {
+ return std::lexicographical_compare(left.begin(), left.end(), right.begin(), right.end());
+ }
                 } // namespace detail
 
         } // namespace cloneable

Modified: sandbox/cloneable/boost/cloneable/list.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/list.hpp (original)
+++ sandbox/cloneable/boost/cloneable/list.hpp 2009-07-03 18:05:37 EDT (Fri, 03 Jul 2009)
@@ -23,181 +23,43 @@
                 // TODO: move to boost/heterogenous/list
                 template <class Base, class Alloc>
                 struct list
- : detail::container_base<Base, Alloc>
+ : detail::sequence_container_base<
+ ptr_list<
+ abstract_base<Base>
+ , allocator
+ , typename detail::make_clone_allocator<Alloc>::type >
+ , Base
+ , Alloc>
                 {
- typedef detail::container_base<Base,Alloc> parent_type;
+ typedef detail::sequence_container_base<
+ ptr_list<abstract_base<Base>
+ , allocator
+ , typename detail::make_clone_allocator<Alloc>::type >
+ , Base
+ , Alloc>
+ parent_type;
                         typedef typename parent_type::base_type base_type;
                         typedef typename parent_type::abstract_base_type abstract_base_type;
                         typedef typename parent_type::allocator_type allocator_type;
                         using parent_type::validate;
                         using parent_type::new_instance;
-
- typedef ptr_list<abstract_base_type, allocator, allocator_type> implementation;
-
- typedef typename implementation::value_type value_type;
- typedef typename implementation::reference reference;
- typedef typename implementation::const_reference const_reference;
- typedef typename implementation::iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
-
- private:
- implementation impl;
+ typedef typename parent_type::value_type value_type;
+ typedef typename parent_type::reference reference;
+ typedef typename parent_type::const_reference const_reference;
+ typedef typename parent_type::iterator iterator;
+ typedef typename parent_type::const_iterator const_iterator;
 
                 public:
                         list()
- : impl(get_allocator())
                         {
                         }
 
                         list(allocator_type &a)
- : parent_type(a), impl(get_allocator())
- {
- }
-
- //purposefully elided
- //template <class II>
- //list(II F, II L, allocator_type a = allocator_type());
- //list(size_t reserved);
-
- template <class Ty, class Fun>
- Fun for_each(Fun fun)
- {
- BOOST_FOREACH(base_type &b, *this)
- {
- if (Ty *ptr = dynamic_cast<Ty *>(&b))
- {
- fun(*ptr);
- }
- }
- return fun;
- }
-
- template <class Ty, class Fun>
- Fun for_each(Fun fun) const
- {
- BOOST_FOREACH(const base_type &base, *this)
- {
- if (Ty *ptr = dynamic_cast<Ty *>(&base))
- {
- fun(*ptr);
- }
- }
- return fun;
- }
-
- size_t size() const
- {
- return impl.size();
- }
- bool empty() const
+ : parent_type(a)
                         {
- return impl.empty();
- }
-
- iterator begin()
- {
- return impl.begin();
- }
- iterator end()
- {
- return impl.end();
- }
- const_iterator begin() const
- {
- return impl.begin();
- }
- const_iterator end() const
- {
- return impl.end();
- }
-
- value_type &back()
- {
- return impl.back();
- }
- const value_type &back() const
- {
- return impl.back();
- }
- value_type &front()
- {
- return impl.front();
- }
- const value_type &front() const
- {
- return impl.front();
- }
-
- template <class Other>
- Other &back_as()
- {
- BOOST_STATIC_ASSERT(is_cloneable<Other>::value);
- Other *ptr = dynamic_cast<Other *>(back());
- if (ptr == 0)
- throw std::bad_cast();
- return *ptr;
- }
- template <class Other>
- Other &front_as()
- {
- BOOST_STATIC_ASSERT(is_cloneable<Other>::value);
- Other *ptr = dynamic_cast<Other *>(front());
- if (ptr == 0)
- throw std::bad_cast();
- return *ptr;
- }
-
- // TODO: use variadic arguments or BOOST_PP to pass ctor args
- template <class U>
- void push_back()
- {
- impl.push_back(new_instance<typename validate<U>::type>().to_abstract());
- }
- template <class U, class A0>
- void push_back(A0 a0)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0).to_abstract());
- }
- template <class U, class A0, class A1>
- void push_back(A0 a0, A1 a1)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0,a1).to_abstract());
- }
- template <class U, class A0, class A1, class A2>
- void push_back(A0 a0, A1 a1, A2 a2)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0,a1,a2).to_abstract());
- }
-
-
- template <class U>
- void push_front()
- {
- impl.push_front(new_instance<typename validate<U>::type>().to_abstract());
- }
- template <class U, class A0>
- void push_front(A0 a0)
- {
- impl.push_front(new_instance<typename validate<U>::type>(a0).to_abstract());
- }
- template <class U, class A0, class A1>
- void push_front(A0 a0, A1 a1)
- {
- impl.push_front(new_instance<typename validate<U>::type>(a0,a1).to_abstract());
- }
- template <class U, class A0, class A1, class A2>
- void push_front(A0 a0, A1 a1, A2 a2)
- {
- impl.push_front(new_instance<typename validate<U>::type>(a0,a1,a2).to_abstract());
                         }
                 };
         
- template <class Base, class Alloc>
- bool operator==(const list<Base,Alloc> &left, const list<Base,Alloc> &right)
- {
- return left.size() == right.size()
- && std::equal(left.begin(), left.end(), right.begin(), std::equal_to<abstract_base<Base> >());
- }
         } // namespace cloneable
 
 } // namespace boost

Modified: sandbox/cloneable/boost/cloneable/vector.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/vector.hpp (original)
+++ sandbox/cloneable/boost/cloneable/vector.hpp 2009-07-03 18:05:37 EDT (Fri, 03 Jul 2009)
@@ -17,133 +17,60 @@
 {
         namespace cloneable
         {
- /// a vector of heterogenous objects
- // TODO: move to boost/heterogenous/vector
                 template <class Base, class Alloc>
                 struct vector
- : detail::container_base<Base, Alloc>
+ : detail::sequence_container_base<
+ ptr_vector<
+ abstract_base<Base>
+ , allocator
+ , typename detail::make_clone_allocator<Alloc>::type >
+ , Base
+ , Alloc>
                 {
- typedef detail::container_base<Base,Alloc> parent_type;
+ typedef detail::sequence_container_base<
+ ptr_vector<abstract_base<Base>
+ , allocator
+ , typename detail::make_clone_allocator<Alloc>::type >
+ , Base
+ , Alloc>
+ parent_type;
                         typedef typename parent_type::base_type base_type;
                         typedef typename parent_type::abstract_base_type abstract_base_type;
                         typedef typename parent_type::allocator_type allocator_type;
                         using parent_type::validate;
                         using parent_type::new_instance;
-
- typedef ptr_vector<abstract_base_type, allocator, allocator_type> implementation;
-
- typedef typename implementation::value_type value_type;
- typedef typename implementation::reference reference;
- typedef typename implementation::const_reference const_reference;
- typedef typename implementation::iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
-
- private:
- implementation impl;
+ typedef typename parent_type::value_type value_type;
+ typedef typename parent_type::reference reference;
+ typedef typename parent_type::const_reference const_reference;
+ typedef typename parent_type::iterator iterator;
+ typedef typename parent_type::const_iterator const_iterator;
 
                 public:
- vector() : impl(get_allocator())
- {
- }
-
- vector(allocator_type &a)
- : parent_type(a), impl(a)
- {
- }
-
- /*
- template <class II>
- vector(II F, II L, allocator_type a = allocator_type());
- vector(size_t reserved)
- : impl(alloc)
- {
- }
- */
 
- template <class Ty, class Fun>
- Fun for_each(Fun fun)
+ vector()
                         {
- BOOST_FOREACH(base_type &b, *this)
- {
- if (Ty *ptr = dynamic_cast<Ty *>(&b))
- {
- fun(*ptr);
- }
- }
- return fun;
                         }
 
- template <class Ty, class Fun>
- Fun for_each(Fun fun) const
- {
- BOOST_FOREACH(const base_type &base, *this)
- {
- if (Ty *ptr = dynamic_cast<Ty *>(&base))
- {
- fun(*ptr);
- }
- }
- return fun;
- }
-
- size_t size() const
- {
- return impl.size();
- }
- bool empty() const
- {
- return impl.empty();
- }
-
- iterator begin()
- {
- return impl.begin();
- }
- iterator end()
- {
- return impl.end();
- }
- const_iterator begin() const
- {
- return impl.begin();
- }
- const_iterator end() const
- {
- return impl.end();
- }
-
- value_type &back()
- {
- return impl.back();
- }
- const value_type &back() const
- {
- return impl.back();
- }
- value_type &front()
- {
- return impl.front();
- }
- const value_type &front() const
+ vector(allocator_type &a)
+ : parent_type(a)
                         {
- return impl.front();
                         }
 
                         reference at(size_t n)
                         {
- return impl.at(n);
+ return impl().at(n);
                         }
                         const_reference at(size_t n) const
                         {
- return impl.at(n);
+ return impl().at(n);
                         }
                         reference operator[](size_t n)
                         {
- return impl[n];
+ return impl()[n];
                         }
                         const_reference operator[](size_t n) const
                         {
- return impl[n];
+ return impl()[n];
                         }
 
                         template <class Other>
@@ -180,28 +107,6 @@
                                 return dynamic_cast<const Other *>(&at(n));
                         }
 
- // TODO: use variadic arguments or BOOST_PP to pass ctor args
- template <class U>
- void emplace_back()
- {
- impl.push_back(new_instance<typename validate<U>::type>().to_abstract());
- }
- template <class U, class A0>
- void emplace_back(A0 a0)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0).to_abstract());
- }
- template <class U, class A0, class A1>
- void emplace_back(A0 a0, A1 a1)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0,a1).to_abstract());
- }
- template <class U, class A0, class A1, class A2>
- void emplace_back(A0 a0, A1 a1, A2 a2)
- {
- impl.push_back(new_instance<typename validate<U>::type>(a0,a1,a2).to_abstract());
- }
-
                 };
         
         } // 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-03 18:05:37 EDT (Fri, 03 Jul 2009)
@@ -118,8 +118,8 @@
         typedef cloneable::vector<> vec;
         
         vec v;
- v.emplace_back<Q0>(42);
- v.emplace_back<Q1>("foo");
+ v.push_back<Q0>(42);
+ v.push_back<Q1>("foo");
 
         Q0 &q0 = v.as<Q0>(0);
         Q1 &q1 = v.as<Q1>(1);
@@ -363,10 +363,10 @@
 
                 // type of thing to insert must be passed explicitly, and must derive from common_base.
                 // arguments to push_back are passed directly to ctor
- bases.emplace_back<T0>(42);
- bases.emplace_back<T1>("foo");
- bases.emplace_back<T2>(3.14f, -123, "spam");
- bases.emplace_back<cloneable_external_type>("external");
+ bases.push_back<T0>(42);
+ bases.push_back<T1>("foo");
+ bases.push_back<T2>(3.14f, -123, "spam");
+ bases.push_back<cloneable_external_type>("external");
 
                 // perform functor on each contained object of the given type
                 bases.for_each<T2>(boost::bind(&T2::print, _1));
@@ -416,13 +416,13 @@
         {
                 int num;
                 list_test_base(int n = 0) : num(n) { }
- bool operator<(list_test_base const &other)
+ friend bool operator<(list_test::list_test_base const &left, list_test::list_test_base const &right)
                 {
- return num < other.num;
+ return left.num < right.num;
                 }
- bool operator==(list_test_base const &other)
+ friend bool operator==(list_test::list_test_base const &left, list_test::list_test_base const &right)
                 {
- return num == other.num;
+ return left.num == right.num;
                 }
         };
 
@@ -440,6 +440,7 @@
         };
 }
 
+
 BOOST_AUTO_TEST_CASE(test_list)
 {
         using namespace list_test;
@@ -450,7 +451,13 @@
         l0.push_back<L2>(3.14f, -123, "spam");
 
         list l1 = l0;
- //BOOST_ASSERT(l0 == l1);
+ bool b = l0.front() == l0.back();
+ BOOST_ASSERT(l0 == l1);
+ BOOST_ASSERT(!(l0 < l1));
+ BOOST_ASSERT(!(l1 < l0));
+ list::reference e = l1.front();
+ e.num = 41;
+ BOOST_ASSERT(l1 < l0);
 
         list::iterator iter = l1.begin();
         BOOST_ASSERT(typeid(*iter++) == typeid(L0));


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