From 151f2cf645be10cf324a056ca29642d1784ba716 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 27 Apr 2019 02:31:09 -0400 Subject: [PATCH] Support C++03 implementations that require reference and const_pointer --- doc/default_allocator.qbk | 8 ++-- include/boost/core/default_allocator.hpp | 36 ++++++++++++++++ test/default_allocator_test.cpp | 54 ++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/doc/default_allocator.qbk b/doc/default_allocator.qbk index 87de8c3..f92e51b 100644 --- a/doc/default_allocator.qbk +++ b/doc/default_allocator.qbk @@ -21,9 +21,8 @@ The header provides the class template * Like C++2a's `std::allocator`, does not provide members such as `construct()` and `destroy()` to be eligible for optimizations by allocator-aware code that -detects the absence of these members to provide more optimal construction of -objects. -* Supports `BOOST_NO_EXCEPTIONS`. +detects the absence of these members to provide more optimal construction. +* Supports `BOOST_NO_EXCEPTIONS` in allocation. * Does not have `std` as an associated namespace. [endsect] @@ -37,6 +36,9 @@ template struct default_allocator { typedef T value_type; typedef T* pointer; + typedef const T* const_pointer; + typedef std::add_lvalue_reference_t reference; + typedef std::add_lvalue_reference_t const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef ``['true_type]`` propagate_on_container_move_assignment; diff --git a/include/boost/core/default_allocator.hpp b/include/boost/core/default_allocator.hpp index 00bfd61..20bf39e 100644 --- a/include/boost/core/default_allocator.hpp +++ b/include/boost/core/default_allocator.hpp @@ -12,6 +12,12 @@ Distributed under the Boost Software License, Version 1.0. #include #include +#if defined(BOOST_NO_CXX11_ALLOCATOR) +#define BOOST_CORE_NO_CXX11_ALLOCATOR +#elif defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000 +#define BOOST_CORE_NO_CXX11_ALLOCATOR +#endif + namespace boost { #if defined(BOOST_NO_EXCEPTIONS) @@ -35,10 +41,28 @@ struct true_type { } }; +template +struct add_reference { + typedef T& type; +}; + +template<> +struct add_reference { + typedef void type; +}; + +template<> +struct add_reference { + typedef const void type; +}; + template struct default_allocator { typedef T value_type; typedef T* pointer; + typedef const T* const_pointer; + typedef typename add_reference::type reference; + typedef typename add_reference::type const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef true_type propagate_on_container_move_assignment; @@ -97,6 +121,18 @@ struct default_allocator { ::operator delete(p, std::nothrow); } #endif + +#if defined(BOOST_CORE_NO_CXX11_ALLOCATOR) + template + void construct(U* p, const V& v) { + ::new(p) U(v); + } + + template + void destroy(U* p) { + p->~U(); + } +#endif }; template diff --git a/test/default_allocator_test.cpp b/test/default_allocator_test.cpp index 763318b..e921747 100644 --- a/test/default_allocator_test.cpp +++ b/test/default_allocator_test.cpp @@ -7,6 +7,8 @@ Distributed under the Boost Software License, Version 1.0. */ #include #include +#include +#include class type { public: @@ -44,6 +46,42 @@ void test_pointer() boost::default_allocator::pointer); } +void test_const_pointer() +{ + BOOST_TEST_TRAIT_SAME(const int*, + boost::default_allocator::const_pointer); + BOOST_TEST_TRAIT_SAME(const type*, + boost::default_allocator::const_pointer); + BOOST_TEST_TRAIT_SAME(const int(*)[5], + boost::default_allocator::const_pointer); + BOOST_TEST_TRAIT_SAME(const void*, + boost::default_allocator::const_pointer); +} + +void test_reference() +{ + BOOST_TEST_TRAIT_SAME(int&, + boost::default_allocator::reference); + BOOST_TEST_TRAIT_SAME(type&, + boost::default_allocator::reference); + BOOST_TEST_TRAIT_SAME(int(&)[5], + boost::default_allocator::reference); + BOOST_TEST_TRAIT_SAME(void, + boost::default_allocator::reference); +} + +void test_const_reference() +{ + BOOST_TEST_TRAIT_SAME(const int&, + boost::default_allocator::const_reference); + BOOST_TEST_TRAIT_SAME(const type&, + boost::default_allocator::const_reference); + BOOST_TEST_TRAIT_SAME(const int(&)[5], + boost::default_allocator::const_reference); + BOOST_TEST_TRAIT_SAME(const void, + boost::default_allocator::const_reference); +} + void test_size_type() { BOOST_TEST_TRAIT_SAME(std::size_t, @@ -203,10 +241,25 @@ void test_not_equals() boost::default_allocator())); } +void test_container() +{ + std::vector > v; + v.push_back(1); + BOOST_TEST(v.size() == 1); + BOOST_TEST(v.front() == 1); + std::list > l; + l.push_back(1); + BOOST_TEST(l.size() == 1); + BOOST_TEST(l.front() == 1); +} + int main() { test_value_type(); test_pointer(); + test_const_pointer(); + test_reference(); + test_const_reference(); test_size_type(); test_difference_type(); test_propagate_on_container_move_assignment(); @@ -219,5 +272,6 @@ int main() test_allocate_deallocate(); test_equals(); test_not_equals(); + test_container(); return boost::report_errors(); }