LCOV - code coverage report
Current view: top level - libs/url/src/detail/over_allocator.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 20 20
Test Date: 2024-08-20 16:05:53 Functions: 100.0 % 4 4

            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            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            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            2 :         A a(this->get());
     102              :         return reinterpret_cast<pointer>(
     103            4 :             std::allocator_traits<A>::allocate(a,
     104            4 :                 (n * sizeof(value_type) + extra_ + S - 1) / S));
     105            2 :     }
     106              : 
     107              :     void
     108            2 :     deallocate(pointer p, size_type n)
     109              :     {
     110            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            2 :         A a{this->get()};
     117            2 :         std::allocator_traits<A>::deallocate(a,
     118              :             reinterpret_cast<U*>(p),
     119            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
        

Generated by: LCOV version 2.1