LCOV - code coverage report
Current view: top level - url/detail - over_allocator.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 19 19
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 4 4

           TLA  Line data    Source code
       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 HIT           3 :     over_allocator(
      76                 :         std::size_t extra,
      77                 :         Allocator const& alloc)
      78                 :         : empty_value<Allocator>(
      79                 :             empty_init, alloc)
      80               3 :         , extra_(extra)
      81                 :     {
      82               3 :     }
      83                 : 
      84                 :     template<class U>
      85               6 :     over_allocator(over_allocator<U, Allocator> const& other) noexcept
      86                 :         : empty_value<Allocator>(
      87                 :             empty_init, other.get())
      88               6 :         , extra_(other.extra_)
      89                 :     {
      90               6 :     }
      91                 : 
      92                 :     pointer
      93               3 :     allocate(size_type n)
      94                 :     {
      95               3 :         BOOST_ASSERT(n == 1);
      96                 :         using U = typename boost::type_with_alignment<
      97                 :             alignof(value_type)>::type;
      98               3 :         auto constexpr S = sizeof(U);
      99                 :         using A = typename allocator_traits<
     100                 :             Allocator>::template rebind_alloc<U>;
     101               3 :         A a(this->get());
     102                 :         return reinterpret_cast<pointer>(
     103               6 :             std::allocator_traits<A>::allocate(a,
     104               9 :                 (n * sizeof(value_type) + extra_ + S - 1) / S));
     105                 :     }
     106                 : 
     107                 :     void
     108               3 :     deallocate(pointer p, size_type n)
     109                 :     {
     110               3 :         BOOST_ASSERT(n == 1);
     111                 :         using U = typename boost::type_with_alignment<
     112                 :             alignof(value_type)>::type;
     113               3 :         auto constexpr S = sizeof(U);
     114                 :         using A = typename allocator_traits<
     115                 :             Allocator>::template rebind_alloc<U>;
     116               3 :         A a{this->get()};
     117               3 :         std::allocator_traits<A>::deallocate(a,
     118                 :             reinterpret_cast<U*>(p),
     119               3 :                 (n * sizeof(value_type) + extra_ + S - 1) / S);
     120               3 :     }
     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
        

Generated by: LCOV version 2.3