From c4deb479fdd4e69dd1e20e1a917cb07231d0d07b Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 12 Mar 2022 01:06:00 -0500 Subject: [PATCH] Add detection support for single argument construct and destroy --- include/boost/core/allocator_access.hpp | 135 ++++++++++++++++-------- test/allocator_construct_test.cpp | 16 +++ test/allocator_destroy_test.cpp | 4 - 3 files changed, 106 insertions(+), 49 deletions(-) diff --git a/include/boost/core/allocator_access.hpp b/include/boost/core/allocator_access.hpp index 247ad75..e8e5f58 100644 --- a/include/boost/core/allocator_access.hpp +++ b/include/boost/core/allocator_access.hpp @@ -1,5 +1,5 @@ /* -Copyright 2020-2021 Glen Joseph Fernandes +Copyright 2020-2022 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. @@ -427,9 +427,72 @@ allocator_allocate(A& a, typename allocator_size_type::type n, } #endif +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_no { + char x, y; +}; + +template +class alloc_has_construct { + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static char check(long); + +public: + static const bool value = sizeof(check(0)) > 1; +}; +#else +template +class alloc_has_construct { + template + static auto check(int) + -> alloc_no().construct(std::declval(), + std::declval()...))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +template +struct alloc_if { }; + +template +struct alloc_if { + typedef T type; +}; + +} /* detail */ + #if defined(BOOST_NO_CXX11_ALLOCATOR) template -inline void +inline typename detail::alloc_if::value>::type +allocator_construct(A& a, T* p) +{ + a.construct(p); +} + +template +inline typename detail::alloc_if::value>::type allocator_construct(A&, T* p) { ::new((void*)p) T(); @@ -467,24 +530,6 @@ allocator_construct(A&, T* p, V& v) } #endif #else -namespace detail { - -template -class alloc_has_construct { - template - static auto check(int) - -> alloc_no().construct(std::declval(), - std::declval()...))>; - - template - static char check(long); - -public: - BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; -}; - -} /* detail */ - template inline typename std::enable_if::value>::type @@ -502,17 +547,30 @@ allocator_construct(A&, T* p, Args&&... args) } #endif -#if defined(BOOST_NO_CXX11_ALLOCATOR) -template -inline void -allocator_destroy(A&, T* p) -{ - p->~T(); - (void)p; -} -#else namespace detail { +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +class alloc_has_destroy { + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static char check(long); + +public: + static const bool value = sizeof(check(0)) > 1; +}; +#else template class alloc_has_destroy { template @@ -525,33 +583,28 @@ class alloc_has_destroy { public: BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; }; +#endif } /* detail */ template -inline typename std::enable_if::value>::type +inline typename detail::alloc_if::value>::type allocator_destroy(A& a, T* p) { a.destroy(p); } template -inline typename std::enable_if::value>::type +inline typename detail::alloc_if::value>::type allocator_destroy(A&, T* p) { p->~T(); (void)p; } -#endif namespace detail { #if defined(BOOST_NO_CXX11_ALLOCATOR) -template -struct alloc_no { - char x, y; -}; - template class alloc_has_max_size { template @@ -587,14 +640,6 @@ public: }; #endif -template -struct alloc_if { }; - -template -struct alloc_if { - typedef T type; -}; - } /* detail */ template diff --git a/test/allocator_construct_test.cpp b/test/allocator_construct_test.cpp index 2bd1db2..30f2d0e 100644 --- a/test/allocator_construct_test.cpp +++ b/test/allocator_construct_test.cpp @@ -26,6 +26,16 @@ struct A2 { }; #endif +template +struct A3 { + typedef T value_type; + A3() { } + template + void construct(U* p) { + ::new((void*)p) U(1); + } +}; + int main() { { @@ -42,5 +52,11 @@ int main() BOOST_TEST_EQ(i, 6); } #endif + { + A3 a; + int i = 0; + boost::allocator_construct(a, &i); + BOOST_TEST_EQ(i, 1); + } return boost::report_errors(); } diff --git a/test/allocator_destroy_test.cpp b/test/allocator_destroy_test.cpp index 0b5b64e..04d794e 100644 --- a/test/allocator_destroy_test.cpp +++ b/test/allocator_destroy_test.cpp @@ -29,7 +29,6 @@ struct A1 { A1() { } }; -#if !defined(BOOST_NO_CXX11_ALLOCATOR) template struct A2 { typedef T value_type; @@ -39,7 +38,6 @@ struct A2 { *p = U(); } }; -#endif int main() { @@ -50,13 +48,11 @@ int main() BOOST_TEST_EQ(S::count, 0); ::new((void*)&s) S(); } -#if !defined(BOOST_NO_CXX11_ALLOCATOR) { A2 a; int i = 5; boost::allocator_destroy(a, &i); BOOST_TEST_EQ(i, 0); } -#endif return boost::report_errors(); }