整理
This commit is contained in:
166
include/boost/container/pmr/polymorphic_allocator.hpp
Normal file
166
include/boost/container/pmr/polymorphic_allocator.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/container/detail/dispatch_uses_allocator.hpp>
|
||||
#include <boost/container/new_allocator.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/pmr/global_resource.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace pmr {
|
||||
|
||||
//! A specialization of class template `polymorphic_allocator` conforms to the Allocator requirements.
|
||||
//! Constructed with different memory resources, different instances of the same specialization of
|
||||
//! `polymorphic_allocator` can exhibit entirely different allocation behavior. This runtime
|
||||
//! polymorphism allows objects that use polymorphic_allocator to behave as if they used different
|
||||
//! allocator types at run time even though they use the same static allocator type.
|
||||
template <class T>
|
||||
class polymorphic_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
//! <b>Effects</b>: Sets m_resource to
|
||||
//! `get_default_resource()`.
|
||||
polymorphic_allocator() BOOST_NOEXCEPT
|
||||
: m_resource(::boost::container::pmr::get_default_resource())
|
||||
{}
|
||||
|
||||
//! <b>Requires</b>: r is non-null.
|
||||
//!
|
||||
//! <b>Effects</b>: Sets m_resource to r.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
//! <b>Notes</b>: This constructor provides an implicit conversion from memory_resource*.
|
||||
polymorphic_allocator(memory_resource* r) BOOST_NOEXCEPT
|
||||
: m_resource(r)
|
||||
{ BOOST_ASSERT(r != 0); }
|
||||
|
||||
//! <b>Effects</b>: Sets m_resource to
|
||||
//! other.resource().
|
||||
polymorphic_allocator(const polymorphic_allocator& other) BOOST_NOEXCEPT
|
||||
: m_resource(other.m_resource)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Sets m_resource to
|
||||
//! other.resource().
|
||||
template <class U>
|
||||
polymorphic_allocator(const polymorphic_allocator<U>& other) BOOST_NOEXCEPT
|
||||
: m_resource(other.resource())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Sets m_resource to
|
||||
//! other.resource().
|
||||
polymorphic_allocator& operator=(const polymorphic_allocator& other) BOOST_NOEXCEPT
|
||||
{ m_resource = other.m_resource; return *this; }
|
||||
|
||||
//! <b>Returns</b>: Equivalent to
|
||||
//! `static_cast<T*>(m_resource->allocate(n * sizeof(T), alignof(T)))`.
|
||||
T* allocate(size_t n)
|
||||
{ return static_cast<T*>(m_resource->allocate(n*sizeof(T), ::boost::move_detail::alignment_of<T>::value)); }
|
||||
|
||||
//! <b>Requires</b>: p was allocated from a memory resource, x, equal to *m_resource,
|
||||
//! using `x.allocate(n * sizeof(T), alignof(T))`.
|
||||
//!
|
||||
//! <b>Effects</b>: Equivalent to m_resource->deallocate(p, n * sizeof(T), alignof(T)).
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
void deallocate(T* p, size_t n) BOOST_NOEXCEPT
|
||||
{ m_resource->deallocate(p, n*sizeof(T), ::boost::move_detail::alignment_of<T>::value); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Requires</b>: Uses-allocator construction of T with allocator
|
||||
//! `*this` and constructor arguments `std::forward<Args>(args)...`
|
||||
//! is well-formed. [Note: uses-allocator construction is always well formed for
|
||||
//! types that do not use allocators. - end note]
|
||||
//!
|
||||
//! <b>Effects</b>: Construct a T object at p by uses-allocator construction with allocator
|
||||
//! `*this` and constructor arguments `std::forward<Args>(args)...`.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the constructor for T throws.
|
||||
template < typename U, class ...Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)...args)
|
||||
{
|
||||
new_allocator<U> na;
|
||||
dtl::dispatch_uses_allocator
|
||||
(na, *this, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//Disable this overload if the first argument is pair as some compilers have
|
||||
//overload selection problems when the first parameter is a pair.
|
||||
#define BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE(N) \
|
||||
template < typename U BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
|
||||
void construct(U* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
|
||||
{\
|
||||
new_allocator<U> na;\
|
||||
dtl::dispatch_uses_allocator\
|
||||
(na, *this, p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE)
|
||||
#undef BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_CONSTRUCT_CODE
|
||||
|
||||
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! p->~U().
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
{ (void)p; p->~U(); }
|
||||
|
||||
//! <b>Returns</b>: Equivalent to
|
||||
//! `polymorphic_allocator()`.
|
||||
polymorphic_allocator select_on_container_copy_construction() const BOOST_NOEXCEPT
|
||||
{ return polymorphic_allocator(); }
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! m_resource.
|
||||
memory_resource* resource() const BOOST_NOEXCEPT
|
||||
{ return m_resource; }
|
||||
|
||||
private:
|
||||
memory_resource* m_resource;
|
||||
};
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `*a.resource() == *b.resource()`.
|
||||
template <class T1, class T2>
|
||||
bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
|
||||
{ return *a.resource() == *b.resource(); }
|
||||
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! `! (a == b)`.
|
||||
template <class T1, class T2>
|
||||
bool operator!=(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) BOOST_NOEXCEPT
|
||||
{ return *a.resource() != *b.resource(); }
|
||||
|
||||
} //namespace pmr {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_PMR_POLYMORPHIC_ALLOCATOR_HPP
|
||||
Reference in New Issue
Block a user