Squashed 'third_party/boostorg/container/' content from commit 1ad6431
Change-Id: I7d095db3455264c03446268e5675b926bebedb0a
git-subtree-dir: third_party/boostorg/container
git-subtree-split: 1ad64316a432a7f021b4956acf88abc6aaa8a77e
diff --git a/include/boost/container/pmr/deque.hpp b/include/boost/container/pmr/deque.hpp
new file mode 100644
index 0000000..acb7da3
--- /dev/null
+++ b/include/boost/container/pmr/deque.hpp
@@ -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
diff --git a/include/boost/container/pmr/flat_map.hpp b/include/boost/container/pmr/flat_map.hpp
new file mode 100644
index 0000000..76c697b
--- /dev/null
+++ b/include/boost/container/pmr/flat_map.hpp
@@ -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
diff --git a/include/boost/container/pmr/flat_set.hpp b/include/boost/container/pmr/flat_set.hpp
new file mode 100644
index 0000000..f072c95
--- /dev/null
+++ b/include/boost/container/pmr/flat_set.hpp
@@ -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_SET_HPP
+#define BOOST_CONTAINER_PMR_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_SET_HPP
diff --git a/include/boost/container/pmr/global_resource.hpp b/include/boost/container/pmr/global_resource.hpp
new file mode 100644
index 0000000..219309b
--- /dev/null
+++ b/include/boost/container/pmr/global_resource.hpp
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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 <cstddef>
+
+namespace boost {
+namespace container {
+namespace pmr {
+
+/// @cond
+class memory_resource;
+/// @endcond
+
+//! <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
diff --git a/include/boost/container/pmr/list.hpp b/include/boost/container/pmr/list.hpp
new file mode 100644
index 0000000..f3676a3
--- /dev/null
+++ b/include/boost/container/pmr/list.hpp
@@ -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
diff --git a/include/boost/container/pmr/map.hpp b/include/boost/container/pmr/map.hpp
new file mode 100644
index 0000000..7182160
--- /dev/null
+++ b/include/boost/container/pmr/map.hpp
@@ -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
diff --git a/include/boost/container/pmr/memory_resource.hpp b/include/boost/container/pmr/memory_resource.hpp
new file mode 100644
index 0000000..72338a7
--- /dev/null
+++ b/include/boost/container/pmr/memory_resource.hpp
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/move/detail/type_traits.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)
+ { return this->do_allocate(bytes, alignment); }
+
+ //! <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); }
+
+ //! <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); }
+
+ 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;
+};
+
+} //namespace pmr {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_PMR_MEMORY_RESOURCE_HPP
diff --git a/include/boost/container/pmr/monotonic_buffer_resource.hpp b/include/boost/container/pmr/monotonic_buffer_resource.hpp
new file mode 100644
index 0000000..5a176a3
--- /dev/null
+++ b/include/boost/container/pmr/monotonic_buffer_resource.hpp
@@ -0,0 +1,182 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/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()`.
+ virtual ~monotonic_buffer_resource();
+
+ //! <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);
+
+ //! <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;
+
+ //! <b>Returns</b>:
+ //! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.
+ virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
+};
+
+} //namespace pmr {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP
diff --git a/include/boost/container/pmr/polymorphic_allocator.hpp b/include/boost/container/pmr/polymorphic_allocator.hpp
new file mode 100644
index 0000000..8c04653
--- /dev/null
+++ b/include/boost/container/pmr/polymorphic_allocator.hpp
@@ -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 <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*.
+ //! Non-standard extension: if r is null m_resource is set to get_default_resource().
+ polymorphic_allocator(memory_resource* r)
+ : m_resource(r ? r : ::boost::container::pmr::get_default_resource())
+ {}
+
+ //! <b>Effects</b>: Sets m_resource to
+ //! other.resource().
+ polymorphic_allocator(const polymorphic_allocator& other)
+ : 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)
+ { 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)
+ { 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
+ { return polymorphic_allocator(); }
+
+ //! <b>Returns</b>:
+ //! m_resource.
+ memory_resource* resource() const
+ { 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
diff --git a/include/boost/container/pmr/pool_options.hpp b/include/boost/container/pmr/pool_options.hpp
new file mode 100644
index 0000000..e9f7289
--- /dev/null
+++ b/include/boost/container/pmr/pool_options.hpp
@@ -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
diff --git a/include/boost/container/pmr/resource_adaptor.hpp b/include/boost/container/pmr/resource_adaptor.hpp
new file mode 100644
index 0000000..f5ce5c8
--- /dev/null
+++ b/include/boost/container/pmr/resource_adaptor.hpp
@@ -0,0 +1,193 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/config.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>
+
+namespace boost {
+namespace container {
+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((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(size_t bytes, size_t alignment)
+ { (void)alignment; return this->ebo_alloc_t::get().allocate(bytes); }
+
+ //! <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, size_t bytes, size_t alignment)
+ { (void)alignment; this->ebo_alloc_t::get().deallocate((char*)p, bytes); }
+
+ //! 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
+ {
+ const resource_adaptor_imp* p = dynamic_cast<const resource_adaptor_imp*>(&other);
+ return p && p->ebo_alloc_t::get() == this->ebo_alloc_t::get();
+ }
+};
+
+#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_BASE(base_t, 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 {
+
+#endif //BOOST_CONTAINER_PMR_RESOURCE_ADAPTOR_HPP
diff --git a/include/boost/container/pmr/set.hpp b/include/boost/container/pmr/set.hpp
new file mode 100644
index 0000000..3201696
--- /dev/null
+++ b/include/boost/container/pmr/set.hpp
@@ -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
diff --git a/include/boost/container/pmr/slist.hpp b/include/boost/container/pmr/slist.hpp
new file mode 100644
index 0000000..c90fd7d
--- /dev/null
+++ b/include/boost/container/pmr/slist.hpp
@@ -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
diff --git a/include/boost/container/pmr/small_vector.hpp b/include/boost/container/pmr/small_vector.hpp
new file mode 100644
index 0000000..6eef149
--- /dev/null
+++ b/include/boost/container/pmr/small_vector.hpp
@@ -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
diff --git a/include/boost/container/pmr/stable_vector.hpp b/include/boost/container/pmr/stable_vector.hpp
new file mode 100644
index 0000000..d11c426
--- /dev/null
+++ b/include/boost/container/pmr/stable_vector.hpp
@@ -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
diff --git a/include/boost/container/pmr/string.hpp b/include/boost/container/pmr/string.hpp
new file mode 100644
index 0000000..c1eba67
--- /dev/null
+++ b/include/boost/container/pmr/string.hpp
@@ -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
diff --git a/include/boost/container/pmr/synchronized_pool_resource.hpp b/include/boost/container/pmr/synchronized_pool_resource.hpp
new file mode 100644
index 0000000..516e6d2
--- /dev/null
+++ b/include/boost/container/pmr/synchronized_pool_resource.hpp
@@ -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()
+ virtual ~synchronized_pool_resource();
+
+ //! @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);
+
+ //! @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);
+
+ //! @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;
+
+ //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
diff --git a/include/boost/container/pmr/unsynchronized_pool_resource.hpp b/include/boost/container/pmr/unsynchronized_pool_resource.hpp
new file mode 100644
index 0000000..21d30b1
--- /dev/null
+++ b/include/boost/container/pmr/unsynchronized_pool_resource.hpp
@@ -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()`.
+ virtual ~unsynchronized_pool_resource();
+
+ //! <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);
+
+ //! <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);
+
+ //! <b>Returns</b>:
+ //! `this == dynamic_cast<const unsynchronized_pool_resource*>(&other)`.
+ virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
+
+ //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
diff --git a/include/boost/container/pmr/vector.hpp b/include/boost/container/pmr/vector.hpp
new file mode 100644
index 0000000..2bd9c15
--- /dev/null
+++ b/include/boost/container/pmr/vector.hpp
@@ -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