Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73678 - in trunk: boost/unordered boost/unordered/detail libs/unordered/test/objects libs/unordered/test/unordered
From: dnljms_at_[hidden]
Date: 2011-08-11 17:17:59


Author: danieljames
Date: 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
New Revision: 73678
URL: http://svn.boost.org/trac/boost/changeset/73678

Log:
Unordered: Starting to support allocator_traits.
Text files modified:
   trunk/boost/unordered/detail/allocator_helpers.hpp | 192 +++++++++++++++++++++++++++++++++++++--
   trunk/boost/unordered/detail/buckets.hpp | 25 ++--
   trunk/boost/unordered/detail/equivalent.hpp | 10 +-
   trunk/boost/unordered/detail/node.hpp | 15 +-
   trunk/boost/unordered/detail/table.hpp | 40 ++++----
   trunk/boost/unordered/detail/unique.hpp | 10 +-
   trunk/boost/unordered/unordered_map.hpp | 25 ++--
   trunk/boost/unordered/unordered_set.hpp | 26 ++--
   trunk/libs/unordered/test/objects/minimal.hpp | 64 +++++++++++++
   trunk/libs/unordered/test/unordered/compile_map.cpp | 57 +++++++++++
   trunk/libs/unordered/test/unordered/compile_set.cpp | 59 ++++++++++++
   11 files changed, 435 insertions(+), 88 deletions(-)

Modified: trunk/boost/unordered/detail/allocator_helpers.hpp
==============================================================================
--- trunk/boost/unordered/detail/allocator_helpers.hpp (original)
+++ trunk/boost/unordered/detail/allocator_helpers.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -1,9 +1,12 @@
 
 // Copyright 2005-2011 Daniel James.
+// Copyright 2009 Pablo Halpern.
+//
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// A couple of templates to make using allocators easier.
+//
+// Written by Daniel James using some code from Pablo Halpern's
+// allocator traits implementation.
 
 #ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
 #define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
@@ -13,6 +16,7 @@
 #endif
 
 #include <boost/config.hpp>
+#include <boost/detail/select_type.hpp>
 
 #if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
     && !defined(__BORLANDC__)
