|
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