|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54603 - in sandbox/cloneable: boost/cloneable boost/ptr_container libs/cloneable/test
From: christian.schladetsch_at_[hidden]
Date: 2009-07-02 21:16:53
Author: cschladetsch
Date: 2009-07-02 21:16:52 EDT (Thu, 02 Jul 2009)
New Revision: 54603
URL: http://svn.boost.org/trac/boost/changeset/54603
Log:
changed map::insert
Text files modified:
sandbox/cloneable/boost/cloneable/instance.hpp | 95 +++++++++++++++++-------
sandbox/cloneable/boost/cloneable/map.hpp | 150 ++++++++++++++++++++++++++++-----------
sandbox/cloneable/boost/cloneable/set.hpp | 26 ++++--
sandbox/cloneable/boost/ptr_container/ptr_map_adapter.hpp | 2
sandbox/cloneable/libs/cloneable/test/tests.cpp | 40 +++++----
5 files changed, 211 insertions(+), 102 deletions(-)
Modified: sandbox/cloneable/boost/cloneable/instance.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/instance.hpp (original)
+++ sandbox/cloneable/boost/cloneable/instance.hpp 2009-07-02 21:16:52 EDT (Thu, 02 Jul 2009)
@@ -14,72 +14,111 @@
{
namespace cloneable
{
+ template <class Base, class Alloc>
+ struct instance_base
+ {
+ typedef Base base_type;
+ typedef Alloc allocator_type;
+
+ private:
+ allocator_type *alloc;
+
+ public:
+ instance_base(allocator_type *al = 0) : alloc(al) { }
+
+ bool has_allocator() const
+ {
+ return alloc != 0;
+ }
+ allocator_type &get_allocator() const
+ {
+ if (!alloc)
+ throw std::exception("empty allocator");
+ return *alloc;
+ }
+ void set_allocator(allocator_type &al)
+ {
+ alloc = &al;
+ }
+
+ virtual const std::type_info &get_type() const = 0;
+ virtual void allocate() = 0;
+ virtual bool exists() const = 0;
+ virtual base_type *to_base() const = 0;
+ virtual void release() = 0;
+ };
+
/// a pointer store that can retrieve pointers from up and down
/// the inheritance tree. stores the allocator that made it.
- template <class U, class B, class Alloc>
- struct instance
+ template <class Derived, class Base, class Alloc>
+ struct instance : instance_base<Base, Alloc>
{
- typedef B base_type;
- typedef U derived_type;
- typedef Alloc allocator_type;
+ typedef instance_base<Base,Alloc> parent_type;
+ using parent_type::base_type;
+ using parent_type::allocator_type;
+
+ typedef Derived derived_type;
typedef base<derived_type, base_type> cloneable_type;
typedef typename cloneable_type::abstract_base_type abstract_base_type;
private:
cloneable_type *ptr;
- allocator_type *alloc;
public:
instance() : ptr(0), alloc(0) { }
- instance(allocator_type &al) : ptr(0), alloc(&al)
+ template <class Other>
+ instance(const instance<Other,base_type,allocator_type> &other)
+ : ptr(dynamic_cast<cloneable_type *>(other.to_base()))
+ {
+ if (other.has_allocator())
+ parent_type::set_allocator(other.get_allocator());
+ }
+ instance(allocator_type &al) : parent_type(&al), ptr(0)
{
allocate();
}
template <class A0>
- instance(allocator_type &al, A0 a0) : ptr(0), alloc(&al)
+ instance(allocator_type &al, A0 a0) : parent_type(&al), ptr(0)
{
allocate();
- new (to_derived()) U(a0);
+ new (to_derived()) derived_type(a0);
}
template <class A0, class A1>
- instance(allocator_type &al, A0 a0, A1 a1) : ptr(0), alloc(&al)
+ instance(allocator_type &al, A0 a0, A1 a1) : parent_type(&al), ptr(0)
{
allocate();
- new (to_derived()) U(a0, a1);
+ new (to_derived()) derived_type(a0, a1);
}
template <class A0, class A1, class A2>
- instance(allocator_type &al, A0 a0, A1 a1, A2 a2) : ptr(0), alloc(&al)
+ instance(allocator_type &al, A0 a0, A1 a1, A2 a2) : parent_type(&al), ptr(0)
{
allocate();
- new (to_derived()) U(a0, a1, a2);
- }
-
- operator derived_type *()
- {
- return to_derived();
- }
- operator const derived_type *() const
- {
- return to_derived();
+ new (to_derived()) derived_type(a0, a1, a2);
}
void allocate()
{
- if (!alloc)
+ if (!has_allocator())
return;
- U *u_ptr = cloneable::allocate<U>(*alloc);
- u_ptr->cloneable_type::self_ptr = u_ptr;
- ptr = u_ptr;
+ if (exists())
+ release();
+ derived_type *derived = cloneable::allocate<derived_type>(get_allocator());
+ derived->cloneable_type::self_ptr = derived;
+ ptr = derived;
}
void release()
{
- if (!alloc)
+ if (!has_allocator())
return;
- cloneable::release(ptr, *alloc);
+ cloneable::release(ptr, get_allocator());
ptr = 0;
}
+ const std::type_info &get_type() const
+ {
+ return typeid(derived_type);
+ }
bool exists() const
{
return ptr != 0;
Modified: sandbox/cloneable/boost/cloneable/map.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/map.hpp (original)
+++ sandbox/cloneable/boost/cloneable/map.hpp 2009-07-02 21:16:52 EDT (Thu, 02 Jul 2009)
@@ -18,15 +18,17 @@
{
/// a vector of heterogenous objects
// TODO: move to boost/heterogenous/map
- template <class Base, class Pred, class Alloc>//, class AbstractBase>
+ template <class Base, class Pred, class Alloc>
struct map
{
- typedef typename detail::make_clone_allocator<Alloc>::type allocator_type;
typedef Base base_type;
- //typedef ptr_map<Base, Base, Pred, allocator, allocator_type> implementation;
- typedef abstract_base<Base> abstract_base_type;
+ typedef Pred predicate_type;
+ typedef abstract_base<base_type> abstract_base_type;
+ typedef typename detail::make_clone_allocator<Alloc>::type allocator_type;
+ typedef instance_base<base_type, allocator_type> instance_base_type;
+ typedef ptr_map<abstract_base_type, abstract_base_type, Pred, allocator, allocator_type> implementation;
- typedef std::map<Base *, Base *, Pred, allocator_type> implementation;
+ //typedef std::map<abstract_base_type *, abstract_base_type *, Pred, allocator_type> implementation;
typedef typename implementation::value_type value_type;
typedef typename implementation::reference reference;
@@ -35,7 +37,7 @@
typedef typename implementation::const_iterator const_iterator;
typedef typename implementation::key_type key_type;
typedef typename implementation::mapped_type mapped_type;
- typedef map<Base, Pred, Alloc/*, AbstractBase*/> this_type;
+ typedef map<Base, Pred, Alloc> this_type;
private:
implementation impl;
@@ -55,68 +57,109 @@
*/
private:
+ typedef std::pair<iterator, bool> map_insert_result;
+
+ template <class K, class V>
+ struct insert_result
+ {
+ //TODO: typedef const_instance<K,base_type,allocator_type> key_type;
+ typedef instance<K,base_type,allocator_type> key_type;
+ typedef instance<V,base_type,allocator_type> value_type;
+
+ key_type key;
+ value_type value;
+ iterator where;
+ bool inserted;
+
+ insert_result() : inserted(false) { }
+ insert_result(const key_type &K, const value_type &V, const map_insert_result &R)
+ : key(K), value(V), where(R.first), inserted(R.second) { }
+ };
+
+ template <class K>
struct value_adder
{
+ typedef instance<K,base_type,allocator_type> key_type;
this_type *parent;
- base_type *key_instance;
+ key_type key;
- value_adder(this_type &P, base_type &K)
- : parent(&P), key_instance(&K) { }
+ value_adder(this_type &P, const key_type &K)
+ : parent(&P), key(K) { }
- template <class U>
- this_type &value()
+ template <class V>
+ insert_result<K,V> value()
{
- base_type *val = detail::construct<U,base_type>(parent->get_allocator()).to_base();
- parent->insert(std::make_pair(key_instance, val));
- return *parent;
+ instance<V,base_type,allocator_type> val(parent->get_allocator());
+ map_insert_result result = parent->insert(key.to_abstract(), val.to_abstract());
+ if (!result.second)
+ {
+ key.release();
+ val.release();
+ }
+ return insert_result<K,V>(key, val, result);
}
- // TODO: use variadic arguments or BOOST_PP to pass ctor args
- template <class U, class A0>
- this_type &value(A0 a0)
+ template <class V, class A0>
+ insert_result<K,V> value(A0 a0)
{
- base_type *val = detail::construct<U,base_type>(parent->get_allocator(), a0).to_base();
- parent->insert(std::make_pair(key_instance, val));
- return *parent;
+ instance<V,base_type,allocator_type> val(parent->get_allocator(), a0);
+ map_insert_result result = parent->insert(key.to_abstract(), val.to_abstract());
+ if (!result.second)
+ {
+ key.release();
+ val.release();
+ }
+ return insert_result<K,V>(key, val, result);
}
- template <class U, class A0, class A1>
- this_type &value(A0 a0, A1 a1)
+ template <class V, class A0, class A1>
+ insert_result<K,V> value(A0 a0, A1 a1)
{
- base_type *val = detail::construct<U,base_type>(parent->get_allocator(), a0, a1).to_base();
- parent->insert(std::make_pair(key_instance, val));
- return *parent;
+ instance<V,base_type,allocator_type> val(parent->get_allocator(), a0, a1);
+ map_insert_result result = parent->insert(key.to_abstract(), val.to_abstract());
+ if (!result.second)
+ {
+ key.release();
+ val.release();
+ }
+ return insert_result<K,V>(key, val, result);
}
};
public:
- template <class U>
- value_adder key()
+ template <class K>
+ value_adder<K> key()
{
- base_type *key_instance = detail::construct<U,base_type>(get_allocator()).to_base();
- return value_adder(*this, *key_instance);
+ instance<K,base_type,allocator_type> key_instance(get_allocator());
+ return value_adder<K>(*this, key_instance);
}
// TODO: use variadic arguments or BOOST_PP to pass ctor args
- template <class U, class A0>
- value_adder key(A0 a0)
+ template <class K, class A0>
+ value_adder<K> key(A0 a0)
{
- base_type *key_instance = detail::construct<U,base_type>(get_allocator(), a0).to_base();
- return value_adder(*this, *key_instance);
+ instance<K,base_type,allocator_type> key_instance(get_allocator(), a0);
+ return value_adder<K>(*this, key_instance);
}
- template <class U, class A0, class A1>
- value_adder key(A0 a0, A1 a1)
+ template <class K, class A0, class A1>
+ value_adder<K> key(A0 a0, A1 a1)
{
- base_type *key_instance = detail::construct<U,base_type>(get_allocator(), a0, a1).to_base();
- return value_adder(*this, *key_instance);
+ instance<K,base_type,allocator_type> key_instance(get_allocator(), a0, a1);
+ return value_adder<K>(*this, key_instance);
}
- template <class U, class A0, class A1, class A2>
- value_adder key(A0 a0, A1 a1, A2 a2)
+ template <class K, class A0, class A1, class A2>
+ value_adder<K> key(A0 a0, A1 a1, A2 a2)
{
- base_type *key_instance = detail::construct<U,base_type>(get_allocator(), a0, a1, a2).to_base();
- return value_adder(*this, *key_instance);
+ throw;
+ //base_type *key_instance = detail::construct<U,base_type>(get_allocator(), a0, a1, a2).to_base();
+ //return value_adder(*this, *key_instance);
}
// TODO: make this private
+ template <class A, class B>
+ map_insert_result insert(A a, B b)
+ {
+ return impl.insert(a, b);
+ }
void insert(value_type x)
{
impl.insert(x);
@@ -183,9 +226,28 @@
return impl.end();
}
- iterator find(key_type const &key)
+ template <class K>
+ iterator find()
{
- return impl.find(key);
+ instance<K,base_type,allocator_type> k(get_allocator());
+ BOOST_SCOPE_EXIT((k))
+ {
+ k.release();
+ }
+ BOOST_SCOPE_EXIT_END
+ return impl.find(k.to_abstract());
+ }
+
+ template <class K, class A0>
+ iterator find(A0 a0)
+ {
+ instance<K,base_type,allocator_type> k(get_allocator(), a0);
+ BOOST_SCOPE_EXIT((k))
+ {
+ k.release();
+ }
+ BOOST_SCOPE_EXIT_END
+ return impl.find(k.to_abstract());
}
//reference operator[](key_type const &key)
@@ -197,7 +259,7 @@
// return impl[n];
//}
- typename implementation::allocator_type get_allocator()
+ typename allocator_type get_allocator()
{
return impl.get_allocator();
}
Modified: sandbox/cloneable/boost/cloneable/set.hpp
==============================================================================
--- sandbox/cloneable/boost/cloneable/set.hpp (original)
+++ sandbox/cloneable/boost/cloneable/set.hpp 2009-07-02 21:16:52 EDT (Thu, 02 Jul 2009)
@@ -141,27 +141,31 @@
template <class U>
struct find
{
- template <class A0>
- static iterator given(this_type *cont, A0 a0)
+ template <class Instance>
+ static iterator search(this_type *cont, Instance &value)
{
- instance<U,base_type,allocator_type> value(cont->get_allocator(), a0);
- BOOST_SCOPE_EXIT((value))
+ BOOST_SCOPE_EXIT((&value))
{
value.release();
}
BOOST_SCOPE_EXIT_END
return cont->find_instance<U>(value);
}
+
+ static iterator given(this_type *cont)
+ {
+ return search(cont, instance<U,base_type,allocator_type>(cont->get_allocator()));
+ }
+
+ template <class A0>
+ static iterator given(this_type *cont, A0 a0)
+ {
+ return search(cont, instance<U,base_type,allocator_type>(cont->get_allocator(), a0));
+ }
template <class A0, class A1>
static iterator given(this_type *cont, A0 a0, A1 a1)
{
- instance<U,base_type,allocator_type> value(cont->get_allocator(), a0, a1);
- BOOST_SCOPE_EXIT((value))
- {
- value.release();
- }
- BOOST_SCOPE_EXIT_END
- return cont->find_instance<U>(value);
+ return search(cont, instance<U,base_type,allocator_type>(cont->get_allocator(), a0, a1));
}
};
struct default_key : base<default_key, base_type>
Modified: sandbox/cloneable/boost/ptr_container/ptr_map_adapter.hpp
==============================================================================
--- sandbox/cloneable/boost/ptr_container/ptr_map_adapter.hpp (original)
+++ sandbox/cloneable/boost/ptr_container/ptr_map_adapter.hpp 2009-07-02 21:16:52 EDT (Thu, 02 Jul 2009)
@@ -522,7 +522,7 @@
std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong
{
this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" );
- auto_type ptr( x ); // nothrow
+ auto_type ptr( x, get_allocator() ); // nothrow
std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
res = this->base().insert( std::make_pair( key, x ) ); // strong, commit
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-02 21:16:52 EDT (Thu, 02 Jul 2009)
@@ -24,7 +24,7 @@
#include <boost/cloneable/clone.hpp>
#include <boost/cloneable/vector.hpp>
#include <boost/cloneable/list.hpp>
-//#include <boost/cloneable/map.hpp>
+#include <boost/cloneable/map.hpp>
#include <boost/cloneable/set.hpp>
#include <boost/cloneable/adaptor.hpp>
@@ -459,22 +459,30 @@
}
+struct wtf_less
+{
+ template <class A, class B>
+ bool operator()(A const &a, B const &b) const
+ {
+ return a->number < b->number;
+ }
+};
+
BOOST_AUTO_TEST_CASE(test_map)
{
- /*
using namespace map_test;
- typedef cloneable::map<map_test::my_base> map_type;
+ typedef cloneable::map<map_test::my_base, wtf_less> map_type;
map_type map;
- map .key<M0>(42).value<M1>("foo")
- .key<M2>().value<M3>()
- ;
- M0 *m0 = create<M0>(map.get_allocator(), 42);
- map_type::iterator iter = map.find(m0);
+ map.key<M0>(42).value<M1>("foo");
+ map.key<M2>().value<M3>();
+
+ //M0 *m0 = create<M0>(map.get_allocator(), 42);
+ map_type::iterator iter = map.find<M0>(42);
+
BOOST_ASSERT(iter!= map.end());
M1 *m1 = dynamic_cast<M1 *>(iter->second);
BOOST_ASSERT(m1 != 0);
BOOST_ASSERT(m1->str == "foo");
- */
}
BOOST_AUTO_TEST_CASE(test_hash)
@@ -546,16 +554,11 @@
using namespace set_test;
typedef cloneable::set<set_base> Set;
Set set;
- const S0 *s0 = &*set.emplace<S0>(1).value;
+ const S0 *s0 = set.emplace<S0>(1).value.to_derived();
set.emplace<S1>(2);
set.emplace<S2>(3);
set.emplace<S2>(4);
- /*
- BOOST_FOREACH(Set::value_type const &val, set)
- {
- BOOST_ASSERT(val != 0);
- }
- */
+
Set::const_iterator A = set.begin(), B = set.end();
for (; A != B; ++A)
{
@@ -565,12 +568,13 @@
BOOST_ASSERT(set.size() == 4);
BOOST_ASSERT(set.find<S0>(1) != set.end());
+ BOOST_ASSERT(&*set.find<S0>(1) == s0);
BOOST_ASSERT(set.find<set_base>(2) != set.end());
+ BOOST_ASSERT(set.find<S1>(1) == set.end());
+ BOOST_ASSERT(set.find<set_base>(1) != set.end());
Set copy = set;
-// BOOST_ASSERT(copy == set);
-
BOOST_ASSERT(copy.size() == 4);
BOOST_ASSERT(copy.find<S0>(1) != copy.end());
BOOST_ASSERT(copy.find<set_base>(2) != copy.end());
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