@@ -23,24 +27,185 @@
 # include <boost/detail/allocator_utilities.hpp>
 #endif
 
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+# include <memory>
+#endif
+
+#if !defined(BOOST_NO_0X_HDR_TYPE_TRAITS)
+#include <type_traits>
+namespace boost { namespace unordered { namespace detail {
+ using std::integral_constant;
+ using std::true_type;
+ using std::false_type;
+}}}
+#else
+namespace boost { namespace unordered { namespace detail {
+ template <typename T, T Value>
+ struct integral_constant { enum { value = Value }; };
+ typedef integral_constant<bool, true> true_type;
+ typedef integral_constant<bool, false> false_type;
+}}}
+#endif
+
 namespace boost { namespace unordered { namespace detail {
 
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+ template <typename Alloc>
+ struct allocator_traits : std::allocator_traits<Alloc> {};
+
+ template <typename Alloc, typename T>
+ struct rebind_wrap
+ {
+ typedef typename allocator_traits<Alloc>::rebind_alloc<T> type;
+ };
+#else
     // rebind_wrap
     //
     // Rebind allocators. For some problematic libraries, use rebind_to
     // from <boost/detail/allocator_utilities.hpp>.
 
-#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
- template <class Alloc, class T>
+# if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
+ template <typename Alloc, typename T>
     struct rebind_wrap : ::boost::detail::allocator::rebind_to<Alloc, T> {};
-#else
- template <class Alloc, class T>
+# else
+ template <typename Alloc, typename T>
     struct rebind_wrap
     {
         typedef BOOST_DEDUCED_TYPENAME
             Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
             type;
     };
+# endif
+
+ struct convertible_from_anything
+ {
+ template<typename T> convertible_from_anything(T const&);
+ };
+
+ // Infrastructure for providing a default type for Tp::tname if absent.
+ #define BOOST_DEFAULT_TYPE_TMPLT(tname) \
+ template <typename Tp, typename Default> \
+ struct default_type_ ## tname { \
+ \
+ template <typename X> \
+ static char test(int, BOOST_DEDUCED_TYPENAME X::tname*); \
+ \
+ template <typename X> \
+ static int test(convertible_from_anything, void*); \
+ \
+ struct DefaultWrap { typedef Default tname; }; \
+ \
+ static const bool value = (1 == sizeof(test<Tp>(0, 0))); \
+ \
+ typedef BOOST_DEDUCED_TYPENAME \
+ boost::detail::if_true<value>:: \
+ BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \
+ ::type::tname type; \
+ }
+
+ #define BOOST_DEFAULT_TYPE(T,tname, arg) \
+ BOOST_DEDUCED_TYPENAME default_type_ ## tname<T, arg>::type
+
+ BOOST_DEFAULT_TYPE_TMPLT(pointer);
+ BOOST_DEFAULT_TYPE_TMPLT(const_pointer);
+ BOOST_DEFAULT_TYPE_TMPLT(void_pointer);
+ BOOST_DEFAULT_TYPE_TMPLT(const_void_pointer);
+ BOOST_DEFAULT_TYPE_TMPLT(difference_type);
+ BOOST_DEFAULT_TYPE_TMPLT(size_type);
+ BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment);
+ BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment);
+ BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
+
+ template <typename Alloc>
+ struct allocator_traits
+ {
+ typedef Alloc allocator_type;
+ typedef typename Alloc::value_type value_type;
+
+ typedef BOOST_DEFAULT_TYPE(Alloc, pointer, value_type*)
+ pointer;
+
+ // For now always use the allocator's const_pointer.
+
+ //typedef BOOST_DEFAULT_TYPE(Alloc, const_pointer,
+ // BOOST_DEDUCED_TYPENAME pointer_traits<pointer>::
+ // BOOST_NESTED_TEMPLATE rebind<const value_type>::other)
+ // const_pointer;
+
+ typedef BOOST_DEFAULT_TYPE(Alloc, const_pointer, value_type const*)
+ const_pointer;
+
+ // I'm not using void pointers for now.
+
+ //typedef BOOST_DEFAULT_TYPE(Alloc, void_pointer,
+ // BOOST_NESTED_TEMPLATE pointer_traits<pointer>::
+ // BOOST_NESTED_TEMPLATE rebind<void>::other)
+ // void_pointer;
+
+ //typedef BOOST_DEFAULT_TYPE(Alloc, const_void_pointer,
+ // BOOST_DEDUCED_TYPENAME pointer_traits<pointer>::
+ // BOOST_NESTED_TEMPLATE rebind<const void>::other)
+ // const_void_pointer;
+
+ typedef BOOST_DEFAULT_TYPE(Alloc, difference_type, std::ptrdiff_t)
+ difference_type;
+
+ typedef BOOST_DEFAULT_TYPE(Alloc, size_type, std::size_t)
+ size_type;
+
+ // TODO: rebind_alloc and rebind_traits
+
+ static pointer allocate(Alloc& a, size_type n)
+ { return a.allocate(n); }
+
+ // I never use this, so I'll just comment it out for now.
+ //
+ //static pointer allocate(Alloc& a, size_type n, const_void_pointer hint)
+ // { return DEFAULT_FUNC(allocate, pointer)(a, n, hint); }
+
+ static void deallocate(Alloc& a, pointer p, size_type n)
+ { a.deallocate(p, n); }
+
+ // Only support the basic copy constructor
+
+ // template <typename T, typename... Args>
+ // static void construct(Alloc& a, T* p, Args&&... args) {
+ // DEFAULT_FUNC(construct,void)(a, p, std::forward<Args>(args)...);
+ // }
+
+ template <typename T>
+ static void construct(Alloc& a, T* p, T const& x) {
+ a.construct(p, x);
+ }
+
+ template <typename T>
+ static void destroy(Alloc& a, T* p) {
+ // DEFAULT_FUNC(destroy,void)(a, p);
+ a.destroy(p);
+ }
+
+ static size_type max_size(const Alloc& a)
+ { return a.max_size(); }
+
+ // Allocator propagation on construction
+
+ static Alloc select_on_container_copy_construction(const Alloc& rhs) {
+ //return BOOST_DEFAULT_FUNC(select_on_container_copy_construction,Alloc)(rhs);
+ return rhs;
+ }
+
+ // Allocator propagation on assignment and swap.
+ // Return true if lhs is modified.
+ typedef BOOST_DEFAULT_TYPE(
+ Alloc, propagate_on_container_copy_assignment, false_type)
+ propagate_on_container_copy_assignment;
+ typedef BOOST_DEFAULT_TYPE(
+ Alloc,propagate_on_container_move_assignment, false_type)
+ propagate_on_container_move_assignment;
+ typedef BOOST_DEFAULT_TYPE(
+ Alloc,propagate_on_container_swap,false_type)
+ propagate_on_container_swap;
+ };
 #endif
 
     // allocator_array_constructor
@@ -49,10 +214,11 @@
     // clean up if an exception is thrown before the container takes charge
     // of it.
 
- template <class Allocator>
+ template <typename Allocator>
     struct allocator_array_constructor
     {
- typedef BOOST_DEDUCED_TYPENAME Allocator::pointer pointer;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<Allocator>::pointer
+ pointer;
 
         Allocator& alloc_;
         pointer ptr_;
@@ -69,21 +235,21 @@
         ~allocator_array_constructor() {
             if (ptr_) {
                 for(pointer p = ptr_; p != constructed_; ++p)
- alloc_.destroy(p);
+ allocator_traits<Allocator>::destroy(alloc_, p);
 
- alloc_.deallocate(ptr_, length_);
+ allocator_traits<Allocator>::deallocate(alloc_, ptr_, length_);
             }
         }
 
- template <class V>
+ template <typename V>
         void construct(V const& v, std::size_t l)
         {
             BOOST_ASSERT(!ptr_);
             length_ = l;
- ptr_ = alloc_.allocate(length_);
+ ptr_ = allocator_traits<Allocator>::allocate(alloc_, length_);
             pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_);
             for(constructed_ = ptr_; constructed_ != end; ++constructed_)
- alloc_.construct(constructed_, v);
+ allocator_traits<Allocator>::construct(alloc_, constructed_, v);
         }
 
         pointer get() const

Modified: trunk/boost/unordered/detail/buckets.hpp
==============================================================================
--- trunk/boost/unordered/detail/buckets.hpp (original)
+++ trunk/boost/unordered/detail/buckets.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -49,16 +49,16 @@
 
         typedef A value_allocator;
         typedef ::boost::unordered::detail::bucket<A> bucket;
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
 
         typedef BOOST_DEDUCED_TYPENAME bucket::bucket_allocator
             bucket_allocator;
- typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<bucket_allocator>::pointer bucket_ptr;
         typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
 
         typedef BOOST_DEDUCED_TYPENAME rebind_wrap<value_allocator, node>::type
             node_allocator;
- typedef BOOST_DEDUCED_TYPENAME node_allocator::pointer real_node_ptr;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<node_allocator>::pointer real_node_ptr;
 
         // Members
 
@@ -91,7 +91,7 @@
         std::size_t max_bucket_count() const
         {
             // -1 to account for the start bucket.
- return prev_prime(this->bucket_alloc().max_size() - 1);
+ return prev_prime(allocator_traits<bucket_allocator>::max_size(bucket_alloc()) - 1);
         }
 
         ////////////////////////////////////////////////////////////////////////
@@ -184,8 +184,8 @@
             real_node_ptr real_ptr(node_alloc().address(*raw_ptr));
 
             ::boost::unordered::detail::destroy(raw_ptr->value_ptr());
- node_alloc().destroy(real_ptr);
- node_alloc().deallocate(real_ptr, 1);
+ allocator_traits<node_allocator>::destroy(node_alloc(), real_ptr);
+ allocator_traits<node_allocator>::deallocate(node_alloc(), real_ptr, 1);
         }
 
         void delete_buckets()
@@ -202,10 +202,10 @@
     
             ++end;
             for(bucket_ptr begin = this->buckets_; begin != end; ++begin) {
- bucket_alloc().destroy(begin);
+ allocator_traits<bucket_allocator>::destroy(bucket_alloc(), begin);
             }
     
- bucket_alloc().deallocate(this->buckets_, this->bucket_count_ + 1);
+ allocator_traits<bucket_allocator>::deallocate(bucket_alloc(), this->buckets_, this->bucket_count_ + 1);
     
             this->buckets_ = bucket_ptr();
         }
@@ -476,6 +476,7 @@
         typedef BOOST_DEDUCED_TYPENAME buckets::node node;
         typedef BOOST_DEDUCED_TYPENAME buckets::real_node_ptr real_node_ptr;
         typedef BOOST_DEDUCED_TYPENAME buckets::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
 
         buckets& buckets_;
         real_node_ptr node_;
@@ -570,9 +571,9 @@
             }
 
             if (node_constructed_)
- buckets_.node_alloc().destroy(node_);
+ allocator_traits<node_allocator>::destroy(buckets_.node_alloc(), node_);
 
- buckets_.node_alloc().deallocate(node_, 1);
+ allocator_traits<node_allocator>::deallocate(buckets_.node_alloc(), node_, 1);
         }
     }
 
@@ -583,8 +584,8 @@
             node_constructed_ = false;
             value_constructed_ = false;
 
- node_ = buckets_.node_alloc().allocate(1);
- buckets_.node_alloc().construct(node_, node());
+ node_ = allocator_traits<node_allocator>::allocate(buckets_.node_alloc(), 1);
+ allocator_traits<node_allocator>::construct(buckets_.node_alloc(), node_, node());
             node_->init(buckets_.bucket_alloc().address(*node_));
 
             node_constructed_ = true;

Modified: trunk/boost/unordered/detail/equivalent.hpp
==============================================================================
--- trunk/boost/unordered/detail/equivalent.hpp (original)
+++ trunk/boost/unordered/detail/equivalent.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -279,10 +279,10 @@
 
     template <class H, class P, class A>
     struct multiset : public types<
- BOOST_DEDUCED_TYPENAME A::value_type,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
+ BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
         H, P, A,
- set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
+ set_extractor<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
         false>
     {
         typedef equivalent_table<multiset<H, P, A> > impl;
@@ -291,9 +291,9 @@
 
     template <class K, class H, class P, class A>
     struct multimap : public types<
- K, BOOST_DEDUCED_TYPENAME A::value_type,
+ K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
         H, P, A,
- map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
+ map_extractor<K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
         false>
     {
         typedef equivalent_table<multimap<K, H, P, A> > impl;

Modified: trunk/boost/unordered/detail/node.hpp
==============================================================================
--- trunk/boost/unordered/detail/node.hpp (original)
+++ trunk/boost/unordered/detail/node.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -28,7 +28,7 @@
     //
     // For unordered_set/unordered_map:
     //
- // bucket<A> value_base<A::value_type>
+ // bucket<A> value_base<allocator_traits<A>::value_type>
     // | |
     // +--------------+-------------+
     // |
@@ -36,7 +36,7 @@
     //
     // For unordered_multiset/unordered_multimap:
     //
- // bucket<A> value_base<A::value_type>
+ // bucket<A> value_base<allocator_traits<A>::value_type>
     // | |
     // +--------------+-------------+
     // |
@@ -57,7 +57,8 @@
         typedef BOOST_DEDUCED_TYPENAME
             ::boost::unordered::detail::rebind_wrap<A, bucket>::type
             bucket_allocator;
- typedef BOOST_DEDUCED_TYPENAME bucket_allocator::pointer bucket_ptr;
+ typedef BOOST_DEDUCED_TYPENAME
+ allocator_traits<bucket_allocator>::pointer bucket_ptr;
         typedef bucket_ptr node_ptr;
     
         node_ptr next_;
@@ -101,12 +102,12 @@
     template <class A>
     struct ungrouped_node
       : ::boost::unordered::detail::bucket<A>,
- value_base<BOOST_DEDUCED_TYPENAME A::value_type>
+ value_base<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>
     {
         typedef ::boost::unordered::detail::bucket<A> bucket;
         typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
         typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
 
         std::size_t hash_;
 
@@ -176,12 +177,12 @@
     template <class A>
     struct grouped_node
       : ::boost::unordered::detail::bucket<A>,
- value_base<BOOST_DEDUCED_TYPENAME A::value_type>
+ value_base<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>
     {
         typedef ::boost::unordered::detail::bucket<A> bucket;
         typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
         typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type value_type;
 
         std::size_t hash_;
         node_ptr group_prev_;

Modified: trunk/boost/unordered/detail/table.hpp
==============================================================================
--- trunk/boost/unordered/detail/table.hpp (original)
+++ trunk/boost/unordered/detail/table.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -617,13 +617,13 @@
     class l_iterator
         : public ::boost::iterator <
             std::forward_iterator_tag,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
             std::ptrdiff_t,
- BOOST_DEDUCED_TYPENAME A::pointer,
- BOOST_DEDUCED_TYPENAME A::reference>
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::pointer,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type&>
     {
     public:
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
 
     private:
         typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
@@ -641,7 +641,7 @@
         l_iterator() : ptr_() {}
         l_iterator(node_ptr x, std::size_t b, std::size_t c)
             : ptr_(x), bucket_(b), bucket_count_(c) {}
- BOOST_DEDUCED_TYPENAME A::reference operator*() const {
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
             return node::get_value(ptr_);
         }
         value_type* operator->() const {
@@ -678,13 +678,13 @@
     class cl_iterator
         : public ::boost::iterator <
             std::forward_iterator_tag,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
             std::ptrdiff_t,
- BOOST_DEDUCED_TYPENAME A::const_pointer,
- BOOST_DEDUCED_TYPENAME A::const_reference >
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::const_pointer,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& >
     {
     public:
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
 
     private:
         typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
@@ -705,7 +705,7 @@
         cl_iterator(local_iterator x)
             : ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
         {}
- BOOST_DEDUCED_TYPENAME A::const_reference
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const&
             operator*() const {
             return node::get_value(ptr_);
         }
@@ -743,13 +743,13 @@
     class iterator
         : public ::boost::iterator <
             std::forward_iterator_tag,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
             std::ptrdiff_t,
- BOOST_DEDUCED_TYPENAME A::pointer,
- BOOST_DEDUCED_TYPENAME A::reference >
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::pointer,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& >
     {
     public:
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
 
     private:
         typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
@@ -763,7 +763,7 @@
 
         iterator() : node_() {}
         explicit iterator(node_ptr const& x) : node_(x) {}
- BOOST_DEDUCED_TYPENAME A::reference operator*() const {
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type& operator*() const {
             return node::get_value(node_);
         }
         value_type* operator->() const {
@@ -793,13 +793,13 @@
     class c_iterator
         : public ::boost::iterator <
             std::forward_iterator_tag,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type,
             std::ptrdiff_t,
- BOOST_DEDUCED_TYPENAME A::const_pointer,
- BOOST_DEDUCED_TYPENAME A::const_reference >
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::const_pointer,
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& >
     {
     public:
- typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type value_type;
 
     private:
         typedef ::boost::unordered::detail::buckets<A, Unique> buckets;
@@ -829,7 +829,7 @@
         c_iterator() : node_() {}
         explicit c_iterator(node_ptr const& x) : node_(x) {}
         c_iterator(iterator const& x) : node_(x.node_) {}
- BOOST_DEDUCED_TYPENAME A::const_reference operator*() const {
+ BOOST_DEDUCED_TYPENAME boost::unordered::detail::allocator_traits<A>::value_type const& operator*() const {
             return node::get_value(node_);
         }
         value_type const* operator->() const {

Modified: trunk/boost/unordered/detail/unique.hpp
==============================================================================
--- trunk/boost/unordered/detail/unique.hpp (original)
+++ trunk/boost/unordered/detail/unique.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -370,10 +370,10 @@
 
     template <class H, class P, class A>
     struct set : public types<
- BOOST_DEDUCED_TYPENAME A::value_type,
- BOOST_DEDUCED_TYPENAME A::value_type,
+ BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
+ BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
         H, P, A,
- set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
+ set_extractor<BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
         true>
     {
         typedef ::boost::unordered::detail::unique_table<set<H, P, A> > impl;
@@ -382,9 +382,9 @@
 
     template <class K, class H, class P, class A>
     struct map : public types<
- K, BOOST_DEDUCED_TYPENAME A::value_type,
+ K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type,
         H, P, A,
- map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
+ map_extractor<K, BOOST_DEDUCED_TYPENAME allocator_traits<A>::value_type>,
         true>
     {
         typedef ::boost::unordered::detail::unique_table<map<K, H, P, A> > impl;

Modified: trunk/boost/unordered/unordered_map.hpp
==============================================================================
--- trunk/boost/unordered/unordered_map.hpp (original)
+++ trunk/boost/unordered/unordered_map.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -56,6 +56,7 @@
             ::boost::unordered::detail::rebind_wrap<
                 allocator_type, value_type>::type
             value_allocator;
+ typedef ::boost::unordered::detail::allocator_traits<value_allocator> allocator_traits;
 
         typedef ::boost::unordered::detail::map<K, H, P,
             value_allocator> types;
@@ -66,13 +67,12 @@
     public:
 
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::pointer pointer;
+ allocator_traits::pointer pointer;
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::reference reference;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_reference const_reference;
+ allocator_traits::const_pointer const_pointer;
+
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
 
         typedef std::size_t size_type;
         typedef std::ptrdiff_t difference_type;
@@ -407,6 +407,8 @@
             ::boost::unordered::detail::rebind_wrap<
                 allocator_type, value_type>::type
             value_allocator;
+ typedef ::boost::unordered::detail::allocator_traits<value_allocator>
+ allocator_traits;
 
         typedef ::boost::unordered::detail::multimap<K, H, P,
             value_allocator> types;
@@ -417,13 +419,12 @@
     public:
 
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::pointer pointer;
+ allocator_traits::pointer pointer;
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::reference reference;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_reference const_reference;
+ allocator_traits::const_pointer const_pointer;
+
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
 
         typedef std::size_t size_type;
         typedef std::ptrdiff_t difference_type;

Modified: trunk/boost/unordered/unordered_set.hpp
==============================================================================
--- trunk/boost/unordered/unordered_set.hpp (original)
+++ trunk/boost/unordered/unordered_set.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -56,6 +56,8 @@
             ::boost::unordered::detail::rebind_wrap<
                 allocator_type, value_type>::type
             value_allocator;
+ typedef ::boost::unordered::detail::allocator_traits<value_allocator>
+ allocator_traits;
 
         typedef ::boost::unordered::detail::set<H, P,
             value_allocator> types;
@@ -66,13 +68,12 @@
     public:
 
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::pointer pointer;
+ allocator_traits::pointer pointer;
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::reference reference;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_reference const_reference;
+ allocator_traits::const_pointer const_pointer;
+
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
 
         typedef std::size_t size_type;
         typedef std::ptrdiff_t difference_type;
@@ -387,6 +388,8 @@
             ::boost::unordered::detail::rebind_wrap<
                 allocator_type, value_type>::type
             value_allocator;
+ typedef ::boost::unordered::detail::allocator_traits<value_allocator>
+ allocator_traits;
 
         typedef ::boost::unordered::detail::multiset<H, P,
             value_allocator> types;
@@ -397,13 +400,12 @@
     public:
 
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::pointer pointer;
+ allocator_traits::pointer pointer;
         typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::reference reference;
- typedef BOOST_DEDUCED_TYPENAME
- value_allocator::const_reference const_reference;
+ allocator_traits::const_pointer const_pointer;
+
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
 
         typedef std::size_t size_type;
         typedef std::ptrdiff_t difference_type;

Modified: trunk/libs/unordered/test/objects/minimal.hpp
==============================================================================
--- trunk/libs/unordered/test/objects/minimal.hpp (original)
+++ trunk/libs/unordered/test/objects/minimal.hpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -33,6 +33,7 @@
     template <class T> class ptr;
     template <class T> class const_ptr;
     template <class T> class allocator;
+ template <class T> class cxx11_allocator;
 
     class copy_constructible
     {
@@ -316,6 +317,69 @@
     void swap(allocator<T>&, allocator<T>&)
     {
     }
+
+ // C++11 allocator
+ //
+ // Not a fully minimal C++11 allocator, just what I support. Hopefully will
+ // cut down further in the future.
+
+ template <class T>
+ class cxx11_allocator
+ {
+ public:
+ typedef T value_type;
+ template <class U> struct rebind { typedef cxx11_allocator<U> other; };
+
+ cxx11_allocator() {}
+ template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {}
+ cxx11_allocator(cxx11_allocator const&) {}
+ ~cxx11_allocator() {}
+
+ T* address(T& r) { return &r; }
+ T const* address(T const& r) { return &r; }
+
+ T* allocate(std::size_t n) {
+ return static_cast<T*>(::operator new(n * sizeof(T)));
+ }
+
+ template <class Y>
+ T* allocate(std::size_t n, const_ptr<Y> u) {
+ return static_cast<T*>(::operator new(n * sizeof(T)));
+ }
+
+ void deallocate(T* p, std::size_t) {
+ ::operator delete((void*) p);
+ }
+
+ void construct(T* p, T const& t) { new((void*)p) T(t); }
+
+#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
+ template<class... Args> void construct(T* p, Args&&... args) {
+ new((void*)p) T(std::forward<Args>(args)...);
+ }
+#endif
+
+ void destroy(T* p) { p->~T(); }
+
+ std::size_t max_size() const { return 1000u; }
+ };
+
+ template <class T>
+ inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
+ {
+ return true;
+ }
+
+ template <class T>
+ inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
+ {
+ return false;
+ }
+
+ template <class T>
+ void swap(cxx11_allocator<T>&, cxx11_allocator<T>&)
+ {
+ }
 }
 }
 

Modified: trunk/libs/unordered/test/unordered/compile_map.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/compile_map.cpp (original)
+++ trunk/libs/unordered/test/unordered/compile_map.cpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -18,6 +18,19 @@
 // Explicit instantiation to catch compile-time errors
 
 template class boost::unordered_map<
+ int,
+ int,
+ boost::hash<int>,
+ std::equal_to<int>,
+ test::minimal::allocator<std::pair<int const, int> > >;
+template class boost::unordered_multimap<
+ int,
+ int,
+ boost::hash<int>,
+ std::equal_to<int>,
+ test::minimal::allocator<std::pair<int const, int> > >;
+
+template class boost::unordered_map<
     test::minimal::assignable,
     test::minimal::default_copy_constructible,
     test::minimal::hash<test::minimal::assignable>,
@@ -42,6 +55,11 @@
 
     boost::unordered_map<int, int> int_map;
 
+ boost::unordered_map<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > int_map2;
+
     boost::unordered_map<
         test::minimal::assignable,
         test::minimal::copy_constructible,
@@ -50,12 +68,18 @@
         test::minimal::allocator<value_type> > map;
 
     container_test(int_map, std::pair<int const, int>(0, 0));
+ container_test(int_map2, std::pair<int const, int>(0, 0));
     container_test(map, value);
 
     std::cout<<"Test unordered_multimap.\n";
 
     boost::unordered_multimap<int, int> int_multimap;
 
+ boost::unordered_multimap<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > int_multimap2;
+
     boost::unordered_multimap<
         test::minimal::assignable,
         test::minimal::copy_constructible,
@@ -64,6 +88,7 @@
         test::minimal::allocator<value_type> > multimap;
 
     container_test(int_multimap, std::pair<int const, int>(0, 0));
+ container_test(int_multimap2, std::pair<int const, int>(0, 0));
     container_test(multimap, value);
 }
 
@@ -74,6 +99,11 @@
 
     boost::unordered_map<int, int> int_map;
 
+ boost::unordered_map<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > int_map2;
+
     boost::unordered_map<
         test::minimal::copy_constructible_equality_comparable,
         test::minimal::copy_constructible_equality_comparable,
@@ -82,10 +112,16 @@
         test::minimal::allocator<value_type> > map;
 
     equality_test(int_map);
+ equality_test(int_map2);
     equality_test(map);
 
     boost::unordered_multimap<int, int> int_multimap;
 
+ boost::unordered_multimap<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > int_multimap2;
+
     boost::unordered_multimap<
         test::minimal::copy_constructible_equality_comparable,
         test::minimal::copy_constructible_equality_comparable,
@@ -94,6 +130,7 @@
         test::minimal::allocator<value_type> > multimap;
 
     equality_test(int_multimap);
+ equality_test(int_multimap2);
     equality_test(multimap);
 }
 
@@ -107,18 +144,37 @@
 
     boost::unordered_map<int, int> map;
 
+ boost::unordered_map<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > map2;
+
     unordered_unique_test(map, map_value);
     unordered_map_test(map, value, value);
     unordered_test(map, value, map_value, hash, equal_to);
     unordered_map_functions(map, value, value);
 
+ unordered_unique_test(map2, map_value);
+ unordered_map_test(map2, value, value);
+ unordered_test(map2, value, map_value, hash, equal_to);
+ unordered_map_functions(map2, value, value);
+
     std::cout<<"Test unordered_multimap.\n";
 
     boost::unordered_multimap<int, int> multimap;
 
+ boost::unordered_multimap<int, int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<std::pair<int const, int> >
+ > multimap2;
+
     unordered_equivalent_test(multimap, map_value);
     unordered_map_test(multimap, value, value);
     unordered_test(multimap, value, map_value, hash, equal_to);
+
+ unordered_equivalent_test(multimap2, map_value);
+ unordered_map_test(multimap2, value, value);
+ unordered_test(multimap2, value, map_value, hash, equal_to);
 }
 
 UNORDERED_AUTO_TEST(test2)
@@ -149,7 +205,6 @@
     unordered_map_test(map, assignable, copy_constructible);
     unordered_test(map, assignable, map_value, hash, equal_to);
 
-
     boost::unordered_map<
         test::minimal::assignable,
         test::minimal::default_copy_constructible,

Modified: trunk/libs/unordered/test/unordered/compile_set.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/compile_set.cpp (original)
+++ trunk/libs/unordered/test/unordered/compile_set.cpp 2011-08-11 17:17:57 EDT (Thu, 11 Aug 2011)
@@ -16,7 +16,18 @@
 #include "./compile_tests.hpp"
 
 // Explicit instantiation to catch compile-time errors
-
+/*
+template class boost::unordered_set<
+ int,
+ boost::hash<int>,
+ std::equal_to<int>,
+ test::minimal::allocator<int> >;
+template class boost::unordered_multiset<
+ int,
+ boost::hash<int>,
+ std::equal_to<int>,
+ test::minimal::allocator<int> >;
+*/
 template class boost::unordered_set<
     test::minimal::assignable,
     test::minimal::hash<test::minimal::assignable>,
@@ -33,7 +44,14 @@
     test::minimal::assignable assignable = test::minimal::assignable::create();
 
     std::cout<<"Test unordered_set.\n";
+
     boost::unordered_set<int> int_set;
+
+ boost::unordered_set<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > int_set2;
+
     boost::unordered_set<
         test::minimal::assignable,
         test::minimal::hash<test::minimal::assignable>,
@@ -41,10 +59,18 @@
         test::minimal::allocator<test::minimal::assignable> > set;
 
     container_test(int_set, 0);
+ container_test(int_set2, 0);
     container_test(set, assignable);
 
     std::cout<<"Test unordered_multiset.\n";
+
     boost::unordered_multiset<int> int_multiset;
+
+ boost::unordered_multiset<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > int_multiset2;
+
     boost::unordered_multiset<
         test::minimal::assignable,
         test::minimal::hash<test::minimal::assignable>,
@@ -52,6 +78,7 @@
         test::minimal::allocator<test::minimal::assignable> > multiset;
 
     container_test(int_multiset, 0);
+ container_test(int_multiset2, 0);
     container_test(multiset, assignable);
 }
 
@@ -60,6 +87,11 @@
 
     boost::unordered_set<int> int_set;
 
+ boost::unordered_set<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > int_set2;
+
     boost::unordered_set<
         test::minimal::copy_constructible_equality_comparable,
         test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
@@ -67,10 +99,16 @@
         test::minimal::allocator<value_type> > set;
 
     equality_test(int_set);
+ equality_test(int_set2);
     equality_test(set);
 
     boost::unordered_multiset<int> int_multiset;
 
+ boost::unordered_multiset<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > int_multiset2;
+
     boost::unordered_multiset<
         test::minimal::copy_constructible_equality_comparable,
         test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
@@ -78,6 +116,7 @@
         test::minimal::allocator<value_type> > multiset;
 
     equality_test(int_multiset);
+ equality_test(int_multiset2);
     equality_test(multiset);
 }
 
@@ -91,17 +130,35 @@
 
     boost::unordered_set<int> set;
     
+ boost::unordered_set<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > set2;
+
     unordered_unique_test(set, value);
     unordered_set_test(set, value);
     unordered_test(set, value, value, hash, equal_to);
 
+ unordered_unique_test(set2, value);
+ unordered_set_test(set2, value);
+ unordered_test(set2, value, value, hash, equal_to);
+
     std::cout<<"Test unordered_multiset.\n";
 
     boost::unordered_multiset<int> multiset;
     
+ boost::unordered_multiset<int,
+ boost::hash<int>, std::equal_to<int>,
+ test::minimal::cxx11_allocator<int>
+ > multiset2;
+
     unordered_equivalent_test(multiset, value);
     unordered_set_test(multiset, value);
     unordered_test(multiset, value, value, hash, equal_to);
+
+ unordered_equivalent_test(multiset2, value);
+ unordered_set_test(multiset2, value);
+ unordered_test(multiset2, value, value, hash, equal_to);
 }
 
 UNORDERED_AUTO_TEST(test2)


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