Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:26

0001  //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/url
0008 //
0009 
0010 #ifndef BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
0011 #define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
0012 
0013 #include <boost/config.hpp>
0014 #include <boost/core/empty_value.hpp>
0015 #include <boost/assert.hpp>
0016 #include <boost/type_traits/is_final.hpp>
0017 #include <boost/type_traits/type_with_alignment.hpp>
0018 #ifdef BOOST_NO_CXX11_ALLOCATOR
0019 # include <boost/core/allocator_traits.hpp>
0020 #endif
0021 #include <cstddef>
0022 #include <memory>
0023 #include <type_traits>
0024 #include <utility>
0025 
0026 namespace boost {
0027 namespace urls {
0028 namespace detail {
0029 
0030 // This is a workaround for allocator_traits
0031 // implementations which falsely claim C++11
0032 // compatibility.
0033 #ifdef BOOST_NO_CXX11_ALLOCATOR
0034 template<class Alloc>
0035 using allocator_traits =
0036     boost::allocator_traits<Alloc>;
0037 #else
0038 template<class Alloc>
0039 using allocator_traits = std::allocator_traits<Alloc>;
0040 #endif
0041 
0042 template<class T, class Allocator>
0043 class over_allocator
0044     : private empty_value<Allocator>
0045 {
0046     template<class U, class OtherAlloc>
0047     friend class over_allocator;
0048 
0049     std::size_t extra_;
0050 
0051 public:
0052     using is_always_equal = std::false_type;
0053     using value_type = typename
0054         allocator_traits<typename allocator_traits<
0055             Allocator>::template rebind_alloc<T>>::value_type;
0056     using pointer = typename
0057         allocator_traits<typename allocator_traits<
0058             Allocator>::template rebind_alloc<T>>::pointer;
0059     using const_pointer = typename
0060         allocator_traits<typename allocator_traits<
0061             Allocator>::template rebind_alloc<T>>::const_pointer;
0062     using size_type = typename
0063         allocator_traits<typename allocator_traits<
0064             Allocator>::template rebind_alloc<T>>::size_type;
0065     using difference_type = typename
0066         allocator_traits<typename allocator_traits<
0067             Allocator>::template rebind_alloc<T>>::difference_type;
0068 
0069     template<class U>
0070     struct rebind
0071     {
0072         using other = over_allocator<U, Allocator>;
0073     };
0074 
0075     over_allocator(
0076         std::size_t extra,
0077         Allocator const& alloc)
0078         : empty_value<Allocator>(
0079             empty_init, alloc)
0080         , extra_(extra)
0081     {
0082     }
0083 
0084     template<class U>
0085     over_allocator(over_allocator<U, Allocator> const& other) noexcept
0086         : empty_value<Allocator>(
0087             empty_init, other.get())
0088         , extra_(other.extra_)
0089     {
0090     }
0091 
0092     pointer
0093     allocate(size_type n)
0094     {
0095         BOOST_ASSERT(n == 1);
0096         using U = typename boost::type_with_alignment<
0097             alignof(value_type)>::type;
0098         auto constexpr S = sizeof(U);
0099         using A = typename allocator_traits<
0100             Allocator>::template rebind_alloc<U>;
0101         A a(this->get());
0102         return reinterpret_cast<pointer>(
0103             std::allocator_traits<A>::allocate(a,
0104                 (n * sizeof(value_type) + extra_ + S - 1) / S));
0105     }
0106 
0107     void
0108     deallocate(pointer p, size_type n)
0109     {
0110         BOOST_ASSERT(n == 1);
0111         using U = typename boost::type_with_alignment<
0112             alignof(value_type)>::type;
0113         auto constexpr S = sizeof(U);
0114         using A = typename allocator_traits<
0115             Allocator>::template rebind_alloc<U>;
0116         A a{this->get()};
0117         std::allocator_traits<A>::deallocate(a,
0118             reinterpret_cast<U*>(p),
0119                 (n * sizeof(value_type) + extra_ + S - 1) / S);
0120     }
0121 
0122 #if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
0123     template<class U, class... Args>
0124     void
0125     construct(U* ptr, Args&&... args)
0126     {
0127         ::new((void*)ptr) U(std::forward<Args>(args)...);
0128     }
0129 
0130     template<class U>
0131     void
0132     destroy(U* ptr)
0133     {
0134         ptr->~U();
0135     }
0136 #endif
0137 
0138     template<class U>
0139     friend
0140     bool
0141     operator==(
0142         over_allocator const& lhs,
0143         over_allocator<U, Allocator> const& rhs)
0144     {
0145         return
0146             lhs.get() == rhs.get() &&
0147             lhs.extra_ == rhs.extra_;
0148     }
0149 
0150     template<class U>
0151     friend
0152     bool
0153     operator!=(
0154         over_allocator const& lhs,
0155         over_allocator<U, Allocator> const& rhs)
0156     {
0157         return ! (lhs == rhs);
0158     }
0159 };
0160 
0161 } // detail
0162 } // urls
0163 } // boost
0164 
0165 #endif