From c31e23b36294bc3958b04deef62123abce0204b9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 13 Apr 2020 01:43:43 -0400 Subject: [PATCH] Implement allocator access utilities --- doc/allocator_access.qbk | 244 +++++++++ doc/core.qbk | 1 + include/boost/core/allocator_access.hpp | 545 +++++++++++++++++++++ test/Jamfile.v2 | 18 + test/allocator_allocate_hint_test.cpp | 61 +++ test/allocator_allocate_test.cpp | 31 ++ test/allocator_const_pointer_test.cpp | 30 ++ test/allocator_const_void_pointer_test.cpp | 28 ++ test/allocator_construct_test.cpp | 49 ++ test/allocator_deallocate_test.cpp | 31 ++ test/allocator_destroy_test.cpp | 62 +++ test/allocator_difference_type_test.cpp | 28 ++ test/allocator_is_always_equal_test.cpp | 36 ++ test/allocator_max_size_test.cpp | 35 ++ test/allocator_pocca_test.cpp | 27 + test/allocator_pocma_test.cpp | 27 + test/allocator_pocs_test.cpp | 27 + test/allocator_pointer_test.cpp | 28 ++ test/allocator_rebind_test.cpp | 30 ++ test/allocator_size_type_test.cpp | 34 ++ test/allocator_soccc_test.cpp | 40 ++ test/allocator_value_type_test.cpp | 21 + test/allocator_void_pointer_test.cpp | 28 ++ 23 files changed, 1461 insertions(+) create mode 100644 doc/allocator_access.qbk create mode 100644 include/boost/core/allocator_access.hpp create mode 100644 test/allocator_allocate_hint_test.cpp create mode 100644 test/allocator_allocate_test.cpp create mode 100644 test/allocator_const_pointer_test.cpp create mode 100644 test/allocator_const_void_pointer_test.cpp create mode 100644 test/allocator_construct_test.cpp create mode 100644 test/allocator_deallocate_test.cpp create mode 100644 test/allocator_destroy_test.cpp create mode 100644 test/allocator_difference_type_test.cpp create mode 100644 test/allocator_is_always_equal_test.cpp create mode 100644 test/allocator_max_size_test.cpp create mode 100644 test/allocator_pocca_test.cpp create mode 100644 test/allocator_pocma_test.cpp create mode 100644 test/allocator_pocs_test.cpp create mode 100644 test/allocator_pointer_test.cpp create mode 100644 test/allocator_rebind_test.cpp create mode 100644 test/allocator_size_type_test.cpp create mode 100644 test/allocator_soccc_test.cpp create mode 100644 test/allocator_value_type_test.cpp create mode 100644 test/allocator_void_pointer_test.cpp diff --git a/doc/allocator_access.qbk b/doc/allocator_access.qbk new file mode 100644 index 0000000..69559c6 --- /dev/null +++ b/doc/allocator_access.qbk @@ -0,0 +1,244 @@ +[/ +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +] + +[section Allocator Access] + +[simplesect Authors] + +* Glen Fernandes + +[endsimplesect] + +[section Overview] + +The header `` provides the class and function +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`. + +[endsect] + +[section Examples] + +The following example shows these utilities used in the definition of +an allocator-aware container class: + +``` +template > +class container + : boost::empty_value::type> { +public: + typedef T value_type; + typedef A allocator_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename boost::allocator_pointer::type pointer; + typedef typename boost::allocator_const_pointer::type const_pointer; + // ... +}; +``` + +In C++11 or above, aliases such as `boost::allocator_pointer_t` can be used +instead of `typename boost::allocator_pointer::type`. + +[endsect] + +[section Reference] + +``` +namespace boost { + +template +struct allocator_value_type; + +template +using allocator_value_type_t = typename allocator_value_type::type; + +template +struct allocator_pointer; + +template +using allocator_pointer_t = typename allocator_pointer::type; + +template +struct allocator_const_pointer; + +template +using allocator_const_pointer_t = typename allocator_const_pointer::type; + +template +struct allocator_void_pointer; + +template +using allocator_void_pointer_t = typename allocator_void_pointer::type; + +template +struct allocator_const_void_pointer; + +template +using allocator_const_void_pointer_t = + typename allocator_const_void_pointer::type; + +template +struct allocator_difference_type; + +template +using allocator_difference_type_t = + typename allocator_difference_type::type; + +template +struct allocator_size_type; + +template +using allocator_size_type_t = typename allocator_size_type::type; + +template +struct allocator_propagate_on_container_copy_assignment; + +template +using allocator_propagate_on_container_copy_assignment_t = + typename allocator_propagate_on_container_copy_assignment::type; + +template +struct allocator_propagate_on_container_move_assignment; + +template +using allocator_propagate_on_container_move_assignment_t = + typename allocator_propagate_on_container_move_assignment::type; + +template +struct allocator_propagate_on_container_swap; + +template +using allocator_propagate_on_container_swap_t = + typename allocator_propagate_on_container_swap::type; + +template +struct allocator_is_always_equal; + +template +using allocator_is_always_equal_t = + typename allocator_is_always_equal::type; + +template +struct allocator_rebind; + +template +using allocator_rebind_t = typename allocator_rebind::type; + +template +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); + +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); + +template +void allocator_destroy(A& a, T* p); + +template +allocator_size_type_t allocator_max_size(const A& a); + +template +A allocator_select_on_container_copy_construction(const A& a); + +} // boost +``` + +[section Types] + +[variablelist +[[`template struct allocator_value_type;`] +[The member `type` is `A::value_type`.]] +[[`template struct allocator_pointer;`] +[The member `type` is `A::pointer` if valid, otherwise `A::value_type*`.]] +[[`template struct allocator_const_pointer;`] +[The member `type` is `A::const_pointer` if valid, otherwise +`pointer_traits >::rebind >`.]] +[[`template struct allocator_void_pointer;`] +[The member `type` is `A::void_pointer` if valid, otherwise +`pointer_traits >::rebind`.]] +[[`template struct allocator_const_void_pointer;`] +[The member `type` is `A::const_void_pointer` if valid, otherwise +`pointer_traits >::rebind`.]] +[[`template struct allocator_difference_type;`] +[The member `type` is `A::difference_type` if valid, otherwise +`pointer_traits >::difference_type`.]] +[[`template struct allocator_size_type;`] +[The member `type` is `A::size_type` if valid, otherwise +`std::make_unsigned_t >`.]] +[[`template struct allocator_propagate_on_container_copy_assignment;`] +[The member `type` is `A::propagate_on_container_copy_assignment` if valid, +otherwise `std::false_type`.]] +[[`template struct allocator_propagate_on_container_move_assignment;`] +[The member `type` is `A::propagate_on_container_move_assignment` if valid, +otherwise `std::false_type`.]] +[[`template struct allocator_propagate_on_container_swap;`] +[The member `type` is `A::propagate_on_container_swap` if valid, otherwise +`std::false_type`.]] +[[`template struct allocator_is_always_equal;`] +[The member `type` is `A::is_always_equal` if valid, otherwise +`std::is_empty::type`.]] +[[`template struct allocator_rebind;`] +[The member `type` is `A::rebind::other` if valid, otherwise `A` +if this `A` is `A`.]]] + +[endsect] + +[section Functions] + +[variablelist +[[`template +allocator_pointer_t allocator_allocate(A& a, allocator_size_type_t n);`] +[Calls `a.allcoate(n)`.]] +[[`template allocator_pointer_t allocator_allocate(A& a, +allocator_size_type_t n, allocator_const_void_pointer_t hint);`] +[Calls `a.allocate(n, hint)` if valid, otherwise calls `a.allocate(n)`.]] +[[`template void allocator_deallocate(A& a, allocator_pointer_t p, +allocator_size_type_t n);`] +[Calls `a.deallocate(p, n)`.]] +[[`template +void allocator_construct(A& a, T*p, Args&&... args);`] +[Calls `a.construct(p, std::forward(args)...)` if valid, otherwise calls +`::new(static_cast(p)) T(std::forward(args)...)`.]] +[[`template void allocator_destroy(A& a, T* p);`] +[Calls `a.destroy(p)` if valid, otherwise calls `p->~T()`.]] +[[`template allocator_size_type_t allocator_max_size(const A& a);`] +[Returns `a.max_size()` if valid, otehrwise returns +`std::numeric_limits >::max() / +sizeof(A::value_type)`.]] +[[`template A allocator_select_on_container_copy_construction(const +A& a);`] +[Returns `a.select_on_container_copy_construction()` if valid, otherwise +returns `a`.]]] + +[endsect] + +[endsect] + +[section Acknowledgments] + +Glen Fernandes implemented the allocator access utilities. + +[endsect] + +[endsect] diff --git a/doc/core.qbk b/doc/core.qbk index 1aac342..a51d6f9 100644 --- a/doc/core.qbk +++ b/doc/core.qbk @@ -39,6 +39,7 @@ criteria for inclusion is that the utility component be: [endsect] [include addressof.qbk] +[include allocator_access.qbk] [include alloc_construct.qbk] [include checked_delete.qbk] [include default_allocator.qbk] diff --git a/include/boost/core/allocator_access.hpp b/include/boost/core/allocator_access.hpp new file mode 100644 index 0000000..4298e5b --- /dev/null +++ b/include/boost/core/allocator_access.hpp @@ -0,0 +1,545 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP +#define BOOST_CORE_ALLOCATOR_ACCESS_HPP + +#include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include +#endif +#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 >= 1910) +#define BOOST_CORE_ALLOCATOR_DETECTION +#endif + +namespace boost { + +template +struct allocator_value_type { + typedef typename A::value_type type; +}; + +namespace detail { + +template +struct alloc_void { + typedef void type; +}; + +} /* detail */ + +template +struct allocator_pointer { + typedef typename A::value_type* type; +}; + +template +struct allocator_pointer::type> { + typedef typename A::pointer type; +}; + +template +struct allocator_const_pointer { + typedef typename pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct allocator_const_pointer::type> { + typedef typename A::const_pointer type; +}; + +template +struct allocator_void_pointer { + typedef typename pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct allocator_void_pointer::type> { + typedef typename A::void_pointer type; +}; + +template +struct allocator_const_void_pointer { + typedef typename pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct allocator_const_void_pointer::type> { + typedef typename A::const_void_pointer type; +}; + +template +struct allocator_difference_type { + typedef typename pointer_traits::type>::difference_type type; +}; + +template +struct allocator_difference_type::type> { + typedef typename A::difference_type type; +}; + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +template +struct allocator_size_type { + typedef typename std::make_unsigned::type>::type type; +}; + +template +struct allocator_size_type::type> { + typedef typename A::size_type type; +}; +#else +template +struct allocator_size_type { + typedef typename A::size_type 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; +}; + +template +struct allocator_propagate_on_container_copy_assignment::type> { + typedef typename A::propagate_on_container_copy_assignment type; +}; + +template +struct allocator_propagate_on_container_move_assignment { + typedef detail::alloc_false_type type; +}; + +template +struct allocator_propagate_on_container_move_assignment::type> { + typedef typename A::propagate_on_container_move_assignment type; +}; + +template +struct allocator_propagate_on_container_swap { + typedef detail::alloc_false_type type; +}; + +template +struct allocator_propagate_on_container_swap::type> { + typedef typename A::propagate_on_container_swap type; +}; + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +template +struct allocator_is_always_equal { + typedef typename std::is_empty::type type; +}; +#else +template +struct allocator_is_always_equal { + typedef typename detail::alloc_false_type type; +}; +#endif + +template +struct allocator_is_always_equal::type> { + typedef typename A::is_always_equal type; +}; + +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 */ + +template +struct allocator_rebind { + typedef typename detail::alloc_to::type type; +}; + +template +struct allocator_rebind::other>::type> { + typedef typename A::template rebind::other type; +}; + +template +inline typename allocator_pointer::type +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; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +template +T alloc_declval() BOOST_NOEXCEPT; +#endif + +template +struct alloc_has_allocate { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +template +struct alloc_has_allocate().allocate(alloc_declval::type>(), alloc_declval::type>()))>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::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, + 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, + typename allocator_size_type::type n) +{ + a.deallocate(p, n); +} + +namespace detail { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct alloc_types { }; +#else +template +struct alloc_types { }; +#endif + +template +struct alloc_has_construct { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct alloc_has_construct, typename + alloc_void().construct(alloc_declval(), + alloc_declval()...))>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#else +template +struct alloc_has_construct, typename + alloc_void().construct(alloc_declval(), + alloc_declval()))>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif +#endif + +} /* detail */ + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A& a, T*p, Args&&... args) +{ + a.construct(p, std::forward(args)...); +} + +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A&, T* p, Args&&... args) +{ + ::new(static_cast(p)) T(std::forward(args)...); +} +#else +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A& a, T*p, V&& v) +{ + a.construct(p, std::forward(v)); +} + +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A&, T* p, V&& v) +{ + ::new(static_cast(p)) T(std::forward(v)); +} +#endif +#else +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A& a, T*p, const V& v) +{ + a.construct(p, v); +} + +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A&, T* p, const V& v) +{ + ::new(static_cast(p)) T(v); +} + +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A& a, T*p, V& v) +{ + a.construct(p, v); +} + +template +inline typename detail::alloc_if >::value>::type +allocator_construct(A&, T* p, V& v) +{ + ::new(static_cast(p)) T(v); +} +#endif + +namespace detail { + +template +struct alloc_has_destroy { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +template +struct alloc_has_destroy(). + destroy(alloc_declval()))>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A& a, T*p) +{ + a.destroy(p); +} + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A&, T* p) +{ + p->~T(); + (void)p; +} + +namespace detail { + +template +struct alloc_has_max_size { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +template +struct alloc_has_max_size().max_size())>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_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, + typename allocator_size_type::type>::type +allocator_max_size(const A&) +{ + return std::numeric_limits::type>::max() / + sizeof(typename A::value_type); +} + +namespace detail { + +template +struct alloc_has_soccc { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +template +struct alloc_has_soccc().select_on_container_copy_construction())>::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a.select_on_container_copy_construction(); +} + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a; +} + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +using allocator_value_type_t = typename allocator_value_type::type; + +template +using allocator_pointer_t = typename allocator_pointer::type; + +template +using allocator_const_pointer_t = typename allocator_const_pointer::type; + +template +using allocator_void_pointer_t = typename allocator_void_pointer::type; + +template +using allocator_const_void_pointer_t = + typename allocator_const_void_pointer::type; + +template +using allocator_difference_type_t = + typename allocator_difference_type::type; + +template +using allocator_size_type_t = typename allocator_size_type::type; + +template +using allocator_propagate_on_container_copy_assignment_t = + typename allocator_propagate_on_container_copy_assignment::type; + +template +using allocator_propagate_on_container_move_assignment_t = + typename allocator_propagate_on_container_move_assignment::type; + +template +using allocator_propagate_on_container_swap_t = + typename allocator_propagate_on_container_swap::type; + +template +using allocator_is_always_equal_t = + typename allocator_is_always_equal::type; + +template +using allocator_rebind_t = typename allocator_rebind::type; +#endif + +} /* boost */ + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 4b915e6..54fc0c8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -161,6 +161,24 @@ run alloc_construct_cxx11_test.cpp ; run nvp_test.cpp ; +run allocator_value_type_test.cpp ; +run allocator_pointer_test.cpp ; +run allocator_const_pointer_test.cpp ; +run allocator_void_pointer_test.cpp ; +run allocator_const_void_pointer_test.cpp ; +run allocator_difference_type_test.cpp ; +run allocator_size_type_test.cpp ; +run allocator_pocca_test.cpp ; +run allocator_pocma_test.cpp ; +run allocator_pocs_test.cpp ; +run allocator_is_always_equal_test.cpp ; +run allocator_rebind_test.cpp ; +run allocator_allocate_test.cpp ; +run allocator_allocate_hint_test.cpp ; +run allocator_deallocate_test.cpp ; +run allocator_max_size_test.cpp ; +run allocator_soccc_test.cpp ; + lib lib_typeid : lib_typeid.cpp : shared:LIB_TYPEID_DYN_LINK=1 ; run test_lib_typeid.cpp lib_typeid : : : shared : test_lib_typeid_shared ; diff --git a/test/allocator_allocate_hint_test.cpp b/test/allocator_allocate_hint_test.cpp new file mode 100644 index 0000000..e5ca2f3 --- /dev/null +++ b/test/allocator_allocate_hint_test.cpp @@ -0,0 +1,61 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +struct A1 { + typedef int* pointer; + typedef int size_type; + + A1() + : value() { } + + pointer allocate(size_type n) { + value = n; + return &value; + } + + size_type value; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +struct A2 { + typedef int* pointer; + typedef int size_type; + + A2() + : value() { } + + pointer allocate(size_type n) { + value = n; + return &value; + } + + pointer allocate(size_type n, const void*) { + value = n + 1; + return &value; + } + + size_type value; +}; +#endif + +int main() +{ + { + A1 a; + BOOST_TEST_EQ(*boost::allocator_allocate(a, 1, 0), 1); + } +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) + { + A2 a; + BOOST_TEST_EQ(*boost::allocator_allocate(a, 1, 0), 2); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocator_allocate_test.cpp b/test/allocator_allocate_test.cpp new file mode 100644 index 0000000..73ee06b --- /dev/null +++ b/test/allocator_allocate_test.cpp @@ -0,0 +1,31 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +struct A { + typedef int* pointer; + typedef int size_type; + + A() + : value() { } + + pointer allocate(size_type n) { + value = n; + return &value; + } + + size_type value; +}; + +int main() +{ + A a; + BOOST_TEST_EQ(*boost::allocator_allocate(a, 5), 5); + return boost::report_errors(); +} diff --git a/test/allocator_const_pointer_test.cpp b/test/allocator_const_pointer_test.cpp new file mode 100644 index 0000000..b8fc78d --- /dev/null +++ b/test/allocator_const_pointer_test.cpp @@ -0,0 +1,30 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + typedef char value_type; + typedef int* pointer; +}; + +struct A2 { + typedef char value_type; + typedef int* pointer; + typedef const bool* const_pointer; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_const_void_pointer_test.cpp b/test/allocator_const_void_pointer_test.cpp new file mode 100644 index 0000000..ed39feb --- /dev/null +++ b/test/allocator_const_void_pointer_test.cpp @@ -0,0 +1,28 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + typedef int* pointer; +}; + +struct A2 { + typedef int* pointer; + typedef const bool* const_void_pointer; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_construct_test.cpp b/test/allocator_construct_test.cpp new file mode 100644 index 0000000..8e7be0b --- /dev/null +++ b/test/allocator_construct_test.cpp @@ -0,0 +1,49 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct S { + S(int v) + : value(v) { } + + int value; +}; + +struct A1 { }; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +struct A2 { + void construct(S* p, int v) { + new(p) S(v + 1); + } +}; +#endif + +int main() +{ + boost::default_allocator d; + { + S* p = d.allocate(1); + A1 a; + boost::allocator_construct(a, p, 1); + BOOST_TEST_EQ(p->value, 1); + d.deallocate(p, 1); + } +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) + { + S* p = d.allocate(1); + A2 a; + boost::allocator_construct(a, p, 1); + BOOST_TEST_EQ(p->value, 2); + d.deallocate(p, 1); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocator_deallocate_test.cpp b/test/allocator_deallocate_test.cpp new file mode 100644 index 0000000..83a4bda --- /dev/null +++ b/test/allocator_deallocate_test.cpp @@ -0,0 +1,31 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +struct A { + typedef int* pointer; + typedef int size_type; + + A() + : value() { } + + void deallocate(pointer, size_type n) { + value = n; + } + + size_type value; +}; + +int main() +{ + A a; + boost::allocator_deallocate(a, 0, 5); + BOOST_TEST_EQ(a.value, 5); + return boost::report_errors(); +} diff --git a/test/allocator_destroy_test.cpp b/test/allocator_destroy_test.cpp new file mode 100644 index 0000000..5ecc6c0 --- /dev/null +++ b/test/allocator_destroy_test.cpp @@ -0,0 +1,62 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct S { + static int count; + + S() { + ++count; + } + + S(const S&) { + ++count; + } + + ~S() { + --count; + } +}; + +int S::count = 0; + +struct A1 { }; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +struct A2 { + void destroy(S*) { + ++S::count; + } +}; +#endif + +int main() +{ + boost::default_allocator d; + { + S* p = d.allocate(1); + new(p) S; + A1 a; + boost::allocator_destroy(a, p); + BOOST_TEST_EQ(S::count, 0); + d.deallocate(p, 1); + } +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) + { + S* p = d.allocate(1); + new(p) S; + A2 a; + boost::allocator_destroy(a, p); + BOOST_TEST_EQ(S::count, 2); + d.deallocate(p, 1); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocator_difference_type_test.cpp b/test/allocator_difference_type_test.cpp new file mode 100644 index 0000000..d40ef46 --- /dev/null +++ b/test/allocator_difference_type_test.cpp @@ -0,0 +1,28 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + typedef char* pointer; +}; + +struct A2 { + typedef char* pointer; + typedef int difference_type; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_is_always_equal_test.cpp b/test/allocator_is_always_equal_test.cpp new file mode 100644 index 0000000..aef2f60 --- /dev/null +++ b/test/allocator_is_always_equal_test.cpp @@ -0,0 +1,36 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + int value; +}; + +struct A2 { + struct is_always_equal { + BOOST_STATIC_CONSTEXPR bool value = true; + }; + + int value; +}; + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +struct A3 { }; +#endif + +int main() +{ + BOOST_TEST_TRAIT_FALSE((boost::allocator_is_always_equal::type)); + BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal::type)); +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal::type)); +#endif + return boost::report_errors(); +} diff --git a/test/allocator_max_size_test.cpp b/test/allocator_max_size_test.cpp new file mode 100644 index 0000000..0ad609a --- /dev/null +++ b/test/allocator_max_size_test.cpp @@ -0,0 +1,35 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +struct A1 { + typedef long value_type; + typedef short size_type; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +struct A2 { + typedef long value_type; + typedef short size_type; + + size_type max_size() const { + return 1; + } +}; +#endif + +int main() +{ + BOOST_TEST_EQ(boost::allocator_max_size(A1()), + std::numeric_limits::max() / sizeof(A1::value_type)); +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) + BOOST_TEST_EQ(boost::allocator_max_size(A2()), 1); +#endif + return boost::report_errors(); +} diff --git a/test/allocator_pocca_test.cpp b/test/allocator_pocca_test.cpp new file mode 100644 index 0000000..80e9e75 --- /dev/null +++ b/test/allocator_pocca_test.cpp @@ -0,0 +1,27 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { }; + +struct A2 { + struct propagate_on_container_copy_assignment { + BOOST_STATIC_CONSTEXPR bool value = true; + }; +}; + +int main() +{ + BOOST_TEST_TRAIT_FALSE((boost:: + allocator_propagate_on_container_copy_assignment::type)); + BOOST_TEST_TRAIT_TRUE((boost:: + allocator_propagate_on_container_copy_assignment::type)); + return boost::report_errors(); +} diff --git a/test/allocator_pocma_test.cpp b/test/allocator_pocma_test.cpp new file mode 100644 index 0000000..c8d1a45 --- /dev/null +++ b/test/allocator_pocma_test.cpp @@ -0,0 +1,27 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { }; + +struct A2 { + struct propagate_on_container_move_assignment { + BOOST_STATIC_CONSTEXPR bool value = true; + }; +}; + +int main() +{ + BOOST_TEST_TRAIT_FALSE((boost:: + allocator_propagate_on_container_move_assignment::type)); + BOOST_TEST_TRAIT_TRUE((boost:: + allocator_propagate_on_container_move_assignment::type)); + return boost::report_errors(); +} diff --git a/test/allocator_pocs_test.cpp b/test/allocator_pocs_test.cpp new file mode 100644 index 0000000..3fa94c1 --- /dev/null +++ b/test/allocator_pocs_test.cpp @@ -0,0 +1,27 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { }; + +struct A2 { + struct propagate_on_container_swap { + BOOST_STATIC_CONSTEXPR bool value = true; + }; +}; + +int main() +{ + BOOST_TEST_TRAIT_FALSE((boost:: + allocator_propagate_on_container_swap::type)); + BOOST_TEST_TRAIT_TRUE((boost:: + allocator_propagate_on_container_swap::type)); + return boost::report_errors(); +} diff --git a/test/allocator_pointer_test.cpp b/test/allocator_pointer_test.cpp new file mode 100644 index 0000000..95eade2 --- /dev/null +++ b/test/allocator_pointer_test.cpp @@ -0,0 +1,28 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + typedef char value_type; +}; + +struct A2 { + typedef char value_type; + typedef int* pointer; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_rebind_test.cpp b/test/allocator_rebind_test.cpp new file mode 100644 index 0000000..5e4030f --- /dev/null +++ b/test/allocator_rebind_test.cpp @@ -0,0 +1,30 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +template +struct A1 { }; + +template +struct A2 { + template + struct rebind { + typedef A1 other; + }; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::allocator_rebind, bool>::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::allocator_rebind, bool>::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_size_type_test.cpp b/test/allocator_size_type_test.cpp new file mode 100644 index 0000000..bdc8dc5 --- /dev/null +++ b/test/allocator_size_type_test.cpp @@ -0,0 +1,34 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +struct A1 { + typedef long difference_type; +}; +#else +struct A1 { + typedef unsigned long size_type; +}; +#endif + +struct A2 { + typedef long difference_type; + typedef unsigned short size_type; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_soccc_test.cpp b/test/allocator_soccc_test.cpp new file mode 100644 index 0000000..d361549 --- /dev/null +++ b/test/allocator_soccc_test.cpp @@ -0,0 +1,40 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +struct A1 { + A1(int v) + : value(v) { } + + int value; +}; + +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) +struct A2 { + A2(int v) + : value(v) { } + + A2 select_on_container_copy_construction() const { + return A2(value + 1); + } + + int value; +}; +#endif + +int main() +{ + BOOST_TEST_EQ(1, + boost::allocator_select_on_container_copy_construction(A1(1)).value); +#if defined(BOOST_CORE_ALLOCATOR_DETECTION) + BOOST_TEST_EQ(2, + boost::allocator_select_on_container_copy_construction(A2(1)).value); +#endif + return boost::report_errors(); +} diff --git a/test/allocator_value_type_test.cpp b/test/allocator_value_type_test.cpp new file mode 100644 index 0000000..ddd5601 --- /dev/null +++ b/test/allocator_value_type_test.cpp @@ -0,0 +1,21 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A { + typedef int value_type; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +} diff --git a/test/allocator_void_pointer_test.cpp b/test/allocator_void_pointer_test.cpp new file mode 100644 index 0000000..2ec053b --- /dev/null +++ b/test/allocator_void_pointer_test.cpp @@ -0,0 +1,28 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct A1 { + typedef int* pointer; +}; + +struct A2 { + typedef int* pointer; + typedef bool* void_pointer; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::type>)); + return boost::report_errors(); +}