GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/over_allocator.hpp
Date: 2024-03-15 19:37:09
Exec Total Coverage
Lines: 19 19 100.0%
Functions: 4 4 100.0%
Branches: 4 8 50.0%

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