early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_DEQUE_HPP
#define BOOST_CONTAINER_PMR_DEQUE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/deque.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
using deque = boost::container::deque<T, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a deque
//! that uses a polymorphic allocator
template<class T>
struct deque_of
{
typedef boost::container::deque
< T, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_DEQUE_HPP

View File

@@ -0,0 +1,51 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_VECTOR_HPP
#define BOOST_CONTAINER_PMR_VECTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/devector.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <
typename T,
typename GrowthPolicy = growth_factor_60
>
using devector = boost::container::devector<T, GrowthPolicy, polymorphic_allocator<T> >;
#endif
//! A portable metafunction to obtain a vector
//! that uses a polymorphic allocator
template <
typename T,
typename GrowthPolicy = growth_factor_60
>
struct devector_of
{
typedef boost::container::devector
< T, GrowthPolicy, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_VECTOR_HPP

View File

@@ -0,0 +1,63 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_FLAT_MAP_HPP
#define BOOST_CONTAINER_PMR_FLAT_MAP_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/flat_map.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class Key
,class T
,class Compare = std::less<Key > >
using flat_map = boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >;
template <class Key
,class T
,class Compare = std::less<Key> >
using flat_multimap = boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >;
#endif
//! A portable metafunction to obtain a flat_map
//! that uses a polymorphic allocator
template <class Key
,class T
,class Compare = std::less<Key> >
struct flat_map_of
{
typedef boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type;
};
//! A portable metafunction to obtain a flat_multimap
//! that uses a polymorphic allocator
template <class Key
,class T
,class Compare = std::less<Key> >
struct flat_multimap_of
{
typedef boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_FLAT_MAP_HPP

View File

@@ -0,0 +1,59 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_FLAT_SET_HPP
#define BOOST_CONTAINER_PMR_FLAT_SET_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/flat_set.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class Key
,class Compare = std::less<Key> >
using flat_set = boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> >;
template <class Key
,class Compare = std::less<Key> >
using flat_multiset = boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> >;
#endif
//! A portable metafunction to obtain a flat_set
//! that uses a polymorphic allocator
template <class Key
,class Compare = std::less<Key> >
struct flat_set_of
{
typedef boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> > type;
};
//! A portable metafunction to obtain a flat_multiset
//! that uses a polymorphic allocator
template <class Key
,class Compare = std::less<Key> >
struct flat_multiset_of
{
typedef boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_FLAT_SET_HPP

View File

@@ -0,0 +1,63 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_GLOBAL_RESOURCE_HPP
#define BOOST_CONTAINER_PMR_GLOBAL_RESOURCE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/auto_link.hpp>
#include <boost/container/container_fwd.hpp>
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! <b>Returns</b>: A pointer to a static-duration object of a type derived from
//! memory_resource that can serve as a resource for allocating memory using
//! global `operator new` and global `operator delete`. The same value is returned every time this function
//! is called. For return value p and memory resource r, p->is_equal(r) returns &r == p.
BOOST_CONTAINER_DECL memory_resource* new_delete_resource() BOOST_NOEXCEPT;
//! <b>Returns</b>: A pointer to a static-duration object of a type derived from
//! memory_resource for which allocate() always throws bad_alloc and for which
//! deallocate() has no effect. The same value is returned every time this function
//! is called. For return value p and memory resource r, p->is_equal(r) returns &r == p.
BOOST_CONTAINER_DECL memory_resource* null_memory_resource() BOOST_NOEXCEPT;
//! <b>Effects</b>: If r is non-null, sets the value of the default memory resource
//! pointer to r, otherwise sets the default memory resource pointer to new_delete_resource().
//!
//! <b>Postconditions</b>: get_default_resource() == r.
//!
//! <b>Returns</b>: The previous value of the default memory resource pointer.
//!
//! <b>Remarks</b>: Calling the set_default_resource and get_default_resource functions shall
//! not incur a data race. A call to the set_default_resource function shall synchronize
//! with subsequent calls to the set_default_resource and get_default_resource functions.
BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT;
//! <b>Returns</b>: The current value of the default
//! memory resource pointer.
BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT;
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_GLOBAL_RESOURCE_HPP

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_LIST_HPP
#define BOOST_CONTAINER_PMR_LIST_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/list.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
using list = boost::container::list<T, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a list
//! that uses a polymorphic allocator
template<class T>
struct list_of
{
typedef boost::container::list
< T, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_VECTOR_HPP

View File

@@ -0,0 +1,67 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_MAP_HPP
#define BOOST_CONTAINER_PMR_MAP_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/map.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class Key
,class T
,class Compare = std::less<Key>
,class Options = void >
using map = boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>;
template <class Key
,class T
,class Compare = std::less<Key>
,class Options = void >
using multimap = boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>;
#endif
//! A portable metafunction to obtain a map
//! that uses a polymorphic allocator
template <class Key
,class T
,class Compare = std::less<Key>
,class Options = void >
struct map_of
{
typedef boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type;
};
//! A portable metafunction to obtain a multimap
//! that uses a polymorphic allocator
template <class Key
,class T
,class Compare = std::less<Key>
,class Options = void >
struct multimap_of
{
typedef boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_MAP_HPP

View File

@@ -0,0 +1,135 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_MEMORY_RESOURCE_HPP
#define BOOST_CONTAINER_PMR_MEMORY_RESOURCE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! The memory_resource class is an abstract interface to an
//! unbounded set of classes encapsulating memory resources.
class memory_resource
{
public:
// For exposition only
static BOOST_CONSTEXPR_OR_CONST std::size_t max_align =
boost::move_detail::alignment_of<boost::move_detail::max_align_t>::value;
//! <b>Effects</b>: Destroys
//! this memory_resource.
virtual ~memory_resource(){}
//! <b>Effects</b>: Equivalent to
//! `return do_allocate(bytes, alignment);`
void* allocate(std::size_t bytes, std::size_t alignment = max_align)
{
//Obtain a pointer to enough storage and initialize the lifetime
//of an array object of the given size in the address
return ::operator new(bytes, this->do_allocate(bytes, alignment), boost_container_new_t());
}
//! <b>Effects</b>: Equivalent to
//! `return do_deallocate(bytes, alignment);`
void deallocate(void* p, std::size_t bytes, std::size_t alignment = max_align)
{ return this->do_deallocate(p, bytes, alignment); }
//! <b>Effects</b>: Equivalent to
//! `return return do_is_equal(other);`
bool is_equal(const memory_resource& other) const BOOST_NOEXCEPT
{ return this->do_is_equal(other); }
#if !defined(BOOST_EMBTC)
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return &a == &b || a.is_equal(b); }
//! <b>Returns</b>:
//! !(a == b).
friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return !(a == b); }
#else
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! !(a == b).
friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT;
#endif
protected:
//! <b>Requires</b>: Alignment shall be a power of two.
//!
//! <b>Returns</b>: A derived class shall implement this function to return a pointer
//! to allocated storage with a size of at least bytes. The returned storage is
//! aligned to the specified alignment, if such alignment is supported; otherwise
//! it is aligned to max_align.
//!
//! <b>Throws</b>: A derived class implementation shall throw an appropriate exception if
//! it is unable to allocate memory with the requested size and alignment.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) = 0;
//! <b>Requires</b>: p shall have been returned from a prior call to
//! `allocate(bytes, alignment)` on a memory resource equal to *this, and the storage
//! at p shall not yet have been deallocated.
//!
//! <b>Effects</b>: A derived class shall implement this function to dispose of allocated storage.
//!
//! <b>Throws</b>: Nothing.
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) = 0;
//! <b>Returns</b>: A derived class shall implement this function to return true if memory
//! allocated from this can be deallocated from other and vice-versa; otherwise it shall
//! return false. <i>[Note: The most-derived type of other might not match the type of this.
//! For a derived class, D, a typical implementation of this function will compute
//! `dynamic_cast<const D*>(&other)` and go no further (i.e., return false)
//! if it returns nullptr. - end note]</i>.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT = 0;
};
#if defined(BOOST_EMBTC)
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
inline bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return &a == &b || a.is_equal(b); }
//! <b>Returns</b>:
//! !(a == b).
inline bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return !(a == b); }
#endif
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_MEMORY_RESOURCE_HPP

View File

@@ -0,0 +1,183 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_MONOTONIC_BUFFER_RESOURCE_HPP
#define BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/auto_link.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/detail/block_slist.hpp>
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! A monotonic_buffer_resource is a special-purpose memory resource intended for
//! very fast memory allocations in situations where memory is used to build up a
//! few objects and then is released all at once when the memory resource object
//! is destroyed. It has the following qualities:
//!
//! - A call to deallocate has no effect, thus the amount of memory consumed
//! increases monotonically until the resource is destroyed.
//!
//! - The program can supply an initial buffer, which the allocator uses to satisfy
//! memory requests.
//!
//! - When the initial buffer (if any) is exhausted, it obtains additional buffers
//! from an upstream memory resource supplied at construction. Each additional
//! buffer is larger than the previous one, following a geometric progression.
//!
//! - It is intended for access from one thread of control at a time. Specifically,
//! calls to allocate and deallocate do not synchronize with one another.
//!
//! - It owns the allocated memory and frees it on destruction, even if deallocate has
//! not been called for some of the allocated blocks.
class BOOST_CONTAINER_DECL monotonic_buffer_resource
: public memory_resource
{
block_slist m_memory_blocks;
void * m_current_buffer;
std::size_t m_current_buffer_size;
std::size_t m_next_buffer_size;
void * const m_initial_buffer;
std::size_t const m_initial_buffer_size;
/// @cond
void increase_next_buffer();
void increase_next_buffer_at_least_to(std::size_t minimum_size);
void *allocate_from_current(std::size_t aligner, std::size_t bytes);
/// @endcond
public:
//! The number of bytes that will be requested by the default in the first call
//! to the upstream allocator
//!
//! <b>Note</b>: Non-standard extension.
static const std::size_t initial_next_buffer_size = 32u*sizeof(void*);
//! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`
//!
//! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
//! to get_default_resource() otherwise.
//! Sets the internal `current_buffer` to `nullptr` and the internal `next_buffer_size` to an
//! implementation-defined size.
explicit monotonic_buffer_resource(memory_resource* upstream = 0) BOOST_NOEXCEPT;
//! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`
//! and `initial_size` shall be greater than zero.
//!
//! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
//! to get_default_resource() otherwise. Sets the internal `current_buffer` to `nullptr` and
//! `next_buffer_size` to at least `initial_size`.
explicit monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream = 0) BOOST_NOEXCEPT;
//! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`,
//! `buffer_size` shall be no larger than the number of bytes in buffer.
//!
//! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
//! to get_default_resource() otherwise. Sets the internal `current_buffer` to `buffer`,
//! and `next_buffer_size` to `buffer_size` (but not less than an implementation-defined size),
//! then increases `next_buffer_size` by an implementation-defined growth factor (which need not be integral).
monotonic_buffer_resource(void* buffer, std::size_t buffer_size, memory_resource* upstream = 0) BOOST_NOEXCEPT;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
monotonic_buffer_resource operator=(const monotonic_buffer_resource&) = delete;
#else
private:
monotonic_buffer_resource (const monotonic_buffer_resource&);
monotonic_buffer_resource operator=(const monotonic_buffer_resource&);
public:
#endif
//! <b>Effects</b>: Calls
//! `this->release()`.
~monotonic_buffer_resource() BOOST_OVERRIDE;
//! <b>Effects</b>: `upstream_resource()->deallocate()` as necessary to release all allocated memory.
//! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated
//! from this have not been deallocated from this. - end note]
void release() BOOST_NOEXCEPT;
//! <b>Returns</b>: The value of
//! the internal resource.
memory_resource* upstream_resource() const BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! The number of bytes of storage available for the specified alignment and
//! the number of bytes wasted due to the requested alignment.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t remaining_storage(std::size_t alignment, std::size_t &wasted_due_to_alignment) const BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! The number of bytes of storage available for the specified alignment.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t remaining_storage(std::size_t alignment = 1u) const BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! The address pointing to the start of the current free storage.
//!
//! <b>Note</b>: Non-standard extension.
const void *current_buffer() const BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! The number of bytes that will be requested for the next buffer once the
//! current one is exhausted.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t next_buffer_size() const BOOST_NOEXCEPT;
protected:
//! <b>Returns</b>: A pointer to allocated storage with a size of at least `bytes`. The size
//! and alignment of the allocated memory shall meet the requirements for a class derived
//! from `memory_resource`.
//!
//! <b>Effects</b>: If the unused space in the internal `current_buffer` can fit a block with the specified
//! bytes and alignment, then allocate the return block from the internal `current_buffer`; otherwise sets
//! the internal `current_buffer` to `upstream_resource()->allocate(n, m)`, where `n` is not less than
//! `max(bytes, next_buffer_size)` and `m` is not less than alignment, and increase
//! `next_buffer_size` by an implementation-defined growth factor (which need not be integral),
//! then allocate the return block from the newly-allocated internal `current_buffer`.
//!
//! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Effects</b>: None
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Remarks</b>: Memory used by this resource increases monotonically until its destruction.
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT BOOST_OVERRIDE;
//! <b>Returns</b>:
//! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP

View File

@@ -0,0 +1,165 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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 <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

View File

@@ -0,0 +1,52 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_POOL_OPTIONS_HPP
#define BOOST_CONTAINER_PMR_POOL_OPTIONS_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! The members of pool_options comprise a set of constructor options for pool resources.
//! The effect of each option on the pool resource behavior is described below:
//!
//! - `std::size_t max_blocks_per_chunk`: The maximum number of blocks that will be allocated
//! at once from the upstream memory resource to replenish a pool. If the value of
//! `max_blocks_per_chunk` is zero or is greater than an implementation-defined limit,
//! that limit is used instead. The implementation may choose to use a smaller value
//! than is specified in this field and may use different values for different pools.
//!
//! - `std::size_t largest_required_pool_block`: The largest allocation size that is required
//! to be fulfilled using the pooling mechanism. Attempts to allocate a single block
//! larger than this threshold will be allocated directly from the upstream memory
//! resource. If largest_required_pool_block is zero or is greater than an
//! implementation-defined limit, that limit is used instead. The implementation may
//! choose a pass-through threshold larger than specified in this field.
struct pool_options
{
pool_options()
: max_blocks_per_chunk(0u), largest_required_pool_block(0u)
{}
std::size_t max_blocks_per_chunk;
std::size_t largest_required_pool_block;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_POOL_OPTIONS_HPP

View File

@@ -0,0 +1,277 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_RESOURCE_ADAPTOR_HPP
#define BOOST_CONTAINER_PMR_RESOURCE_ADAPTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <boost/container/detail/std_fwd.hpp>
#include <cstring>
namespace boost {
namespace container {
namespace pmr_dtl {
template<class T>
struct max_allocator_alignment
{
static const std::size_t value = 1;
};
template<class T>
struct max_allocator_alignment< ::boost::container::new_allocator<T> >
{
static const std::size_t value = boost::move_detail::alignment_of<boost::move_detail::max_align_t>::value;
};
template<class T>
struct max_allocator_alignment< std::allocator<T> >
{
static const std::size_t value = boost::move_detail::alignment_of<boost::move_detail::max_align_t>::value;
};
} //namespace pmr_dtl
namespace pmr {
//! An instance of resource_adaptor<Allocator> is an adaptor that wraps a memory_resource interface
//! around Allocator. In order that resource_adaptor<X<T>> and resource_adaptor<X<U>> are the same
//! type for any allocator template X and types T and U, resource_adaptor<Allocator> is rendered as
//! an alias to this class template such that Allocator is rebound to a char value type in every
//! specialization of the class template. The requirements on this class template are defined below.
//! In addition to the Allocator requirements, the parameter to resource_adaptor shall meet
//! the following additional requirements:
//!
//! - `typename allocator_traits<Allocator>:: pointer` shall be identical to
//! `typename allocator_traits<Allocator>:: value_type*`.
//!
//! - `typename allocator_traits<Allocator>:: const_pointer` shall be identical to
//! `typename allocator_traits<Allocator>:: value_type const*`.
//!
//! - `typename allocator_traits<Allocator>:: void_pointer` shall be identical to `void*`.
//!
//! - `typename allocator_traits<Allocator>:: const_void_pointer` shall be identical to `void const*`.
template <class Allocator>
class resource_adaptor_imp
: public memory_resource
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
, private ::boost::intrusive::detail::ebo_functor_holder<Allocator>
#endif
{
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
Allocator m_alloc;
#else
BOOST_COPYABLE_AND_MOVABLE(resource_adaptor_imp)
typedef ::boost::intrusive::detail::ebo_functor_holder<Allocator> ebo_alloc_t;
void static_assert_if_not_char_allocator() const
{
//This class can only be used with allocators type char
BOOST_STATIC_ASSERT((boost::container::dtl::is_same<typename Allocator::value_type, char>::value));
}
#endif
public:
typedef Allocator allocator_type;
//! <b>Effects</b>: Default constructs
//! m_alloc.
resource_adaptor_imp()
{ this->static_assert_if_not_char_allocator(); }
//! <b>Effects</b>: Copy constructs
//! m_alloc.
resource_adaptor_imp(const resource_adaptor_imp &other)
: ebo_alloc_t(other.ebo_alloc_t::get())
{}
//! <b>Effects</b>: Move constructs
//! m_alloc.
resource_adaptor_imp(BOOST_RV_REF(resource_adaptor_imp) other)
: ebo_alloc_t(::boost::move(other.get()))
{}
//! <b>Effects</b>: Initializes m_alloc with
//! a2.
explicit resource_adaptor_imp(const Allocator& a2)
: ebo_alloc_t(a2)
{ this->static_assert_if_not_char_allocator(); }
//! <b>Effects</b>: Initializes m_alloc with
//! a2.
explicit resource_adaptor_imp(BOOST_RV_REF(Allocator) a2)
: ebo_alloc_t(::boost::move(a2))
{ this->static_assert_if_not_char_allocator(); }
//! <b>Effects</b>: Copy assigns
//! m_alloc.
resource_adaptor_imp& operator=(BOOST_COPY_ASSIGN_REF(resource_adaptor_imp) other)
{ this->ebo_alloc_t::get() = other.ebo_alloc_t::get(); return *this; }
//! <b>Effects</b>: Move assigns
//! m_alloc.
resource_adaptor_imp& operator=(BOOST_RV_REF(resource_adaptor_imp) other)
{ this->ebo_alloc_t::get() = ::boost::move(other.ebo_alloc_t::get()); return *this; }
//! <b>Effects</b>: Returns m_alloc.
allocator_type &get_allocator()
{ return this->ebo_alloc_t::get(); }
//! <b>Effects</b>: Returns m_alloc.
const allocator_type &get_allocator() const
{ return this->ebo_alloc_t::get(); }
protected:
//! <b>Returns</b>: Allocated memory obtained by calling m_alloc.allocate. The size and alignment
//! of the allocated memory shall meet the requirements for a class derived from memory_resource.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{
if (alignment <= priv_guaranteed_allocator_alignment())
return this->ebo_alloc_t::get().allocate(bytes);
else
return this->priv_aligned_alloc(bytes, alignment);
}
//! <b>Requires</b>: p was previously allocated using A.allocate, where A == m_alloc, and not
//! subsequently deallocated.
//!
//! <b>Effects</b>: Returns memory to the allocator using m_alloc.deallocate().
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{
if (alignment <= priv_guaranteed_allocator_alignment())
this->ebo_alloc_t::get().deallocate((char*)p, bytes);
else
this->priv_aligned_dealloc(p, bytes, alignment);
}
//! Let p be dynamic_cast<const resource_adaptor_imp*>(&other).
//!
//! <b>Returns</b>: false if p is null, otherwise the value of m_alloc == p->m_alloc.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
{
const resource_adaptor_imp* p = dynamic_cast<const resource_adaptor_imp*>(&other);
return p && p->ebo_alloc_t::get() == this->ebo_alloc_t::get();
}
private:
void * priv_aligned_alloc(std::size_t bytes, std::size_t alignment)
{
//Allocate space for requested bytes, plus alignment, plus bookeeping data
void *const p = this->ebo_alloc_t::get().allocate(bytes + priv_extra_bytes_for_overalignment(alignment));
if (0 != p) {
//Obtain the aligned address after the bookeeping data
void *const aligned_ptr = (void*)(((std::size_t)p + priv_extra_bytes_for_overalignment(alignment)) & ~(alignment - 1));
//Store bookeeping data. Use memcpy as the underlying memory might be unaligned for
//a pointer (e.g. 2 byte alignment in 32 bit, 4 byte alignment in 64 bit)
std::memcpy(priv_bookeeping_addr_from_aligned_ptr(aligned_ptr), &p, sizeof(p));
return aligned_ptr;
}
return 0;
}
void priv_aligned_dealloc(void *aligned_ptr, std::size_t bytes, std::size_t alignment)
{
//Obtain bookeeping data
void *p;
std::memcpy(&p, priv_bookeeping_addr_from_aligned_ptr(aligned_ptr), sizeof(p));
std::size_t s = bytes + priv_extra_bytes_for_overalignment(alignment);
this->ebo_alloc_t::get().deallocate((char*)p, s);
}
static BOOST_CONTAINER_FORCEINLINE void *priv_bookeeping_addr_from_aligned_ptr(void *aligned_ptr)
{
return reinterpret_cast<void*>(reinterpret_cast<std::size_t>(aligned_ptr) - sizeof(void*));
}
BOOST_CONTAINER_FORCEINLINE static std::size_t priv_extra_bytes_for_overalignment(std::size_t alignment)
{
return alignment - 1 + sizeof(void*);
}
BOOST_CONTAINER_FORCEINLINE static std::size_t priv_guaranteed_allocator_alignment()
{
return pmr_dtl::max_allocator_alignment<Allocator>::value;
}
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! `resource_adaptor<Allocator>` is rendered as an alias to resource_adaptor_imp class template
//! such that Allocator is rebound to a char value type.
template <class Allocator>
using resource_adaptor = resource_adaptor_imp
<typename allocator_traits<Allocator>::template rebind_alloc<char> >;
#else
template <class Allocator>
class resource_adaptor
: public resource_adaptor_imp
<typename allocator_traits<Allocator>::template portable_rebind_alloc<char>::type>
{
typedef resource_adaptor_imp
<typename allocator_traits<Allocator>::template portable_rebind_alloc<char>::type> base_t;
BOOST_COPYABLE_AND_MOVABLE(resource_adaptor)
public:
resource_adaptor()
: base_t()
{}
resource_adaptor(const resource_adaptor &other)
: base_t(other)
{}
resource_adaptor(BOOST_RV_REF(resource_adaptor) other)
: base_t(BOOST_MOVE_BASE(base_t, other))
{}
explicit resource_adaptor(const Allocator& a2)
: base_t(a2)
{}
explicit resource_adaptor(BOOST_RV_REF(Allocator) a2)
: base_t(::boost::move(a2))
{}
resource_adaptor& operator=(BOOST_COPY_ASSIGN_REF(resource_adaptor) other)
{ return static_cast<resource_adaptor&>(this->base_t::operator=(other)); }
resource_adaptor& operator=(BOOST_RV_REF(resource_adaptor) other)
{ return static_cast<resource_adaptor&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, other))); }
//get_allocator and protected functions are properly inherited
};
#endif
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_RESOURCE_ADAPTOR_HPP

View File

@@ -0,0 +1,63 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_SET_HPP
#define BOOST_CONTAINER_PMR_SET_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/set.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class Key
,class Compare = std::less<Key>
,class Options = void >
using set = boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options>;
template <class Key
,class Compare = std::less<Key>
,class Options = void >
using multiset = boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options>;
#endif
//! A portable metafunction to obtain a set
//! that uses a polymorphic allocator
template <class Key
,class Compare = std::less<Key>
,class Options = void >
struct set_of
{
typedef boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options> type;
};
//! A portable metafunction to obtain a multiset
//! that uses a polymorphic allocator
template <class Key
,class Compare = std::less<Key>
,class Options = void >
struct multiset_of
{
typedef boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options> type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_SET_HPP

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_SLIST_HPP
#define BOOST_CONTAINER_PMR_SLIST_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/slist.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
using slist = boost::container::slist<T, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a slist
//! that uses a polymorphic allocator
template<class T>
struct slist_of
{
typedef boost::container::slist
< T, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_VECTOR_HPP

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_SMALL_VECTOR_HPP
#define BOOST_CONTAINER_PMR_SMALL_VECTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/small_vector.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T, std::size_t N>
using small_vector = boost::container::small_vector<T, N, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a small_vector
//! that uses a polymorphic allocator
template<class T, std::size_t N>
struct small_vector_of
{
typedef boost::container::small_vector
< T, N, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_SMALL_VECTOR_HPP

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_STABLE_VECTOR_HPP
#define BOOST_CONTAINER_PMR_STABLE_VECTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/stable_vector.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
using stable_vector = boost::container::stable_vector<T, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a stable_vector
//! that uses a polymorphic allocator
template<class T>
struct stable_vector_of
{
typedef boost::container::stable_vector
< T, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_STABLE_VECTOR_HPP

View File

@@ -0,0 +1,50 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_STRING_HPP
#define BOOST_CONTAINER_PMR_STRING_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/string.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class CharT, class Traits = std::char_traits<CharT> >
using basic_string =
boost::container::basic_string<CharT, Traits, polymorphic_allocator<CharT> >;
#endif
//! A portable metafunction to obtain a basic_string
//! that uses a polymorphic allocator
template <class CharT, class Traits = std::char_traits<CharT> >
struct basic_string_of
{
typedef boost::container::basic_string
<CharT, Traits, polymorphic_allocator<CharT> > type;
};
typedef basic_string_of<char>::type string;
typedef basic_string_of<wchar_t>::type wstring;
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_STRING_HPP

View File

@@ -0,0 +1,139 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_SYNCHRONIZED_POOL_RESOURCE_HPP
#define BOOST_CONTAINER_PMR_SYNCHRONIZED_POOL_RESOURCE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/auto_link.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/detail/pool_resource.hpp>
#include <boost/container/detail/thread_mutex.hpp>
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! A synchronized_pool_resource is a general-purpose memory resources having
//! the following qualities:
//!
//! - Each resource owns the allocated memory, and frees it on destruction,
//! even if deallocate has not been called for some of the allocated blocks.
//!
//! - A pool resource consists of a collection of pools, serving
//! requests for different block sizes. Each individual pool manages a
//! collection of chunks that are in turn divided into blocks of uniform size,
//! returned via calls to do_allocate. Each call to do_allocate(size, alignment)
//! is dispatched to the pool serving the smallest blocks accommodating at
//! least size bytes.
//!
//! - When a particular pool is exhausted, allocating a block from that pool
//! results in the allocation of an additional chunk of memory from the upstream
//! allocator (supplied at construction), thus replenishing the pool. With
//! each successive replenishment, the chunk size obtained increases
//! geometrically. [ Note: By allocating memory in chunks, the pooling strategy
//! increases the chance that consecutive allocations will be close together
//! in memory. - end note ]
//!
//! - Allocation requests that exceed the largest block size of any pool are
//! fulfilled directly from the upstream allocator.
//!
//! - A pool_options struct may be passed to the pool resource constructors to
//! tune the largest block size and the maximum chunk size.
//!
//! A synchronized_pool_resource may be accessed from multiple threads without
//! external synchronization and may have thread-specific pools to reduce
//! synchronization costs.
class BOOST_CONTAINER_DECL synchronized_pool_resource
: public memory_resource
{
dtl::thread_mutex m_mut;
pool_resource m_pool_resource;
public:
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options&,memory_resource*)
synchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource()
synchronized_pool_resource() BOOST_NOEXCEPT;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(memory_resource*)
explicit synchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options&)
explicit synchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
synchronized_pool_resource(const synchronized_pool_resource&) = delete;
synchronized_pool_resource operator=(const synchronized_pool_resource&) = delete;
#else
private:
synchronized_pool_resource (const synchronized_pool_resource&);
synchronized_pool_resource operator=(const synchronized_pool_resource&);
public:
#endif
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::~unsynchronized_pool_resource()
~synchronized_pool_resource() BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::release()
void release();
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::upstream_resource()const
memory_resource* upstream_resource() const;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::options()const
pool_options options() const;
protected:
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_allocate()
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_deallocate(void*,std::size_t,std::size_t)
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_is_equal(const memory_resource&)const
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
//Non-standard observers
public:
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_count()
std::size_t pool_count() const;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_index(std::size_t)const
std::size_t pool_index(std::size_t bytes) const;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_next_blocks_per_chunk(std::size_t)const
std::size_t pool_next_blocks_per_chunk(std::size_t pool_idx) const;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_block(std::size_t)const
std::size_t pool_block(std::size_t pool_idx) const;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_cached_blocks(std::size_t)const
std::size_t pool_cached_blocks(std::size_t pool_idx) const;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_SYNCHRONIZED_POOL_RESOURCE_HPP

View File

@@ -0,0 +1,194 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_UNSYNCHRONIZED_POOL_RESOURCE_HPP
#define BOOST_CONTAINER_PMR_UNSYNCHRONIZED_POOL_RESOURCE_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/auto_link.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/detail/pool_resource.hpp>
#include <cstddef>
namespace boost {
namespace container {
namespace pmr {
//! A unsynchronized_pool_resource is a general-purpose memory resources having
//! the following qualities:
//!
//! - Each resource owns the allocated memory, and frees it on destruction,
//! even if deallocate has not been called for some of the allocated blocks.
//!
//! - A pool resource consists of a collection of pools, serving
//! requests for different block sizes. Each individual pool manages a
//! collection of chunks that are in turn divided into blocks of uniform size,
//! returned via calls to do_allocate. Each call to do_allocate(size, alignment)
//! is dispatched to the pool serving the smallest blocks accommodating at
//! least size bytes.
//!
//! - When a particular pool is exhausted, allocating a block from that pool
//! results in the allocation of an additional chunk of memory from the upstream
//! allocator (supplied at construction), thus replenishing the pool. With
//! each successive replenishment, the chunk size obtained increases
//! geometrically. [ Note: By allocating memory in chunks, the pooling strategy
//! increases the chance that consecutive allocations will be close together
//! in memory. - end note ]
//!
//! - Allocation requests that exceed the largest block size of any pool are
//! fulfilled directly from the upstream allocator.
//!
//! - A pool_options struct may be passed to the pool resource constructors to
//! tune the largest block size and the maximum chunk size.
//!
//! An unsynchronized_pool_resource class may not be accessed from multiple threads
//! simultaneously and thus avoids the cost of synchronization entirely in
//! single-threaded applications.
class BOOST_CONTAINER_DECL unsynchronized_pool_resource
: public memory_resource
{
pool_resource m_resource;
public:
//! <b>Requires</b>: `upstream` is the address of a valid memory resource.
//!
//! <b>Effects</b>: Constructs a pool resource object that will obtain memory
//! from upstream whenever the pool resource is unable to satisfy a memory
//! request from its own internal data structures. The resulting object will hold
//! a copy of upstream, but will not own the resource to which upstream points.
//! [ Note: The intention is that calls to upstream->allocate() will be
//! substantially fewer than calls to this->allocate() in most cases. - end note
//! The behavior of the pooling mechanism is tuned according to the value of
//! the opts argument.
//!
//! <b>Throws</b>: Nothing unless upstream->allocate() throws. It is unspecified if
//! or under what conditions this constructor calls upstream->allocate().
unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT;
//! <b>Effects</b>: Same as
//! `unsynchronized_pool_resource(pool_options(), get_default_resource())`.
unsynchronized_pool_resource() BOOST_NOEXCEPT;
//! <b>Effects</b>: Same as
//! `unsynchronized_pool_resource(pool_options(), upstream)`.
explicit unsynchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT;
//! <b>Effects</b>: Same as
//! `unsynchronized_pool_resource(opts, get_default_resource())`.
explicit unsynchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT;
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
unsynchronized_pool_resource operator=(const unsynchronized_pool_resource&) = delete;
#else
private:
unsynchronized_pool_resource (const unsynchronized_pool_resource&);
unsynchronized_pool_resource operator=(const unsynchronized_pool_resource&);
public:
#endif
//! <b>Effects</b>: Calls
//! `this->release()`.
~unsynchronized_pool_resource() BOOST_OVERRIDE;
//! <b>Effects</b>: Calls Calls `upstream_resource()->deallocate()` as necessary
//! to release all allocated memory. [ Note: memory is released back to
//! `upstream_resource()` even if deallocate has not been called for some
//! of the allocated blocks. - end note ]
void release();
//! <b>Returns</b>: The value of the upstream argument provided to the
//! constructor of this object.
memory_resource* upstream_resource() const;
//! <b>Returns</b>: The options that control the pooling behavior of this resource.
//! The values in the returned struct may differ from those supplied to the pool
//! resource constructor in that values of zero will be replaced with
//! implementation-defined defaults and sizes may be rounded to unspecified granularity.
pool_options options() const;
protected:
//! <b>Returns</b>: A pointer to allocated storage with a size of at least `bytes`.
//! The size and alignment of the allocated memory shall meet the requirements for
//! a class derived from `memory_resource`.
//!
//! <b>Effects</b>: If the pool selected for a block of size bytes is unable to
//! satisfy the memory request from its own internal data structures, it will call
//! `upstream_resource()->allocate()` to obtain more memory. If `bytes` is larger
//! than that which the largest pool can handle, then memory will be allocated
//! using `upstream_resource()->allocate()`.
//!
//! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Effects</b>: Return the memory at p to the pool. It is unspecified if or under
//! what circumstances this operation will result in a call to
//! `upstream_resource()->deallocate()`.
//!
//! <b>Throws</b>: Nothing.
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Returns</b>:
//! `this == dynamic_cast<const unsynchronized_pool_resource*>(&other)`.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
//Non-standard observers
public:
//! <b>Returns</b>: The number of pools that will be used in the pool resource.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t pool_count() const;
//! <b>Returns</b>: The index of the pool that will be used to serve the allocation of `bytes`.
//! Returns `pool_count()` if `bytes` is bigger
//! than `options().largest_required_pool_block` (no pool will be used to serve this).
//!
//! <b>Note</b>: Non-standard extension.
std::size_t pool_index(std::size_t bytes) const;
//! <b>Requires</b>: `pool_idx < pool_index()`
//!
//! <b>Returns</b>: The number blocks that will be allocated in the next chunk
//! from the pool specified by `pool_idx`.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t pool_next_blocks_per_chunk(std::size_t pool_idx) const;
//! <b>Requires</b>: `pool_idx < pool_index()`
//!
//! <b>Returns</b>: The number of bytes of the block that the specified `pool_idx` pool manages.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t pool_block(std::size_t pool_idx) const;
//! <b>Requires</b>: `pool_idx < pool_index()`
//!
//! <b>Returns</b>: The number of blocks that the specified `pool_idx` pool has cached
//! and will be served without calling the upstream_allocator.
//!
//! <b>Note</b>: Non-standard extension.
std::size_t pool_cached_blocks(std::size_t pool_idx) const;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_PMR_UNSYNCHRONIZED_POOL_RESOURCE_HPP

View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_VECTOR_HPP
#define BOOST_CONTAINER_PMR_VECTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/vector.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
using vector = boost::container::vector<T, polymorphic_allocator<T>>;
#endif
//! A portable metafunction to obtain a vector
//! that uses a polymorphic allocator
template<class T>
struct vector_of
{
typedef boost::container::vector
< T, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_VECTOR_HPP