File indexing completed on 2025-01-18 09:53:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
0011 #define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
0012
0013 #include <boost/config.hpp>
0014 #include <boost/core/empty_value.hpp>
0015 #include <boost/assert.hpp>
0016 #include <boost/type_traits/is_final.hpp>
0017 #include <boost/type_traits/type_with_alignment.hpp>
0018 #ifdef BOOST_NO_CXX11_ALLOCATOR
0019 # include <boost/core/allocator_traits.hpp>
0020 #endif
0021 #include <cstddef>
0022 #include <memory>
0023 #include <type_traits>
0024 #include <utility>
0025
0026 namespace boost {
0027 namespace urls {
0028 namespace detail {
0029
0030
0031
0032
0033 #ifdef BOOST_NO_CXX11_ALLOCATOR
0034 template<class Alloc>
0035 using allocator_traits =
0036 boost::allocator_traits<Alloc>;
0037 #else
0038 template<class Alloc>
0039 using allocator_traits = std::allocator_traits<Alloc>;
0040 #endif
0041
0042 template<class T, class Allocator>
0043 class over_allocator
0044 : private empty_value<Allocator>
0045 {
0046 template<class U, class OtherAlloc>
0047 friend class over_allocator;
0048
0049 std::size_t extra_;
0050
0051 public:
0052 using is_always_equal = std::false_type;
0053 using value_type = typename
0054 allocator_traits<typename allocator_traits<
0055 Allocator>::template rebind_alloc<T>>::value_type;
0056 using pointer = typename
0057 allocator_traits<typename allocator_traits<
0058 Allocator>::template rebind_alloc<T>>::pointer;
0059 using const_pointer = typename
0060 allocator_traits<typename allocator_traits<
0061 Allocator>::template rebind_alloc<T>>::const_pointer;
0062 using size_type = typename
0063 allocator_traits<typename allocator_traits<
0064 Allocator>::template rebind_alloc<T>>::size_type;
0065 using difference_type = typename
0066 allocator_traits<typename allocator_traits<
0067 Allocator>::template rebind_alloc<T>>::difference_type;
0068
0069 template<class U>
0070 struct rebind
0071 {
0072 using other = over_allocator<U, Allocator>;
0073 };
0074
0075 over_allocator(
0076 std::size_t extra,
0077 Allocator const& alloc)
0078 : empty_value<Allocator>(
0079 empty_init, alloc)
0080 , extra_(extra)
0081 {
0082 }
0083
0084 template<class U>
0085 over_allocator(over_allocator<U, Allocator> const& other) noexcept
0086 : empty_value<Allocator>(
0087 empty_init, other.get())
0088 , extra_(other.extra_)
0089 {
0090 }
0091
0092 pointer
0093 allocate(size_type n)
0094 {
0095 BOOST_ASSERT(n == 1);
0096 using U = typename boost::type_with_alignment<
0097 alignof(value_type)>::type;
0098 auto constexpr S = sizeof(U);
0099 using A = typename allocator_traits<
0100 Allocator>::template rebind_alloc<U>;
0101 A a(this->get());
0102 return reinterpret_cast<pointer>(
0103 std::allocator_traits<A>::allocate(a,
0104 (n * sizeof(value_type) + extra_ + S - 1) / S));
0105 }
0106
0107 void
0108 deallocate(pointer p, size_type n)
0109 {
0110 BOOST_ASSERT(n == 1);
0111 using U = typename boost::type_with_alignment<
0112 alignof(value_type)>::type;
0113 auto constexpr S = sizeof(U);
0114 using A = typename allocator_traits<
0115 Allocator>::template rebind_alloc<U>;
0116 A a{this->get()};
0117 std::allocator_traits<A>::deallocate(a,
0118 reinterpret_cast<U*>(p),
0119 (n * sizeof(value_type) + extra_ + S - 1) / S);
0120 }
0121
0122 #if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
0123 template<class U, class... Args>
0124 void
0125 construct(U* ptr, Args&&... args)
0126 {
0127 ::new((void*)ptr) U(std::forward<Args>(args)...);
0128 }
0129
0130 template<class U>
0131 void
0132 destroy(U* ptr)
0133 {
0134 ptr->~U();
0135 }
0136 #endif
0137
0138 template<class U>
0139 friend
0140 bool
0141 operator==(
0142 over_allocator const& lhs,
0143 over_allocator<U, Allocator> const& rhs)
0144 {
0145 return
0146 lhs.get() == rhs.get() &&
0147 lhs.extra_ == rhs.extra_;
0148 }
0149
0150 template<class U>
0151 friend
0152 bool
0153 operator!=(
0154 over_allocator const& lhs,
0155 over_allocator<U, Allocator> const& rhs)
0156 {
0157 return ! (lhs == rhs);
0158 }
0159 };
0160
0161 }
0162 }
0163 }
0164
0165 #endif