]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/container/include/boost/container/pmr/polymorphic_allocator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / container / include / boost / container / pmr / polymorphic_allocator.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
12#define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
13
14#if defined (_MSC_VER)
15# pragma once
16#endif
17
18#include <boost/config.hpp>
19#include <boost/move/detail/type_traits.hpp>
20#include <boost/move/utility_core.hpp>
21#include <boost/container/detail/dispatch_uses_allocator.hpp>
22#include <boost/container/new_allocator.hpp>
23#include <boost/container/pmr/memory_resource.hpp>
24#include <boost/container/pmr/global_resource.hpp>
25
26#include <cstddef>
27
28namespace boost {
29namespace container {
30namespace pmr {
31
32//! A specialization of class template `polymorphic_allocator` conforms to the Allocator requirements.
33//! Constructed with different memory resources, different instances of the same specialization of
34//! `polymorphic_allocator` can exhibit entirely different allocation behavior. This runtime
35//! polymorphism allows objects that use polymorphic_allocator to behave as if they used different
36//! allocator types at run time even though they use the same static allocator type.
37template <class T>
38class polymorphic_allocator
39{
40 public:
41 typedef T value_type;
42
43 //! <b>Effects</b>: Sets m_resource to
44 //! `get_default_resource()`.
45 polymorphic_allocator() BOOST_NOEXCEPT
46 : m_resource(::boost::container::pmr::get_default_resource())
47 {}
48
49 //! <b>Requires</b>: r is non-null.
50 //!
51 //! <b>Effects</b>: Sets m_resource to r.
52 //!
53 //! <b>Throws</b>: Nothing
54 //!
55 //! <b>Notes</b>: This constructor provides an implicit conversion from memory_resource*.
56 //! Non-standard extension: if r is null m_resource is set to get_default_resource().
57 polymorphic_allocator(memory_resource* r)
58 : m_resource(r ? r : ::boost::container::pmr::get_default_resource())
59 {}
60
61 //! <b>Effects</b>: Sets m_resource to
62 //! other.resource().
63 polymorphic_allocator(const polymorphic_allocator& other)
64 : m_resource(other.m_resource)
65 {}
66
67 //! <b>Effects</b>: Sets m_resource to
68 //! other.resource().
69 template <class U>
70 polymorphic_allocator(const polymorphic_allocator<U>& other) BOOST_NOEXCEPT
71 : m_resource(other.resource())
72 {}
73
74 //! <b>Effects</b>: Sets m_resource to
75 //! other.resource().
76 polymorphic_allocator& operator=(const polymorphic_allocator& other)
77 { m_resource = other.m_resource; return *this; }
78
79 //! <b>Returns</b>: Equivalent to
80 //! `static_cast<T*>(m_resource->allocate(n * sizeof(T), alignof(T)))`.
81 T* allocate(size_t n)
82 { return static_cast<T*>(m_resource->allocate(n*sizeof(T), ::boost::move_detail::alignment_of<T>::value)); }
83
84 //! <b>Requires</b>: p was allocated from a memory resource, x, equal to *m_resource,
85 //! using `x.allocate(n * sizeof(T), alignof(T))`.
86 //!
87 //! <b>Effects</b>: Equivalent to m_resource->deallocate(p, n * sizeof(T), alignof(T)).
88 //!
89 //! <b>Throws</b>: Nothing.
90 void deallocate(T* p, size_t n)
91 { m_resource->deallocate(p, n*sizeof(T), ::boost::move_detail::alignment_of<T>::value); }
92
93 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
94 //! <b>Requires</b>: Uses-allocator construction of T with allocator
95 //! `this->resource()` and constructor arguments `std::forward<Args>(args)...`
96 //! is well-formed. [Note: uses-allocator construction is always well formed for
97 //! types that do not use allocators. - end note]
98 //!
99 //! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
100 //! `this->resource()` and constructor arguments `std::forward<Args>(args)...`.
101 //!
102 //! <b>Throws</b>: Nothing unless the constructor for T throws.
103 template < typename U, class ...Args>
104 void construct(U* p, BOOST_FWD_REF(Args)...args)
105 {
106 new_allocator<U> na;
107 container_detail::dispatch_uses_allocator
108 (na, this->resource(), p, ::boost::forward<Args>(args)...);
109 }
110
111 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
112
113 //Disable this overload if the first argument is pair as some compilers have
114 //overload selection problems when the first parameter is a pair.
115 #define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE(N) \
116 template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
117 void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
118 {\
119 new_allocator<U> na;\
120 container_detail::dispatch_uses_allocator\
121 (na, this->resource(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
122 }\
123 //
124 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE)
125 #undef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE
126
127 #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
128
129 //! <b>Effects</b>:
130 //! p->~U().
131 template <class U>
132 void destroy(U* p)
133 { (void)p; p->~U(); }
134
135 //! <b>Returns</b>: Equivalent to
136 //! `polymorphic_allocator()`.
137 polymorphic_allocator select_on_container_copy_construction() const
138 { return polymorphic_allocator(); }
139
140 //! <b>Returns</b>:
141 //! m_resource.
142 memory_resource* resource() const
143 { return m_resource; }
144
145 private:
146 memory_resource* m_resource;
147};
148
149//! <b>Returns</b>:
150//! `*a.resource() == *b.resource()`.
151template <class T1, class T2>
152bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
153{ return *a.resource() == *b.resource(); }
154
155
156//! <b>Returns</b>:
157//! `! (a == b)`.
158template <class T1, class T2>
159bool operator!=(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
160{ return *a.resource() != *b.resource(); }
161
162} //namespace pmr {
163} //namespace container {
164} //namespace boost {
165
166#endif //BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP