|
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