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

          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           4 :         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             :     }
     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           4 :         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 1.15