diff --git a/doc/allocator_access.qbk b/doc/allocator_access.qbk
index 0bcc044..0d0eb34 100644
--- a/doc/allocator_access.qbk
+++ b/doc/allocator_access.qbk
@@ -21,9 +21,8 @@ templates to simplify allocator use. It provides the same functionality as the
C++ standard library `std::allocator_traits` but with individual templates for
each allocator feature.
-This implementation supports C++03 and above. These facilities also simplify
-existing libraries by avoiding having to check for `BOOST_NO_CXX11_ALLOCATOR`
-and conditionally use `std::allocator_traits`.
+These facilities also simplify existing libraries by avoiding having to check
+for `BOOST_NO_CXX11_ALLOCATOR` and conditionally use `std::allocator_traits`.
[endsect]
@@ -142,14 +141,14 @@ allocator_pointer_t allocator_allocate(A& a, allocator_size_type_t n);
template
allocator_pointer_t allocator_allocate(A& a, allocator_size_type_t n,
- allocator_const_void_pointer_t hint);
+ allocator_const_void_pointer_t h);
template
void allocator_deallocate(A& a, allocator_pointer_t p,
allocator_size_type_t n);
template
-void allocator_construct(A& a, T*p, Args&&... args);
+void allocator_construct(A& a, T* p, Args&&... args);
template
void allocator_destroy(A& a, T* p);
diff --git a/include/boost/core/allocator_access.hpp b/include/boost/core/allocator_access.hpp
index 2a5d3c3..bfe08f7 100644
--- a/include/boost/core/allocator_access.hpp
+++ b/include/boost/core/allocator_access.hpp
@@ -8,40 +8,53 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP
#define BOOST_CORE_ALLOCATOR_ACCESS_HPP
+#include
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include
+#if !defined(BOOST_MSVC)
#include
-#if defined(BOOST_DINKUMWARE_STDLIB)
+#else
#include
#endif
-#include
-#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
#include
#endif
+#include
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include
#endif
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) || \
- defined(BOOST_MSVC) && BOOST_MSVC == 1800
-#define BOOST_CORE_ALLOCATOR_DETECTION
+namespace boost {
+namespace detail {
+
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+struct alloc_false {
+ BOOST_STATIC_CONSTEXPR bool value = false;
+};
+#else
+template
+struct alloc_void {
+ typedef void type;
+};
#endif
-namespace boost {
+} /* detail */
template
struct allocator_value_type {
typedef typename A::value_type type;
};
-namespace detail {
-
-template
-struct alloc_void {
- typedef void type;
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_pointer {
+ typedef typename A::pointer type;
};
-
-} /* detail */
-
+#elif defined(BOOST_MSVC)
+template
+struct allocator_pointer {
+ typedef typename std::allocator_traits::pointer type;
+};
+#else
template
struct allocator_pointer {
typedef typename A::value_type* type;
@@ -52,7 +65,19 @@ struct allocator_pointer::type> {
typedef typename A::pointer type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_const_pointer {
+ typedef typename A::const_pointer type;
+};
+#elif defined(BOOST_MSVC)
+template
+struct allocator_const_pointer {
+ typedef typename std::allocator_traits::const_pointer type;
+};
+#else
template
struct allocator_const_pointer {
typedef typename pointer_traits::type> {
typedef typename A::const_pointer type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_void_pointer {
+ typedef typename A::template rebind::other::pointer type;
+};
+#else
template
struct allocator_void_pointer {
typedef typename pointer_traits::type> {
typedef typename A::void_pointer type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_const_void_pointer {
+ typedef typename A::template rebind::other::const_pointer type;
+};
+#else
template
struct allocator_const_void_pointer {
typedef typename pointer_traits::type> {
typedef typename A::const_void_pointer type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_difference_type {
+ typedef typename A::difference_type type;
+};
+#else
template
struct allocator_difference_type {
typedef typename pointer_traits::type> {
typedef typename A::difference_type type;
};
+#endif
-#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_size_type {
+ typedef typename A::size_type type;
+};
+#else
template
struct allocator_size_type {
typedef typename std::make_unsigned::type> {
typedef typename A::size_type type;
};
-#else
+#endif
+
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
template
-struct allocator_size_type {
- typedef typename A::size_type type;
+struct allocator_propagate_on_container_copy_assignment {
+ typedef detail::alloc_false type;
};
-#endif
-
-namespace detail {
-
-#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
-typedef std::false_type alloc_false_type;
#else
-struct alloc_false_type {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-#endif
-
-} /* detail */
-
template
struct allocator_propagate_on_container_copy_assignment {
- typedef detail::alloc_false_type type;
+ typedef std::false_type type;
};
template
@@ -146,10 +187,17 @@ struct allocator_propagate_on_container_copy_assignment::type> {
typedef typename A::propagate_on_container_copy_assignment type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_propagate_on_container_move_assignment {
+ typedef detail::alloc_false type;
+};
+#else
template
struct allocator_propagate_on_container_move_assignment {
- typedef detail::alloc_false_type type;
+ typedef std::false_type type;
};
template
@@ -158,10 +206,17 @@ struct allocator_propagate_on_container_move_assignment::type> {
typedef typename A::propagate_on_container_move_assignment type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_propagate_on_container_swap {
+ typedef detail::alloc_false type;
+};
+#else
template
struct allocator_propagate_on_container_swap {
- typedef detail::alloc_false_type type;
+ typedef std::false_type type;
};
template
@@ -170,52 +225,46 @@ struct allocator_propagate_on_container_swap::type> {
typedef typename A::propagate_on_container_swap type;
};
+#endif
-#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
-template
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
struct allocator_is_always_equal {
- typedef typename std::is_empty::type type;
+ typedef detail::alloc_false type;
};
#else
template
struct allocator_is_always_equal {
- typedef typename detail::alloc_false_type type;
+ typedef typename std::is_empty::type type;
};
-#endif
template
struct allocator_is_always_equal::type> {
typedef typename A::is_always_equal type;
};
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+struct allocator_rebind {
+ typedef typename A::template rebind::other type;
+};
+#elif defined(BOOST_MSVC)
+template
+struct allocator_rebind {
+ typedef typename std::allocator_traits::template rebind_alloc type;
+};
+#else
namespace detail {
template
struct alloc_to { };
-#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template class A, class T, class U, class... V>
struct alloc_to, T> {
typedef A type;
};
-#else
-template class A, class T, class U>
-struct alloc_to, T> {
- typedef A type;
-};
-
-template class A, class T, class U1, class U2>
-struct alloc_to, T> {
- typedef A type;
-};
-
-template class A, class T, class U1, class U2,
- class U3>
-struct alloc_to, T> {
- typedef A type;
-};
-#endif
} /* detail */
@@ -229,6 +278,7 @@ struct allocator_rebind::other>::type> {
typedef typename A::template rebind::other type;
};
+#endif
template
inline typename allocator_pointer::type
@@ -237,98 +287,6 @@ allocator_allocate(A& a, typename allocator_size_type::type n)
return a.allocate(n);
}
-namespace detail {
-
-template
-struct alloc_if { };
-
-template
-struct alloc_if {
- typedef R type;
-};
-
-template
-struct alloc_enable {
- BOOST_STATIC_CONSTEXPR bool value = true;
-};
-
-#if defined(BOOST_DINKUMWARE_STDLIB)
-template
-struct alloc_enable > {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-#endif
-
-#if defined(BOOST_CORE_ALLOCATOR_DETECTION)
-template
-T alloc_declval() BOOST_NOEXCEPT;
-#endif
-
-#if defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_yes {
- BOOST_STATIC_CONSTEXPR bool value = true;
-};
-
-struct alloc_no {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-#endif
-
-template
-struct alloc_has_allocate {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
-template
-struct alloc_has_allocate().allocate(alloc_declval(),
- alloc_declval()), void())> {
- BOOST_STATIC_CONSTEXPR bool value = true;
-};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_allocate {
-private:
- template
- static auto call(int, U& a) ->
- alloc_yes(),
- alloc_declval()))>;
-
- template
- static alloc_no call(long, U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
-
-} /* detail */
-
-template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_allocate::type,
- typename allocator_const_void_pointer::type>::value,
- typename allocator_pointer::type>::type
-allocator_allocate(A& a, typename allocator_size_type::type n,
- typename allocator_const_void_pointer::type h)
-{
- return a.allocate(n, h);
-}
-
-template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_allocate::type,
- typename allocator_const_void_pointer::type>::value,
- typename allocator_pointer::type>::type
-allocator_allocate(A& a, typename allocator_size_type::type n,
- typename allocator_const_void_pointer::type)
-{
- return a.allocate(n);
-}
-
template
inline void
allocator_deallocate(A& a, typename allocator_pointer::type p,
@@ -337,191 +295,158 @@ allocator_deallocate(A& a, typename allocator_pointer::type p,
a.deallocate(p, n);
}
-namespace detail {
-
-template
-struct alloc_has_construct {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
-template
-struct alloc_has_construct().construct(alloc_declval()), void())> {
- BOOST_STATIC_CONSTEXPR bool value = true;
-};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_construct {
-private:
- template
- static auto call(int, U& a) ->
- alloc_yes()))>;
-
- template
- static alloc_no call(long, U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
-
-} /* detail */
-
-template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_construct::value>::type
-allocator_construct(A& a, T* p)
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+inline typename allocator_pointer::type
+allocator_allocate(A& a, typename allocator_size_type::type n,
+ typename allocator_const_void_pointer::type h)
{
- a.construct(p);
+ return a.allocate(n, h);
}
-
-template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_construct::value>::type
-allocator_construct(A&, T* p)
+#elif defined(BOOST_MSVC)
+template
+inline typename allocator_pointer::type
+allocator_allocate(A& a, typename allocator_size_type::type n,
+ typename allocator_const_void_pointer::type h)
{
- ::new((void*)p) T();
-}
-
-#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
- !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-namespace detail {
-
-template
-struct alloc_has_construct_args {
- BOOST_STATIC_CONSTEXPR bool value = false;
-};
-
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
-template
-struct alloc_has_construct_args().construct(alloc_declval(), alloc_declval()...), void()),
- A, T, Args...> {
- BOOST_STATIC_CONSTEXPR bool value = true;
-};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_construct_args {
-private:
- template
- static auto call(int, U& a) ->
- alloc_yes(),
- alloc_declval()...))>;
-
- template
- static alloc_no call(long, U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
-
-} /* detail */
-
-template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_construct_args::value>::type
-allocator_construct(A& a, T* p, V&& v, Args&&... args)
-{
- a.construct(p, std::forward(v), std::forward(args)...);
-}
-
-template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_construct_args::value>::type
-allocator_construct(A&, T* p, V&& v, Args&&... args)
-{
- ::new((void*)p) T(std::forward(v), std::forward(args)...);
+ return std::allocator_traits::allocate(a, n, h);
}
#else
namespace detail {
template
-struct alloc_has_construct_arg {
+struct alloc_has_allocate {
BOOST_STATIC_CONSTEXPR bool value = false;
};
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
-template
-struct alloc_has_construct_arg().construct(alloc_declval(),
- alloc_declval()), void())> {
+template
+struct alloc_has_allocate().allocate(std::declval(),
+ std::declval()))>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_construct_arg {
-private:
- template
- static auto call(int, U& a) ->
- alloc_yes(),
- alloc_declval()))>;
-
- template
- static alloc_no call(long, U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
} /* detail */
-#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_construct_arg::value>::type
-allocator_construct(A& a, T* p, V&& v)
+template
+inline typename std::enable_if::type,
+ typename allocator_const_void_pointer::type>::value,
+ typename allocator_pointer::type>::type
+allocator_allocate(A& a, typename allocator_size_type::type n,
+ typename allocator_const_void_pointer::type h)
{
- a.construct(p, std::forward(v));
+ return a.allocate(n, h);
}
+template
+inline typename std::enable_if::type,
+ typename allocator_const_void_pointer::type>::value,
+ typename allocator_pointer::type>::type
+allocator_allocate(A& a, typename allocator_size_type::type n,
+ typename allocator_const_void_pointer::type)
+{
+ return a.allocate(n);
+}
+#endif
+
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+inline void
+allocator_construct(A&, T* p)
+{
+ ::new((void*)p) T();
+}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+template
+inline void
+allocator_construct(A&, T* p, V&& v, Args&&... args)
+{
+ ::new((void*)p) T(std::forward(v), std::forward(args)...);
+}
+#else
template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_construct_arg::value>::type
+inline void
allocator_construct(A&, T* p, V&& v)
{
::new((void*)p) T(std::forward(v));
}
+#endif
#else
template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_construct_arg::value>::type
-allocator_construct(A& a, T* p, const V& v)
-{
- a.construct(p, v);
-}
-
-template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_construct_arg::value>::type
+inline void
allocator_construct(A&, T* p, const V& v)
{
::new((void*)p) T(v);
}
template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_construct_arg::value>::type
-allocator_construct(A& a, T* p, V& v)
-{
- a.construct(p, v);
-}
-
-template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_construct_arg::value>::type
+inline void
allocator_construct(A&, T* p, V& v)
{
::new((void*)p) T(v);
}
#endif
+#elif defined(BOOST_MSVC)
+template
+inline void
+allocator_construct(A& a, T* p, Args&&... args)
+{
+ std::allocator_traits::construct(a, p, std::forward(args)...);
+}
+#else
+namespace detail {
+
+template
+struct alloc_has_construct {
+ BOOST_STATIC_CONSTEXPR bool value = false;
+};
+
+template
+struct alloc_has_construct().construct(std::declval(), std::declval()...))>::type,
+ A, T, Args...> {
+ BOOST_STATIC_CONSTEXPR bool value = true;
+};
+
+} /* detail */
+
+template
+inline typename std::enable_if::value>::type
+allocator_construct(A& a, T* p, Args&&... args)
+{
+ a.construct(p, std::forward(args)...);
+}
+
+template
+inline typename std::enable_if::value>::type
+allocator_construct(A&, T* p, Args&&... args)
+{
+ ::new((void*)p) T(std::forward(args)...);
+}
#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+inline void
+allocator_destroy(A&, T* p)
+{
+ p->~T();
+ (void)p;
+}
+#elif defined(BOOST_MSVC)
+template
+inline void
+allocator_destroy(A& a, T* p)
+{
+ std::allocator_traits::destroy(a, p);
+}
+#else
namespace detail {
template
@@ -529,48 +454,46 @@ struct alloc_has_destroy {
BOOST_STATIC_CONSTEXPR bool value = false;
};
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
template
struct alloc_has_destroy().destroy(alloc_declval()), void())> {
+ typename alloc_void().destroy(std::declval()))>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_destroy {
-private:
- template
- static auto call(int, U& a) ->
- alloc_yes()))>;
-
- template
- static alloc_no call(long, U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
} /* detail */
template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_destroy::value>::type
+inline typename std::enable_if::value>::type
allocator_destroy(A& a, T* p)
{
a.destroy(p);
}
template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_destroy::value>::type
+inline typename std::enable_if::value>::type
allocator_destroy(A&, T* p)
{
p->~T();
(void)p;
}
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+inline typename allocator_size_type::type
+allocator_max_size(const A& a)
+{
+ return a.max_size();
+}
+#elif defined(BOOST_MSVC)
+template
+inline typename allocator_size_type::type
+allocator_max_size(const A& a)
+{
+ return std::allocator_traits::max_size(a);
+}
+#else
namespace detail {
template
@@ -578,49 +501,48 @@ struct alloc_has_max_size {
BOOST_STATIC_CONSTEXPR bool value = false;
};
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
template
struct alloc_has_max_size().max_size(), void())> {
+ typename alloc_void().max_size())>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
-#elif defined(BOOST_MSVC) && BOOST_MSVC == 1800
-template
-struct alloc_has_max_size {
-private:
- template
- static auto call(int, const U& a) -> alloc_yes;
-
- template
- static alloc_no call(long, const U&);
-
-public:
- BOOST_STATIC_CONSTEXPR bool value = decltype(call(0,
- alloc_declval()))::value;
-};
-#endif
} /* detail */
template
-inline typename detail::alloc_if::value &&
- detail::alloc_has_max_size::value,
- typename allocator_size_type::type>::type
+inline typename std::enable_if::value,
+ typename allocator_size_type::type>::type
allocator_max_size(const A& a)
{
return a.max_size();
}
template
-inline typename detail::alloc_if::value ||
- !detail::alloc_has_max_size::value,
- typename allocator_size_type::type>::type
+inline typename std::enable_if::value,
+ typename allocator_size_type::type>::type
allocator_max_size(const A&)
{
return (std::numeric_limits::type>::max)() / sizeof(typename A::value_type);
}
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+template
+inline A
+allocator_select_on_container_copy_construction(const A& a)
+{
+ return a;
+}
+#elif defined(BOOST_MSVC)
+template
+inline A
+allocator_select_on_container_copy_construction(const A& a)
+{
+ return std::allocator_traits::select_on_container_copy_construction(a);
+}
+#else
namespace detail {
template
@@ -628,47 +550,29 @@ struct alloc_has_soccc {
BOOST_STATIC_CONSTEXPR bool value = false;
};
-#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
template
struct alloc_has_soccc