Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:34:56

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
0012 #define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
0013 
0014 #if defined (_MSC_VER)
0015 #  pragma once 
0016 #endif
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/move/detail/type_traits.hpp>
0020 #include <boost/move/utility_core.hpp>
0021 #include <boost/container/detail/dispatch_uses_allocator.hpp>
0022 #include <boost/container/new_allocator.hpp>
0023 #include <boost/container/pmr/memory_resource.hpp>
0024 #include <boost/container/pmr/global_resource.hpp>
0025 #include <boost/assert.hpp>
0026 
0027 #include <cstddef>
0028 
0029 namespace boost {
0030 namespace container {
0031 namespace pmr {
0032 
0033 //! A specialization of class template `polymorphic_allocator` conforms to the Allocator requirements.
0034 //! Constructed with different memory resources, different instances of the same specialization of
0035 //! `polymorphic_allocator` can exhibit entirely different allocation behavior. This runtime
0036 //! polymorphism allows objects that use polymorphic_allocator to behave as if they used different
0037 //! allocator types at run time even though they use the same static allocator type.
0038 template <class T>
0039 class polymorphic_allocator
0040 {
0041    public:
0042    typedef T value_type;
0043 
0044    //! <b>Effects</b>: Sets m_resource to
0045    //! `get_default_resource()`.
0046    polymorphic_allocator() BOOST_NOEXCEPT
0047       : m_resource(::boost::container::pmr::get_default_resource())
0048    {}
0049 
0050    //! <b>Requires</b>: r is non-null.
0051    //!
0052    //! <b>Effects</b>: Sets m_resource to r.
0053    //!
0054    //! <b>Throws</b>: Nothing
0055    //!
0056    //! <b>Notes</b>: This constructor provides an implicit conversion from memory_resource*.
0057    polymorphic_allocator(memory_resource* r) BOOST_NOEXCEPT
0058       : m_resource(r)
0059    {  BOOST_ASSERT(r != 0);  }
0060 
0061    //! <b>Effects</b>: Sets m_resource to
0062    //!   other.resource().
0063    polymorphic_allocator(const polymorphic_allocator& other) BOOST_NOEXCEPT
0064       : m_resource(other.m_resource)
0065    {}
0066 
0067    //! <b>Effects</b>: Sets m_resource to
0068    //!   other.resource().
0069    template <class U>
0070    polymorphic_allocator(const polymorphic_allocator<U>& other) BOOST_NOEXCEPT
0071       : m_resource(other.resource())
0072    {}
0073 
0074    //! <b>Effects</b>: Sets m_resource to
0075    //!   other.resource().
0076    polymorphic_allocator& operator=(const polymorphic_allocator& other) BOOST_NOEXCEPT
0077    {  m_resource = other.m_resource;   return *this;  }
0078 
0079    //! <b>Returns</b>: Equivalent to
0080    //!   `static_cast<T*>(m_resource->allocate(n * sizeof(T), alignof(T)))`.
0081    T* allocate(size_t n)
0082    {  return static_cast<T*>(m_resource->allocate(n*sizeof(T), ::boost::move_detail::alignment_of<T>::value));  }
0083 
0084    //! <b>Requires</b>: p was allocated from a memory resource, x, equal to *m_resource,
0085    //! using `x.allocate(n * sizeof(T), alignof(T))`.
0086    //!
0087    //! <b>Effects</b>: Equivalent to m_resource->deallocate(p, n * sizeof(T), alignof(T)).
0088    //!
0089    //! <b>Throws</b>: Nothing.
0090    void deallocate(T* p, size_t n) BOOST_NOEXCEPT
0091    {  m_resource->deallocate(p, n*sizeof(T), ::boost::move_detail::alignment_of<T>::value);  }
0092 
0093    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0094    //! <b>Requires</b>: Uses-allocator construction of T with allocator
0095    //!   `*this` and constructor arguments `std::forward<Args>(args)...`
0096    //!   is well-formed. [Note: uses-allocator construction is always well formed for
0097    //!   types that do not use allocators. - end note]
0098    //!
0099    //! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
0100    //!   `*this` and constructor arguments `std::forward<Args>(args)...`.
0101    //!
0102    //! <b>Throws</b>: Nothing unless the constructor for T throws.
0103    template < typename U, class ...Args>
0104    void construct(U* p, BOOST_FWD_REF(Args)...args)
0105    {
0106       new_allocator<U> na;
0107       dtl::dispatch_uses_allocator
0108          (na, *this, p, ::boost::forward<Args>(args)...);
0109    }
0110 
0111    #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0112 
0113    //Disable this overload if the first argument is pair as some compilers have
0114    //overload selection problems when the first parameter is a pair.
0115    #define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE(N) \
0116    template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
0117    void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
0118    {\
0119       new_allocator<U> na;\
0120       dtl::dispatch_uses_allocator\
0121          (na, *this, p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
0122    }\
0123    //
0124    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE)
0125    #undef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE
0126 
0127    #endif   //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0128 
0129    //! <b>Effects</b>:
0130    //!   p->~U().
0131    template <class U>
0132    void destroy(U* p)
0133    {  (void)p; p->~U(); }
0134 
0135    //! <b>Returns</b>: Equivalent to
0136    //!   `polymorphic_allocator()`.
0137    polymorphic_allocator select_on_container_copy_construction() const BOOST_NOEXCEPT
0138    {  return polymorphic_allocator();  }
0139 
0140    //! <b>Returns</b>:
0141    //!   m_resource.
0142    memory_resource* resource() const BOOST_NOEXCEPT
0143    {  return m_resource;  }
0144 
0145    private:
0146    memory_resource* m_resource;
0147 };
0148 
0149 //! <b>Returns</b>:
0150 //!   `*a.resource() == *b.resource()`.
0151 template <class T1, class T2>
0152 bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
0153 {  return *a.resource() == *b.resource();  }
0154 
0155 
0156 //! <b>Returns</b>:
0157 //!   `! (a == b)`.
0158 template <class T1, class T2>
0159 bool operator!=(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
0160 {  return *a.resource() != *b.resource();  }
0161 
0162 }  //namespace pmr {
0163 }  //namespace container {
0164 }  //namespace boost {
0165 
0166 #endif   //BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP