100.00% Lines (19/19) 100.00% Functions (4/4)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/url 7   // Official repository: https://github.com/boostorg/url
8   // 8   //
9   9  
10   #ifndef BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP 10   #ifndef BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
11   #define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP 11   #define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
12   12  
13   #include <boost/config.hpp> 13   #include <boost/config.hpp>
14   #include <boost/core/empty_value.hpp> 14   #include <boost/core/empty_value.hpp>
15   #include <boost/assert.hpp> 15   #include <boost/assert.hpp>
16   #include <boost/type_traits/is_final.hpp> 16   #include <boost/type_traits/is_final.hpp>
17   #include <boost/type_traits/type_with_alignment.hpp> 17   #include <boost/type_traits/type_with_alignment.hpp>
18   #ifdef BOOST_NO_CXX11_ALLOCATOR 18   #ifdef BOOST_NO_CXX11_ALLOCATOR
19   # include <boost/core/allocator_traits.hpp> 19   # include <boost/core/allocator_traits.hpp>
20   #endif 20   #endif
21   #include <cstddef> 21   #include <cstddef>
22   #include <memory> 22   #include <memory>
23   #include <type_traits> 23   #include <type_traits>
24   #include <utility> 24   #include <utility>
25   25  
26   namespace boost { 26   namespace boost {
27   namespace urls { 27   namespace urls {
28   namespace detail { 28   namespace detail {
29   29  
30   // This is a workaround for allocator_traits 30   // This is a workaround for allocator_traits
31   // implementations which falsely claim C++11 31   // implementations which falsely claim C++11
32   // compatibility. 32   // compatibility.
33   #ifdef BOOST_NO_CXX11_ALLOCATOR 33   #ifdef BOOST_NO_CXX11_ALLOCATOR
34   template<class Alloc> 34   template<class Alloc>
35   using allocator_traits = 35   using allocator_traits =
36   boost::allocator_traits<Alloc>; 36   boost::allocator_traits<Alloc>;
37   #else 37   #else
38   template<class Alloc> 38   template<class Alloc>
39   using allocator_traits = std::allocator_traits<Alloc>; 39   using allocator_traits = std::allocator_traits<Alloc>;
40   #endif 40   #endif
41   41  
42   template<class T, class Allocator> 42   template<class T, class Allocator>
43   class over_allocator 43   class over_allocator
44   : private empty_value<Allocator> 44   : private empty_value<Allocator>
45   { 45   {
46   template<class U, class OtherAlloc> 46   template<class U, class OtherAlloc>
47   friend class over_allocator; 47   friend class over_allocator;
48   48  
49   std::size_t extra_; 49   std::size_t extra_;
50   50  
51   public: 51   public:
52   using is_always_equal = std::false_type; 52   using is_always_equal = std::false_type;
53   using value_type = typename 53   using value_type = typename
54   allocator_traits<typename allocator_traits< 54   allocator_traits<typename allocator_traits<
55   Allocator>::template rebind_alloc<T>>::value_type; 55   Allocator>::template rebind_alloc<T>>::value_type;
56   using pointer = typename 56   using pointer = typename
57   allocator_traits<typename allocator_traits< 57   allocator_traits<typename allocator_traits<
58   Allocator>::template rebind_alloc<T>>::pointer; 58   Allocator>::template rebind_alloc<T>>::pointer;
59   using const_pointer = typename 59   using const_pointer = typename
60   allocator_traits<typename allocator_traits< 60   allocator_traits<typename allocator_traits<
61   Allocator>::template rebind_alloc<T>>::const_pointer; 61   Allocator>::template rebind_alloc<T>>::const_pointer;
62   using size_type = typename 62   using size_type = typename
63   allocator_traits<typename allocator_traits< 63   allocator_traits<typename allocator_traits<
64   Allocator>::template rebind_alloc<T>>::size_type; 64   Allocator>::template rebind_alloc<T>>::size_type;
65   using difference_type = typename 65   using difference_type = typename
66   allocator_traits<typename allocator_traits< 66   allocator_traits<typename allocator_traits<
67   Allocator>::template rebind_alloc<T>>::difference_type; 67   Allocator>::template rebind_alloc<T>>::difference_type;
68   68  
69   template<class U> 69   template<class U>
70   struct rebind 70   struct rebind
71   { 71   {
72   using other = over_allocator<U, Allocator>; 72   using other = over_allocator<U, Allocator>;
73   }; 73   };
74   74  
HITCBC 75   4 over_allocator( 75   4 over_allocator(
76   std::size_t extra, 76   std::size_t extra,
77   Allocator const& alloc) 77   Allocator const& alloc)
78   : empty_value<Allocator>( 78   : empty_value<Allocator>(
79   empty_init, alloc) 79   empty_init, alloc)
HITCBC 80   4 , extra_(extra) 80   4 , extra_(extra)
81   { 81   {
HITCBC 82   4 } 82   4 }
83   83  
84   template<class U> 84   template<class U>
HITCBC 85   8 over_allocator(over_allocator<U, Allocator> const& other) noexcept 85   8 over_allocator(over_allocator<U, Allocator> const& other) noexcept
86   : empty_value<Allocator>( 86   : empty_value<Allocator>(
87   empty_init, other.get()) 87   empty_init, other.get())
HITCBC 88   8 , extra_(other.extra_) 88   8 , extra_(other.extra_)
89   { 89   {
HITCBC 90   8 } 90   8 }
91   91  
92   pointer 92   pointer
HITCBC 93   4 allocate(size_type n) 93   4 allocate(size_type n)
94   { 94   {
HITCBC 95   4 BOOST_ASSERT(n == 1); 95   4 BOOST_ASSERT(n == 1);
96   using U = typename boost::type_with_alignment< 96   using U = typename boost::type_with_alignment<
97   alignof(value_type)>::type; 97   alignof(value_type)>::type;
HITCBC 98   4 auto constexpr S = sizeof(U); 98   4 auto constexpr S = sizeof(U);
99   using A = typename allocator_traits< 99   using A = typename allocator_traits<
100   Allocator>::template rebind_alloc<U>; 100   Allocator>::template rebind_alloc<U>;
HITCBC 101   4 A a(this->get()); 101   4 A a(this->get());
102   return reinterpret_cast<pointer>( 102   return reinterpret_cast<pointer>(
HITCBC 103   8 std::allocator_traits<A>::allocate(a, 103   8 std::allocator_traits<A>::allocate(a,
HITCBC 104   12 (n * sizeof(value_type) + extra_ + S - 1) / S)); 104   12 (n * sizeof(value_type) + extra_ + S - 1) / S));
105   } 105   }
106   106  
107   void 107   void
HITCBC 108   4 deallocate(pointer p, size_type n) 108   4 deallocate(pointer p, size_type n)
109   { 109   {
HITCBC 110   4 BOOST_ASSERT(n == 1); 110   4 BOOST_ASSERT(n == 1);
111   using U = typename boost::type_with_alignment< 111   using U = typename boost::type_with_alignment<
112   alignof(value_type)>::type; 112   alignof(value_type)>::type;
HITCBC 113   4 auto constexpr S = sizeof(U); 113   4 auto constexpr S = sizeof(U);
114   using A = typename allocator_traits< 114   using A = typename allocator_traits<
115   Allocator>::template rebind_alloc<U>; 115   Allocator>::template rebind_alloc<U>;
HITCBC 116   4 A a{this->get()}; 116   4 A a{this->get()};
HITCBC 117   4 std::allocator_traits<A>::deallocate(a, 117   4 std::allocator_traits<A>::deallocate(a,
118   reinterpret_cast<U*>(p), 118   reinterpret_cast<U*>(p),
HITCBC 119   4 (n * sizeof(value_type) + extra_ + S - 1) / S); 119   4 (n * sizeof(value_type) + extra_ + S - 1) / S);
HITCBC 120   4 } 120   4 }
121   121  
122   #if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000 122   #if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
123   template<class U, class... Args> 123   template<class U, class... Args>
124   void 124   void
125   construct(U* ptr, Args&&... args) 125   construct(U* ptr, Args&&... args)
126   { 126   {
127   ::new((void*)ptr) U(std::forward<Args>(args)...); 127   ::new((void*)ptr) U(std::forward<Args>(args)...);
128   } 128   }
129   129  
130   template<class U> 130   template<class U>
131   void 131   void
132   destroy(U* ptr) 132   destroy(U* ptr)
133   { 133   {
134   ptr->~U(); 134   ptr->~U();
135   } 135   }
136   #endif 136   #endif
137   137  
138   template<class U> 138   template<class U>
139   friend 139   friend
140   bool 140   bool
141   operator==( 141   operator==(
142   over_allocator const& lhs, 142   over_allocator const& lhs,
143   over_allocator<U, Allocator> const& rhs) 143   over_allocator<U, Allocator> const& rhs)
144   { 144   {
145   return 145   return
146   lhs.get() == rhs.get() && 146   lhs.get() == rhs.get() &&
147   lhs.extra_ == rhs.extra_; 147   lhs.extra_ == rhs.extra_;
148   } 148   }
149   149  
150   template<class U> 150   template<class U>
151   friend 151   friend
152   bool 152   bool
153   operator!=( 153   operator!=(
154   over_allocator const& lhs, 154   over_allocator const& lhs,
155   over_allocator<U, Allocator> const& rhs) 155   over_allocator<U, Allocator> const& rhs)
156   { 156   {
157   return ! (lhs == rhs); 157   return ! (lhs == rhs);
158   } 158   }
159   }; 159   };
160   160  
161   } // detail 161   } // detail
162   } // urls 162   } // urls
163   } // boost 163   } // boost
164   164  
165   #endif 165   #endif