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/adaptive_pool.hpp b/include/boost/container/adaptive_pool.hpp
new file mode 100644
index 0000000..d1d77bc
--- /dev/null
+++ b/include/boost/container/adaptive_pool.hpp
@@ -0,0 +1,609 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_ADAPTIVE_POOL_HPP
+#define BOOST_CONTAINER_ADAPTIVE_POOL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/detail/version_type.hpp>
+#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/adaptive_node_pool.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/dlmalloc.hpp>
+#include <boost/container/detail/singleton.hpp>
+#include <boost/container/detail/placement_new.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/move/utility_core.hpp>
+#include <cstddef>
+
+
+namespace boost {
+namespace container {
+
+//!An STL node allocator that uses a modified DLMalloc as memory
+//!source.
+//!
+//!This node allocator shares a segregated storage between all instances
+//!of adaptive_pool with equal sizeof(T).
+//!
+//!NodesPerBlock is the number of nodes allocated at once when the allocator
+//!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
+//!that the adaptive node pool will hold. The rest of the totally free blocks will be
+//!deallocated to the memory manager.
+//!
+//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
+//!(memory usable for nodes / total memory allocated from the memory allocator)
+template < class T
+         , std::size_t NodesPerBlock   BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block)
+         , std::size_t MaxFreeBlocks   BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks)
+         , std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent)
+         BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version)
+         >
+class adaptive_pool
+{
+   //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
+   //!the allocator offers advanced expand in place and burst allocation capabilities.
+   public:
+   typedef unsigned int allocation_type;
+   typedef adaptive_pool
+      <T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
+         BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
+         >   self_t;
+
+   static const std::size_t nodes_per_block        = NodesPerBlock;
+   static const std::size_t max_free_blocks        = MaxFreeBlocks;
+   static const std::size_t overhead_percent       = OverheadPercent;
+   static const std::size_t real_nodes_per_block   = NodesPerBlock;
+
+   BOOST_CONTAINER_DOCIGN(BOOST_STATIC_ASSERT((Version <=2)));
+
+   public:
+   //-------
+   typedef T                                    value_type;
+   typedef T *                                  pointer;
+   typedef const T *                            const_pointer;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<T>::type     reference;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<const T>::type     const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+
+   typedef boost::container::dtl::
+      version_type<self_t, Version>             version;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef boost::container::dtl::
+      basic_multiallocation_chain<void*>              multiallocation_chain_void;
+   typedef boost::container::dtl::
+      transform_multiallocation_chain
+         <multiallocation_chain_void, T>              multiallocation_chain;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Obtains adaptive_pool from
+   //!adaptive_pool
+   template<class T2>
+   struct rebind
+   {
+      typedef adaptive_pool
+         < T2
+         , NodesPerBlock
+         , MaxFreeBlocks
+         , OverheadPercent
+         BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
+         >       other;
+   };
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   //!Not assignable from related adaptive_pool
+   template<class T2, std::size_t N2, std::size_t F2, std::size_t O2, unsigned Version2>
+   adaptive_pool& operator=
+      (const adaptive_pool<T2, N2, F2, O2, Version2>&);
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //!Default constructor
+   adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from other adaptive_pool.
+   adaptive_pool(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from related adaptive_pool.
+   template<class T2>
+   adaptive_pool
+      (const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
+            BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Destructor
+   ~adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Returns the number of elements that could be allocated.
+   //!Never throws
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return size_type(-1)/sizeof(T);   }
+
+   //!Allocate memory for an array of count elements.
+   //!Throws std::bad_alloc if there is no enough memory
+   pointer allocate(size_type count, const void * = 0)
+   {
+      if(BOOST_UNLIKELY(count > this->max_size()))
+         boost::container::throw_bad_alloc();
+
+      if(Version == 1 && count == 1){
+         typedef typename dtl::shared_adaptive_node_pool
+            <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+         typedef dtl::singleton_default<shared_pool_t> singleton_t;
+         return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
+      }
+      else{
+         return static_cast<pointer>(dlmalloc_malloc(count*sizeof(T)));
+      }
+   }
+
+   //!Deallocate allocated memory.
+   //!Never throws
+   void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      (void)count;
+      if(Version == 1 && count == 1){
+         typedef dtl::shared_adaptive_node_pool
+            <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+         typedef dtl::singleton_default<shared_pool_t> singleton_t;
+         singleton_t::instance().deallocate_node(ptr);
+      }
+      else{
+         dlmalloc_free(ptr);
+      }
+   }
+
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+      if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+
+   //!Returns maximum the number of objects the previously allocated memory
+   //!pointed by p can hold.
+   size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dlmalloc_size(p);  }
+
+   //!Allocates just one object. Memory allocated with this function
+   //!must be deallocated only with deallocate_one().
+   //!Throws bad_alloc if there is no enough memory
+   pointer allocate_one()
+   {
+      typedef dtl::shared_adaptive_node_pool
+         <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      return (pointer)singleton_t::instance().allocate_node();
+   }
+
+   //!Allocates many elements of size == 1.
+   //!Elements must be individually deallocated with deallocate_one()
+   void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
+   {
+      typedef dtl::shared_adaptive_node_pool
+         <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      singleton_t::instance().allocate_nodes(num_elements, static_cast<typename shared_pool_t::multiallocation_chain&>(chain));
+      //typename shared_pool_t::multiallocation_chain ch;
+      //singleton_t::instance().allocate_nodes(num_elements, ch);
+      //chain.incorporate_after
+         //(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
+   }
+
+   //!Deallocates memory previously allocated with allocate_one().
+   //!You should never use deallocate_one to deallocate memory allocated
+   //!with other functions different from allocate_one(). Never throws
+   void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      typedef dtl::shared_adaptive_node_pool
+         <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      singleton_t::instance().deallocate_node(p);
+   }
+
+   void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      typedef dtl::shared_adaptive_node_pool
+         <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      //typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
+      //singleton_t::instance().deallocate_nodes(ch);
+      singleton_t::instance().deallocate_nodes(chain);
+   }
+
+   //!Allocates many elements of size elem_size.
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));/*
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after(chain.before_begin()
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
+            (n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
+         boost::container::throw_bad_alloc();
+      }
+   }
+
+   //!Allocates n_elements elements, each one of size elem_sizes[i]
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));/*
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after(chain.before_begin()
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
+         (n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
+         boost::container::throw_bad_alloc();
+      }
+   }
+
+   void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {/*
+      dlmalloc_memchain ch;
+      void *beg(&*chain.begin()), *last(&*chain.last());
+      size_t size(chain.size());
+      BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
+      dlmalloc_multidealloc(&ch);*/
+      dlmalloc_multidealloc(reinterpret_cast<dlmalloc_memchain *>(&chain));
+   }
+
+   //!Deallocates all free blocks of the pool
+   static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      typedef dtl::shared_adaptive_node_pool
+         <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      singleton_t::instance().deallocate_free_blocks();
+   }
+
+   //!Swaps allocators. Does not throw. If each allocator is placed in a
+   //!different memory segment, the result is undefined.
+   friend void swap(adaptive_pool &, adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+
+   private:
+   pointer priv_allocation_command
+      (allocation_type command,   std::size_t limit_size
+      ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
+   {
+      std::size_t const preferred_size = prefer_in_recvd_out_size;
+      dlmalloc_command_ret_t ret = {0 , 0};
+      if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
+         return pointer();
+      }
+      std::size_t l_size = limit_size*sizeof(T);
+      std::size_t p_size = preferred_size*sizeof(T);
+      std::size_t r_size;
+      {
+         void* reuse_ptr_void = reuse_ptr;
+         ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+         reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
+      }
+      prefer_in_recvd_out_size = r_size/sizeof(T);
+      return (pointer)ret.first;
+   }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template < class T
+         , std::size_t NodesPerBlock   = ADP_nodes_per_block
+         , std::size_t MaxFreeBlocks   = ADP_max_free_blocks
+         , std::size_t OverheadPercent = ADP_overhead_percent
+         , unsigned Version = 2
+         >
+class private_adaptive_pool
+{
+   //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
+   //!the allocator offers advanced expand in place and burst allocation capabilities.
+   public:
+   typedef unsigned int allocation_type;
+   typedef private_adaptive_pool
+      <T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
+         BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
+         >   self_t;
+
+   static const std::size_t nodes_per_block        = NodesPerBlock;
+   static const std::size_t max_free_blocks        = MaxFreeBlocks;
+   static const std::size_t overhead_percent       = OverheadPercent;
+   static const std::size_t real_nodes_per_block   = NodesPerBlock;
+
+   BOOST_CONTAINER_DOCIGN(BOOST_STATIC_ASSERT((Version <=2)));
+
+   typedef dtl::private_adaptive_node_pool
+      <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> pool_t;
+   pool_t m_pool;
+
+   public:
+   //-------
+   typedef T                                    value_type;
+   typedef T *                                  pointer;
+   typedef const T *                            const_pointer;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<T>::type     reference;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<const T>::type            const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+
+   typedef boost::container::dtl::
+      version_type<self_t, Version>             version;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef boost::container::dtl::
+      basic_multiallocation_chain<void*>              multiallocation_chain_void;
+   typedef boost::container::dtl::
+      transform_multiallocation_chain
+         <multiallocation_chain_void, T>              multiallocation_chain;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Obtains private_adaptive_pool from
+   //!private_adaptive_pool
+   template<class T2>
+   struct rebind
+   {
+      typedef private_adaptive_pool
+         < T2
+         , NodesPerBlock
+         , MaxFreeBlocks
+         , OverheadPercent
+         BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
+         >       other;
+   };
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   //!Not assignable from related private_adaptive_pool
+   template<class T2, std::size_t N2, std::size_t F2, std::size_t O2, unsigned Version2>
+   private_adaptive_pool& operator=
+      (const private_adaptive_pool<T2, N2, F2, O2, Version2>&);
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //!Default constructor
+   private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from other private_adaptive_pool.
+   private_adaptive_pool(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from related private_adaptive_pool.
+   template<class T2>
+   private_adaptive_pool
+      (const private_adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
+            BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Destructor
+   ~private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Returns the number of elements that could be allocated.
+   //!Never throws
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return size_type(-1)/sizeof(T);   }
+
+   //!Allocate memory for an array of count elements.
+   //!Throws std::bad_alloc if there is no enough memory
+   pointer allocate(size_type count, const void * = 0)
+   {
+      if(BOOST_UNLIKELY(count > this->max_size()))
+         boost::container::throw_bad_alloc();
+
+      if(Version == 1 && count == 1){
+         return pointer(static_cast<T*>(m_pool.allocate_node()));
+      }
+      else{
+         return static_cast<pointer>(dlmalloc_malloc(count*sizeof(T)));
+      }
+   }
+
+   //!Deallocate allocated memory.
+   //!Never throws
+   void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      (void)count;
+      if(Version == 1 && count == 1){
+         m_pool.deallocate_node(ptr);
+      }
+      else{
+         dlmalloc_free(ptr);
+      }
+   }
+
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+      if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+
+   //!Returns maximum the number of objects the previously allocated memory
+   //!pointed by p can hold.
+   size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dlmalloc_size(p);  }
+
+   //!Allocates just one object. Memory allocated with this function
+   //!must be deallocated only with deallocate_one().
+   //!Throws bad_alloc if there is no enough memory
+   pointer allocate_one()
+   {
+      return (pointer)m_pool.allocate_node();
+   }
+
+   //!Allocates many elements of size == 1.
+   //!Elements must be individually deallocated with deallocate_one()
+   void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
+   {
+      m_pool.allocate_nodes(num_elements, static_cast<typename pool_t::multiallocation_chain&>(chain));
+   }
+
+   //!Deallocates memory previously allocated with allocate_one().
+   //!You should never use deallocate_one to deallocate memory allocated
+   //!with other functions different from allocate_one(). Never throws
+   void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      m_pool.deallocate_node(p);
+   }
+
+   void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      m_pool.deallocate_nodes(chain);
+   }
+
+   //!Allocates many elements of size elem_size.
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
+            (n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
+         boost::container::throw_bad_alloc();
+      }
+   }
+
+   //!Allocates n_elements elements, each one of size elem_sizes[i]
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
+         (n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
+         boost::container::throw_bad_alloc();
+      }
+   }
+
+   void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      dlmalloc_multidealloc(reinterpret_cast<dlmalloc_memchain *>(&chain));
+   }
+
+   //!Deallocates all free blocks of the pool
+   void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      m_pool.deallocate_free_blocks();
+   }
+
+   //!Swaps allocators. Does not throw. If each allocator is placed in a
+   //!different memory segment, the result is undefined.
+   friend void swap(private_adaptive_pool &, private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+
+   private:
+   pointer priv_allocation_command
+      (allocation_type command,   std::size_t limit_size
+      ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
+   {
+      std::size_t const preferred_size = prefer_in_recvd_out_size;
+      dlmalloc_command_ret_t ret = {0 , 0};
+      if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
+         return pointer();
+      }
+      std::size_t l_size = limit_size*sizeof(T);
+      std::size_t p_size = preferred_size*sizeof(T);
+      std::size_t r_size;
+      {
+         void* reuse_ptr_void = reuse_ptr;
+         ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+         reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
+      }
+      prefer_in_recvd_out_size = r_size/sizeof(T);
+      return (pointer)ret.first;
+   }
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
diff --git a/include/boost/container/allocator.hpp b/include/boost/container/allocator.hpp
new file mode 100644
index 0000000..c0deb0a
--- /dev/null
+++ b/include/boost/container/allocator.hpp
@@ -0,0 +1,368 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013. 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_ALLOCATOR_HPP
+#define BOOST_CONTAINER_ALLOCATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/detail/version_type.hpp>
+#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/dlmalloc.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/static_assert.hpp>
+#include <cstddef>
+#include <cassert>
+
+//!\file
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template<unsigned Version, unsigned int AllocationDisableMask>
+class allocator<void, Version, AllocationDisableMask>
+{
+   typedef allocator<void, Version, AllocationDisableMask>   self_t;
+   public:
+   typedef void                                 value_type;
+   typedef void *                               pointer;
+   typedef const void*                          const_pointer;
+   typedef int &                                reference;
+   typedef const int &                          const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+   typedef boost::container::dtl::
+      version_type<self_t, Version>             version;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef boost::container::dtl::
+         basic_multiallocation_chain<void*>        multiallocation_chain;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Obtains an allocator that allocates
+   //!objects of type T2
+   template<class T2>
+   struct rebind
+   {
+      typedef allocator< T2
+                       #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+                       , Version, AllocationDisableMask
+                       #endif
+                       > other;
+   };
+
+   //!Default constructor
+   //!Never throws
+   allocator()
+   {}
+
+   //!Constructor from other allocator.
+   //!Never throws
+   allocator(const allocator &)
+   {}
+
+   //!Constructor from related allocator.
+   //!Never throws
+   template<class T2>
+      allocator(const allocator<T2, Version, AllocationDisableMask> &)
+   {}
+};
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! This class is an extended STL-compatible that offers advanced allocation mechanism
+//!(in-place expansion, shrinking, burst-allocation...)
+//!
+//! This allocator is a wrapper around a modified DLmalloc.
+//! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
+//! the allocator offers advanced expand in place and burst allocation capabilities.
+//!
+//! AllocationDisableMask works only if Version is 2 and it can be an inclusive OR
+//! of allocation types the user wants to disable.
+template< class T
+        , unsigned Version BOOST_CONTAINER_DOCONLY(=2)
+        , unsigned int AllocationDisableMask BOOST_CONTAINER_DOCONLY(=0)>
+class allocator
+{
+   typedef unsigned int allocation_type;
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   //Self type
+   typedef allocator<T, Version, AllocationDisableMask>   self_t;
+
+   //Not assignable from related allocator
+   template<class T2, unsigned int Version2, unsigned int AllocationDisableMask2>
+   allocator& operator=(const allocator<T2, Version2, AllocationDisableMask2>&);
+
+   static const unsigned int ForbiddenMask =
+      BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BWD | BOOST_CONTAINER_EXPAND_FWD ;
+
+   //The mask can't disable all the allocation types
+   BOOST_STATIC_ASSERT((  (AllocationDisableMask & ForbiddenMask) != ForbiddenMask  ));
+
+   //The mask is only valid for version 2 allocators
+   BOOST_STATIC_ASSERT((  Version != 1 || (AllocationDisableMask == 0)  ));
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   typedef T                                    value_type;
+   typedef T *                                  pointer;
+   typedef const T *                            const_pointer;
+   typedef T &                                  reference;
+   typedef const T &                            const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+
+   typedef boost::container::dtl::
+      version_type<self_t, Version>                version;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef boost::container::dtl::
+         basic_multiallocation_chain<void*>        void_multiallocation_chain;
+
+   typedef boost::container::dtl::
+      transform_multiallocation_chain
+         <void_multiallocation_chain, T>           multiallocation_chain;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Obtains an allocator that allocates
+   //!objects of type T2
+   template<class T2>
+   struct rebind
+   {
+      typedef allocator<T2, Version, AllocationDisableMask> other;
+   };
+
+   //!Default constructor
+   //!Never throws
+   allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from other allocator.
+   //!Never throws
+   allocator(const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from related allocator.
+   //!Never throws
+   template<class T2>
+   allocator(const allocator<T2
+            #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+            , Version, AllocationDisableMask
+            #endif
+            > &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Allocates memory for an array of count elements.
+   //!Throws std::bad_alloc if there is no enough memory
+   //!If Version is 2, this allocated memory can only be deallocated
+   //!with deallocate() or (for Version == 2) deallocate_many()
+   pointer allocate(size_type count, const void * hint= 0)
+   {
+      (void)hint;
+      if(count > this->max_size())
+         boost::container::throw_bad_alloc();
+      void *ret = dlmalloc_malloc(count*sizeof(T));
+      if(!ret)
+         boost::container::throw_bad_alloc();
+      return static_cast<pointer>(ret);
+   }
+
+   //!Deallocates previously allocated memory.
+   //!Never throws
+   void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
+   {  dlmalloc_free(ptr);  }
+
+   //!Returns the maximum number of elements that could be allocated.
+   //!Never throws
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return size_type(-1)/sizeof(T);   }
+
+   //!Swaps two allocators, does nothing
+   //!because this allocator is stateless
+   friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+
+   //!An advanced function that offers in-place expansion shrink to fit and new allocation
+   //!capabilities. Memory allocated with this function can only be deallocated with deallocate()
+   //!or deallocate_many().
+   //!This function is available only with Version == 2
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      const allocation_type mask(AllocationDisableMask);
+      command &= ~mask;
+      pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+      if(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+
+   //!Returns maximum the number of objects the previously allocated memory
+   //!pointed by p can hold.
+   //!Memory must not have been allocated with
+   //!allocate_one or allocate_individual.
+   //!This function is available only with Version == 2
+   size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      return dlmalloc_size(p);
+   }
+
+   //!Allocates just one object. Memory allocated with this function
+   //!must be deallocated only with deallocate_one().
+   //!Throws bad_alloc if there is no enough memory
+   //!This function is available only with Version == 2
+   pointer allocate_one()
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      return this->allocate(1);
+   }
+
+   //!Allocates many elements of size == 1.
+   //!Elements must be individually deallocated with deallocate_one()
+   //!This function is available only with Version == 2
+   void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      this->allocate_many(1, num_elements, chain);
+   }
+
+   //!Deallocates memory previously allocated with allocate_one().
+   //!You should never use deallocate_one to deallocate memory allocated
+   //!with other functions different from allocate_one() or allocate_individual.
+   //Never throws
+   void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      return this->deallocate(p, 1);
+   }
+
+   //!Deallocates memory allocated with allocate_one() or allocate_individual().
+   //!This function is available only with Version == 2
+   void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      return this->deallocate_many(chain);
+   }
+
+   //!Allocates many elements of size elem_size.
+   //!Elements must be individually deallocated with deallocate()
+   //!This function is available only with Version == 2
+   void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));/*
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
+      if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after(chain.before_begin()
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
+      if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
+         boost::container::throw_bad_alloc();
+      }
+   }
+
+   //!Allocates n_elements elements, each one of size elem_sizes[i]
+   //!Elements must be individually deallocated with deallocate()
+   //!This function is available only with Version == 2
+   void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
+      if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after(chain.before_begin()
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
+                             ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );
+      /*
+      if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
+         boost::container::throw_bad_alloc();
+      }*/
+   }
+
+   //!Deallocates several elements allocated by
+   //!allocate_many(), allocate(), or allocation_command().
+   //!This function is available only with Version == 2
+   void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      dlmalloc_memchain ch;
+      void *beg(&*chain.begin()), *last(&*chain.last());
+      size_t size(chain.size());
+      BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
+      dlmalloc_multidealloc(&ch);
+      //dlmalloc_multidealloc(reinterpret_cast<dlmalloc_memchain *>(&chain));
+   }
+
+   private:
+
+   pointer priv_allocation_command
+      (allocation_type command,    std::size_t limit_size
+      ,size_type &prefer_in_recvd_out_size
+      ,pointer &reuse_ptr)
+   {
+      std::size_t const preferred_size = prefer_in_recvd_out_size;
+      dlmalloc_command_ret_t ret = {0 , 0};
+      if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
+         return pointer();
+      }
+      std::size_t l_size = limit_size*sizeof(T);
+      std::size_t p_size = preferred_size*sizeof(T);
+      std::size_t r_size;
+      {
+         void* reuse_ptr_void = reuse_ptr;
+         ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+         reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
+      }
+      prefer_in_recvd_out_size = r_size/sizeof(T);
+      return (pointer)ret.first;
+   }
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_ALLOCATOR_HPP
+
diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp
new file mode 100644
index 0000000..af32f18
--- /dev/null
+++ b/include/boost/container/allocator_traits.hpp
@@ -0,0 +1,477 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2013. 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_ALLOCATOR_ALLOCATOR_TRAITS_HPP
+#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>  //is_empty
+#include <boost/container/detail/placement_new.hpp>
+#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
+#include <boost/container/detail/std_fwd.hpp>
+#endif
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+// other boost
+#include <boost/static_assert.hpp>
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template<class Allocator>
+class small_vector_allocator;
+
+namespace allocator_traits_detail {
+
+BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size)
+BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction)
+
+}  //namespace allocator_traits_detail {
+
+namespace dtl {
+
+//workaround needed for C++03 compilers with no construct()
+//supporting rvalue references
+template<class Allocator>
+struct is_std_allocator
+{  static const bool value = false; };
+
+template<class T>
+struct is_std_allocator< std::allocator<T> >
+{  static const bool value = true; };
+
+template<class T>
+struct is_std_allocator< small_vector_allocator< std::allocator<T> > >
+{  static const bool value = true; };
+
+template<class Allocator>
+struct is_not_std_allocator
+{  static const bool value = !is_std_allocator<Allocator>::value; };
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable)
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! The class template allocator_traits supplies a uniform interface to all allocator types.
+//! This class is a C++03-compatible implementation of std::allocator_traits
+template <typename Allocator>
+struct allocator_traits
+{
+   //allocator_type
+   typedef Allocator allocator_type;
+   //value_type
+   typedef typename allocator_type::value_type value_type;
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //! Allocator::pointer if such a type exists; otherwise, value_type*
+      //!
+      typedef unspecified pointer;
+      //! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
+      //!
+      typedef see_documentation const_pointer;
+      //! Non-standard extension
+      //! Allocator::reference if such a type exists; otherwise, value_type&
+      typedef see_documentation reference;
+      //! Non-standard extension
+      //! Allocator::const_reference if such a type exists ; otherwise, const value_type&
+      typedef see_documentation const_reference;
+      //! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
+      //!
+      typedef see_documentation void_pointer;
+      //! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
+      //!
+      typedef see_documentation const_void_pointer;
+      //! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
+      //!
+      typedef see_documentation difference_type;
+      //! Allocator::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
+      //!
+      typedef see_documentation size_type;
+      //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
+      //! with an internal constant static boolean member <code>value</code> == false.
+      typedef see_documentation propagate_on_container_copy_assignment;
+      //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type
+      //! with an internal constant static boolean member <code>value</code> == false.
+      typedef see_documentation propagate_on_container_move_assignment;
+      //! Allocator::propagate_on_container_swap if such a type exists, otherwise a type
+      //! with an internal constant static boolean member <code>value</code> == false.
+      typedef see_documentation propagate_on_container_swap;
+      //! Allocator::is_always_equal if such a type exists, otherwise a type
+      //! with an internal constant static boolean member <code>value</code> == is_empty<Allocator>::value
+      typedef see_documentation is_always_equal;
+      //! Allocator::is_partially_propagable if such a type exists, otherwise a type
+      //! with an internal constant static boolean member <code>value</code> == false
+      //! <b>Note</b>: Non-standard extension used to implement `small_vector_allocator`.
+      typedef see_documentation is_partially_propagable;
+      //! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
+      //! if Allocator is a class template instantiation of the form Allocator<U, Args>, where Args is zero or
+      //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
+      //!
+      //! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
+      //! deduced by previously detailed rules.
+      template <class T> using rebind_alloc = see_documentation;
+
+      //! In C++03 compilers <code>rebind_traits</code> is a struct derived from
+      //! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
+      //! the allocator deduced by rules explained in <code>rebind_alloc</code>.
+      template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
+
+      //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
+      //! <code>type</code> is an allocator related to Allocator deduced deduced by rules explained in <code>rebind_alloc</code>.
+      template <class T>
+      struct portable_rebind_alloc
+      {  typedef see_documentation type;  };
+   #else
+      //pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         pointer, value_type*)
+            pointer;
+      //const_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator,
+         const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<const value_type>)
+               const_pointer;
+      //reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         reference, typename dtl::unvoid_ref<value_type>::type)
+            reference;
+      //const_reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         const_reference, typename dtl::unvoid_ref<const value_type>::type)
+               const_reference;
+      //void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator,
+         void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<void>)
+               void_pointer;
+      //const_void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator,
+         const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<const void>)
+               const_void_pointer;
+      //difference_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         difference_type, std::ptrdiff_t)
+            difference_type;
+      //size_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         size_type, std::size_t)
+            size_type;
+      //propagate_on_container_copy_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         propagate_on_container_copy_assignment, dtl::false_type)
+            propagate_on_container_copy_assignment;
+      //propagate_on_container_move_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         propagate_on_container_move_assignment, dtl::false_type)
+            propagate_on_container_move_assignment;
+      //propagate_on_container_swap
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         propagate_on_container_swap, dtl::false_type)
+            propagate_on_container_swap;
+      //is_always_equal
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         is_always_equal, dtl::is_empty<Allocator>)
+            is_always_equal;
+      //is_partially_propagable
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator,
+         is_partially_propagable, dtl::false_type)
+            is_partially_propagable;
+
+      //rebind_alloc & rebind_traits
+      #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+         //C++11
+         template <typename T> using rebind_alloc  = typename boost::intrusive::pointer_rebind<Allocator, T>::type;
+         template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
+      #else    // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+         //Some workaround for C++03 or C++11 compilers with no template aliases
+         template <typename T>
+         struct rebind_alloc : boost::intrusive::pointer_rebind<Allocator,T>::type
+         {
+            typedef typename boost::intrusive::pointer_rebind<Allocator,T>::type Base;
+            #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+               template <typename... Args>
+               rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {}
+            #else    // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+               #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
+               BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+               explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\
+               //
+               BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC)
+               #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
+            #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+         };
+
+         template <typename T>
+         struct rebind_traits
+            : allocator_traits<typename boost::intrusive::pointer_rebind<Allocator, T>::type>
+         {};
+      #endif   // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+
+      //portable_rebind_alloc
+      template <class T>
+      struct portable_rebind_alloc
+      {  typedef typename boost::intrusive::pointer_rebind<Allocator, T>::type type;  };
+   #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Returns</b>: <code>a.allocate(n)</code>
+   //!
+   BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n)
+   {  return a.allocate(n);  }
+
+   //! <b>Returns</b>: <code>a.deallocate(p, n)</code>
+   //!
+   //! <b>Throws</b>: Nothing
+   BOOST_CONTAINER_FORCEINLINE static void deallocate(Allocator &a, pointer p, size_type n)
+   {  a.deallocate(p, n);  }
+
+   //! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
+   //! otherwise, invokes <code>a.allocate(n)</code>
+   BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n, const_void_pointer p)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_allocate
+            <Allocator, const size_type, const const_void_pointer>::value;
+      dtl::bool_<value> flag;
+      return allocator_traits::priv_allocate(flag, a, n, p);
+   }
+
+   //! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
+   //! otherwise, invokes <code>p->~T()</code>.
+   template<class T>
+   BOOST_CONTAINER_FORCEINLINE static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      typedef T* destroy_pointer;
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_destroy
+            <Allocator, const destroy_pointer>::value;
+      dtl::bool_<value> flag;
+      allocator_traits::priv_destroy(flag, a, p);
+   }
+
+   //! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
+   //! <code>numeric_limits<size_type>::max()</code>.
+   BOOST_CONTAINER_FORCEINLINE static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value;
+      dtl::bool_<value> flag;
+      return allocator_traits::priv_max_size(flag, a);
+   }
+
+   //! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
+   //! otherwise, a.
+   BOOST_CONTAINER_FORCEINLINE static BOOST_CONTAINER_DOC1ST(Allocator,
+      typename dtl::if_c
+         < allocator_traits_detail::has_select_on_container_copy_construction<Allocator BOOST_MOVE_I Allocator (Allocator::*)() const>::value
+         BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type)
+   select_on_container_copy_construction(const Allocator &a)
+   {
+      const bool value = allocator_traits_detail::has_select_on_container_copy_construction
+         <Allocator, Allocator (Allocator::*)() const>::value;
+      dtl::bool_<value> flag;
+      return allocator_traits::priv_select_on_container_copy_construction(flag, a);
+   }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
+      //! otherwise, invokes <code>`placement new` (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
+      template <class T, class ...Args>
+      BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
+      {
+         static const bool value = ::boost::move_detail::and_
+            < dtl::is_not_std_allocator<Allocator>
+            , boost::container::dtl::has_member_function_callable_with_construct
+                  < Allocator, T*, Args... >
+            >::value;
+         dtl::bool_<value> flag;
+         allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
+      }
+   #endif
+
+   //! <b>Returns</b>: <code>a.storage_is_unpropagable(p)</code> if is_partially_propagable::value is true; otherwise,
+   //! <code>false</code>.
+   BOOST_CONTAINER_FORCEINLINE static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      dtl::bool_<is_partially_propagable::value> flag;
+      return allocator_traits::priv_storage_is_unpropagable(flag, a, p);
+   }
+
+   //! <b>Returns</b>: <code>true</code> if <code>is_always_equal::value == true</code>, otherwise,
+   //! <code>a == b</code>.
+   BOOST_CONTAINER_FORCEINLINE static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      dtl::bool_<is_always_equal::value> flag;
+      return allocator_traits::priv_equal(flag, a, b);
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   private:
+   BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::true_type, Allocator &a, size_type n, const_void_pointer p)
+   {  return a.allocate(n, p);  }
+
+   BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::false_type, Allocator &a, size_type n, const_void_pointer)
+   {  return a.allocate(n);  }
+
+   template<class T>
+   BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  a.destroy(p);  }
+
+   template<class T>
+   BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  p->~T(); (void)p;  }
+
+   BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return a.max_size();  }
+
+   BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return size_type(-1)/sizeof(value_type);  }
+
+   BOOST_CONTAINER_FORCEINLINE static Allocator priv_select_on_container_copy_construction(dtl::true_type, const Allocator &a)
+   {  return a.select_on_container_copy_construction();  }
+
+   BOOST_CONTAINER_FORCEINLINE static const Allocator &priv_select_on_container_copy_construction(dtl::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return a;  }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+      template<class T, class ...Args>
+      BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
+      {  a.construct( p, ::boost::forward<Args>(args)...);  }
+
+      template<class T, class ...Args>
+      BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
+      {  ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
+   #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+      public:
+
+      #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
+      template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+      BOOST_CONTAINER_FORCEINLINE static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+      {\
+         static const bool value = ::boost::move_detail::and_ \
+            < dtl::is_not_std_allocator<Allocator> \
+            , boost::container::dtl::has_member_function_callable_with_construct \
+                  < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \
+            >::value; \
+         dtl::bool_<value> flag;\
+         (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      }\
+      //
+      BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
+      #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
+
+      private:
+      /////////////////////////////////
+      // priv_construct
+      /////////////////////////////////
+      #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
+      template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+      BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+      {  a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N );  }\
+      \
+      template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+      BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+      {  ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\
+      //
+      BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
+      #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
+
+   #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template<class T>
+   BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
+   {  ::new((void*)p, boost_container_new_t()) T; }
+
+   BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::true_type, const Allocator &a, pointer p)
+   {  return a.storage_is_unpropagable(p);  }
+
+   BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::false_type, const Allocator &, pointer)
+   {  return false;  }
+
+   BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::true_type,  const Allocator &, const Allocator &)
+   {  return true;  }
+
+   BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::false_type, const Allocator &a, const Allocator &b)
+   {  return a == b;  }
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
diff --git a/include/boost/container/container_fwd.hpp b/include/boost/container/container_fwd.hpp
new file mode 100644
index 0000000..e4fe6f8
--- /dev/null
+++ b/include/boost/container/container_fwd.hpp
@@ -0,0 +1,296 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2014. 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_CONTAINER_FWD_HPP
+#define BOOST_CONTAINER_CONTAINER_FWD_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//! \file
+//! This header file forward declares the following containers:
+//!   - boost::container::vector
+//!   - boost::container::stable_vector
+//!   - boost::container::static_vector
+//!   - boost::container::small_vector
+//!   - boost::container::slist
+//!   - boost::container::list
+//!   - boost::container::set
+//!   - boost::container::multiset
+//!   - boost::container::map
+//!   - boost::container::multimap
+//!   - boost::container::flat_set
+//!   - boost::container::flat_multiset
+//!   - boost::container::flat_map
+//!   - boost::container::flat_multimap
+//!   - boost::container::basic_string
+//!   - boost::container::string
+//!   - boost::container::wstring
+//!
+//! Forward declares the following allocators:
+//!   - boost::container::allocator
+//!   - boost::container::node_allocator
+//!   - boost::container::adaptive_pool
+//!
+//! Forward declares the following polymorphic resource classes:
+//!   - boost::container::pmr::memory_resource
+//!   - boost::container::pmr::polymorphic_allocator
+//!   - boost::container::pmr::monotonic_buffer_resource
+//!   - boost::container::pmr::pool_options
+//!   - boost::container::pmr::unsynchronized_pool_resource
+//!   - boost::container::pmr::synchronized_pool_resource
+//!
+//! And finally it defines the following types
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//Std forward declarations
+#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
+   #include <boost/container/detail/std_fwd.hpp>
+#endif
+
+namespace boost{
+namespace intrusive{
+namespace detail{
+   //Create namespace to avoid compilation errors
+}}}
+
+namespace boost{ namespace container{ namespace dtl{
+   namespace bi = boost::intrusive;
+   namespace bid = boost::intrusive::detail;
+}}}
+
+namespace boost{ namespace container{ namespace pmr{
+   namespace bi = boost::intrusive;
+   namespace bid = boost::intrusive::detail;
+}}}
+
+#include <cstddef>
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//////////////////////////////////////////////////////////////////////////////
+//                             Containers
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template<class T>
+class new_allocator;
+
+template <class T
+         ,class Allocator = new_allocator<T>
+         ,class Options = void>
+class vector;
+
+template <class T
+         ,class Allocator = new_allocator<T> >
+class stable_vector;
+
+template <class T, std::size_t Capacity>
+class static_vector;
+
+template < class T, std::size_t N
+         , class Allocator= new_allocator<T> >
+class small_vector;
+
+template <class T
+         ,class Allocator = new_allocator<T> >
+class deque;
+
+template <class T
+         ,class Allocator = new_allocator<T> >
+class list;
+
+template <class T
+         ,class Allocator = new_allocator<T> >
+class slist;
+
+template <class Key
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<Key>
+         ,class Options = void>
+class set;
+
+template <class Key
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<Key>
+         ,class Options = void >
+class multiset;
+
+template <class Key
+         ,class T
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<std::pair<const Key, T> >
+         ,class Options = void >
+class map;
+
+template <class Key
+         ,class T
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<std::pair<const Key, T> >
+         ,class Options = void >
+class multimap;
+
+template <class Key
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<Key> >
+class flat_set;
+
+template <class Key
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<Key> >
+class flat_multiset;
+
+template <class Key
+         ,class T
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<std::pair<Key, T> > >
+class flat_map;
+
+template <class Key
+         ,class T
+         ,class Compare  = std::less<Key>
+         ,class Allocator = new_allocator<std::pair<Key, T> > >
+class flat_multimap;
+
+template <class CharT
+         ,class Traits = std::char_traits<CharT>
+         ,class Allocator  = new_allocator<CharT> >
+class basic_string;
+
+typedef basic_string
+   <char
+   ,std::char_traits<char>
+   ,new_allocator<char> >
+string;
+
+typedef basic_string
+   <wchar_t
+   ,std::char_traits<wchar_t>
+   ,new_allocator<wchar_t> >
+wstring;
+
+static const std::size_t ADP_nodes_per_block    = 256u;
+static const std::size_t ADP_max_free_blocks    = 2u;
+static const std::size_t ADP_overhead_percent   = 1u;
+static const std::size_t ADP_only_alignment     = 0u;
+
+template < class T
+         , std::size_t NodesPerBlock   = ADP_nodes_per_block
+         , std::size_t MaxFreeBlocks   = ADP_max_free_blocks
+         , std::size_t OverheadPercent = ADP_overhead_percent
+         , unsigned Version = 2
+         >
+class adaptive_pool;
+
+template < class T
+         , unsigned Version = 2
+         , unsigned int AllocationDisableMask = 0>
+class allocator;
+
+static const std::size_t NodeAlloc_nodes_per_block = 256u;
+
+template
+   < class T
+   , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
+   , std::size_t Version = 2>
+class node_allocator;
+
+namespace pmr {
+
+class memory_resource;
+
+template<class T>
+class polymorphic_allocator;
+
+class monotonic_buffer_resource;
+
+struct pool_options;
+
+template <class Allocator>
+class resource_adaptor_imp;
+
+class unsynchronized_pool_resource;
+
+class synchronized_pool_resource;
+
+}  //namespace pmr {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! Type used to tag that the input range is
+//! guaranteed to be ordered
+struct ordered_range_t
+{};
+
+//! Value used to tag that the input range is
+//! guaranteed to be ordered
+static const ordered_range_t ordered_range = ordered_range_t();
+
+//! Type used to tag that the input range is
+//! guaranteed to be ordered and unique
+struct ordered_unique_range_t
+   : public ordered_range_t
+{};
+
+//! Value used to tag that the input range is
+//! guaranteed to be ordered and unique
+static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
+
+//! Type used to tag that the inserted values
+//! should be default initialized
+struct default_init_t
+{};
+
+//! Value used to tag that the inserted values
+//! should be default initialized
+static const default_init_t default_init = default_init_t();
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! Type used to tag that the inserted values
+//! should be value initialized
+struct value_init_t
+{};
+
+//! Value used to tag that the inserted values
+//! should be value initialized
+static const value_init_t value_init = value_init_t();
+
+namespace container_detail_really_deep_namespace {
+
+//Otherwise, gcc issues a warning of previously defined
+//anonymous_instance and unique_instance
+struct dummy
+{
+   dummy()
+   {
+      (void)ordered_range;
+      (void)ordered_unique_range;
+      (void)default_init;
+   }
+};
+
+}  //detail_really_deep_namespace {
+
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}}  //namespace boost { namespace container {
+
+#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp
new file mode 100644
index 0000000..f04ba49
--- /dev/null
+++ b/include/boost/container/deque.hpp
@@ -0,0 +1,2270 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_DEQUE_HPP
+#define BOOST_CONTAINER_DEQUE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/copy_move_algo.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/min_max.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#include <cstddef>
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Allocator>
+class deque;
+
+template <class T>
+struct deque_value_traits
+{
+   typedef T value_type;
+   static const bool trivial_dctr = dtl::is_trivially_destructible<value_type>::value;
+   static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
+};
+
+// Note: this function is simply a kludge to work around several compilers'
+//  bugs in handling constant expressions.
+template<class T>
+struct deque_buf_size
+{
+   static const std::size_t min_size = 512u;
+   static const std::size_t sizeof_t = sizeof(T);
+   static const std::size_t value    = sizeof_t < min_size ? (min_size/sizeof_t) : std::size_t(1);
+};
+
+namespace dtl {
+
+// Class invariants:
+//  For any nonsingular iterator i:
+//    i.node is the address of an element in the map array.  The
+//      contents of i.node is a pointer to the beginning of a node.
+//    i.first == //(i.node)
+//    i.last  == i.first + node_size
+//    i.cur is a pointer in the range [i.first, i.last).  NOTE:
+//      the implication of this is that i.cur is always a dereferenceable
+//      pointer, even if i is a past-the-end iterator.
+//  Start and Finish are always nonsingular iterators.  NOTE: this means
+//    that an empty deque must have one node, and that a deque
+//    with N elements, where N is the buffer size, must have two nodes.
+//  For every node other than start.node and finish.node, every element
+//    in the node is an initialized object.  If start.node == finish.node,
+//    then [start.cur, finish.cur) are initialized objects, and
+//    the elements outside that range are uninitialized storage.  Otherwise,
+//    [start.cur, start.last) and [finish.first, finish.cur) are initialized
+//    objects, and [start.first, start.cur) and [finish.cur, finish.last)
+//    are uninitialized storage.
+//  [map, map + map_size) is a valid, non-empty range.
+//  [start.node, finish.node] is a valid range contained within
+//    [map, map + map_size).
+//  A pointer in the range [map, map + map_size) points to an allocated node
+//    if and only if the pointer is in the range [start.node, finish.node].
+template<class Pointer, bool IsConst>
+class deque_iterator
+{
+   public:
+   typedef std::random_access_iterator_tag                                          iterator_category;
+   typedef typename boost::intrusive::pointer_traits<Pointer>::element_type         value_type;
+   typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type      difference_type;
+   typedef typename if_c
+      < IsConst
+      , typename boost::intrusive::pointer_traits<Pointer>::template
+                                 rebind_pointer<const value_type>::type
+      , Pointer
+      >::type                                                                       pointer;
+   typedef typename if_c
+      < IsConst
+      , const value_type&
+      , value_type&
+      >::type                                                                       reference;
+
+   static std::size_t s_buffer_size()
+      { return deque_buf_size<value_type>::value; }
+
+   typedef Pointer                                                                  val_alloc_ptr;
+   typedef typename boost::intrusive::pointer_traits<Pointer>::
+      template rebind_pointer<Pointer>::type                                        index_pointer;
+
+   Pointer m_cur;
+   Pointer m_first;
+   Pointer m_last;
+   index_pointer  m_node;
+
+   public:
+
+   Pointer get_cur()          const  {  return m_cur;  }
+   Pointer get_first()        const  {  return m_first;  }
+   Pointer get_last()         const  {  return m_last;  }
+   index_pointer get_node()   const  {  return m_node;  }
+
+   deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_cur(x), m_first(*y), m_last(*y + s_buffer_size()), m_node(y)
+   {}
+
+   deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
+      : m_cur(), m_first(), m_last(), m_node()  //Value initialization to achieve "null iterators" (N3644)
+   {}
+
+   deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
+   {}
+
+   deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_cur(cur), m_first(first), m_last(last), m_node(node)
+   {}
+
+   deque_iterator<Pointer, false> unconst() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
+   }
+
+   reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return *this->m_cur; }
+
+   pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->m_cur; }
+
+   difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if(!this->m_cur && !x.m_cur){
+         return 0;
+      }
+      return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
+         (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
+   }
+
+   deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      ++this->m_cur;
+      if (this->m_cur == this->m_last) {
+         this->priv_set_node(this->m_node + 1);
+         this->m_cur = this->m_first;
+      }
+      return *this;
+   }
+
+   deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      deque_iterator tmp(*this);
+      ++*this;
+      return tmp;
+   }
+
+   deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if (this->m_cur == this->m_first) {
+         this->priv_set_node(this->m_node - 1);
+         this->m_cur = this->m_last;
+      }
+      --this->m_cur;
+      return *this;
+   }
+
+   deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      deque_iterator tmp(*this);
+      --*this;
+      return tmp;
+   }
+
+   deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      difference_type offset = n + (this->m_cur - this->m_first);
+      if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
+         this->m_cur += n;
+      else {
+         difference_type node_offset =
+         offset > 0 ? offset / difference_type(this->s_buffer_size())
+                     : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
+         this->priv_set_node(this->m_node + node_offset);
+         this->m_cur = this->m_first +
+         (offset - node_offset * difference_type(this->s_buffer_size()));
+      }
+      return *this;
+   }
+
+   deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+      {  deque_iterator tmp(*this); return tmp += n;  }
+
+   deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
+      { return *this += -n; }
+
+   deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+      {  deque_iterator tmp(*this); return tmp -= n;  }
+
+   reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+      { return *(*this + n); }
+
+   friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      { return l.m_cur == r.m_cur; }
+
+   friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      { return l.m_cur != r.m_cur; }
+
+   friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      {  return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node);  }
+
+   friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      { return r < l; }
+
+   friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      { return !(r < l); }
+
+   friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+      { return !(l < r); }
+
+   void priv_set_node(index_pointer new_node) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      this->m_node = new_node;
+      this->m_first = *new_node;
+      this->m_last = this->m_first + this->s_buffer_size();
+   }
+
+   friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
+      {  return x += n;  }
+};
+
+}  //namespace dtl {
+
+// Deque base class.  It has two purposes.  First, its constructor
+//  and destructor allocate (but don't initialize) storage.  This makes
+//  exception safety easier.
+template <class Allocator>
+class deque_base
+{
+   BOOST_COPYABLE_AND_MOVABLE(deque_base)
+   public:
+   typedef allocator_traits<Allocator>                            val_alloc_traits_type;
+   typedef typename val_alloc_traits_type::value_type             val_alloc_val;
+   typedef typename val_alloc_traits_type::pointer                val_alloc_ptr;
+   typedef typename val_alloc_traits_type::const_pointer          val_alloc_cptr;
+   typedef typename val_alloc_traits_type::reference              val_alloc_ref;
+   typedef typename val_alloc_traits_type::const_reference        val_alloc_cref;
+   typedef typename val_alloc_traits_type::difference_type        val_alloc_diff;
+   typedef typename val_alloc_traits_type::size_type              val_alloc_size;
+   typedef typename val_alloc_traits_type::template
+      portable_rebind_alloc<val_alloc_ptr>::type                  ptr_alloc_t;
+   typedef allocator_traits<ptr_alloc_t>                          ptr_alloc_traits_type;
+   typedef typename ptr_alloc_traits_type::value_type             ptr_alloc_val;
+   typedef typename ptr_alloc_traits_type::pointer                ptr_alloc_ptr;
+   typedef typename ptr_alloc_traits_type::const_pointer          ptr_alloc_cptr;
+   typedef typename ptr_alloc_traits_type::reference              ptr_alloc_ref;
+   typedef typename ptr_alloc_traits_type::const_reference        ptr_alloc_cref;
+   typedef Allocator                                                      allocator_type;
+   typedef allocator_type                                         stored_allocator_type;
+   typedef val_alloc_size                                         size_type;
+
+   protected:
+
+   typedef deque_value_traits<val_alloc_val>             traits_t;
+   typedef ptr_alloc_t                                   map_allocator_type;
+
+   static size_type s_buffer_size() BOOST_NOEXCEPT_OR_NOTHROW
+      { return deque_buf_size<val_alloc_val>::value; }
+
+   val_alloc_ptr priv_allocate_node()
+      {  return this->alloc().allocate(s_buffer_size());  }
+
+   void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
+      {  this->alloc().deallocate(p, s_buffer_size());  }
+
+   ptr_alloc_ptr priv_allocate_map(size_type n)
+      { return this->ptr_alloc().allocate(n); }
+
+   void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+      { this->ptr_alloc().deallocate(p, n); }
+
+   typedef dtl::deque_iterator<val_alloc_ptr, false> iterator;
+   typedef dtl::deque_iterator<val_alloc_ptr, true > const_iterator;
+
+   deque_base(size_type num_elements, const allocator_type& a)
+      :  members_(a)
+   { this->priv_initialize_map(num_elements); }
+
+   explicit deque_base(const allocator_type& a)
+      :  members_(a)
+   {}
+
+   deque_base()
+      :  members_()
+   {}
+
+   explicit deque_base(BOOST_RV_REF(deque_base) x)
+      :  members_( boost::move(x.ptr_alloc())
+                 , boost::move(x.alloc()) )
+   {}
+
+   ~deque_base()
+   {
+      if (this->members_.m_map) {
+         this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+      }
+   }
+
+   private:
+   deque_base(const deque_base&);
+
+   protected:
+
+   void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start);
+      ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish);
+      ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map);
+      ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size);
+   }
+
+   void priv_initialize_map(size_type num_elements)
+   {
+//      if(num_elements){
+         size_type num_nodes = num_elements / s_buffer_size() + 1;
+
+         this->members_.m_map_size = dtl::max_value((size_type) InitialMapSize, num_nodes + 2);
+         this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
+
+         ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
+         ptr_alloc_ptr nfinish = nstart + num_nodes;
+
+         BOOST_TRY {
+            this->priv_create_nodes(nstart, nfinish);
+         }
+         BOOST_CATCH(...){
+            this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+            this->members_.m_map = 0;
+            this->members_.m_map_size = 0;
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+
+         this->members_.m_start.priv_set_node(nstart);
+         this->members_.m_finish.priv_set_node(nfinish - 1);
+         this->members_.m_start.m_cur = this->members_.m_start.m_first;
+         this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
+                        num_elements % s_buffer_size();
+//      }
+   }
+
+   void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+   {
+      ptr_alloc_ptr cur = nstart;
+      BOOST_TRY {
+         for (; cur < nfinish; ++cur)
+            *cur = this->priv_allocate_node();
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_nodes(nstart, cur);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
+         this->priv_deallocate_node(*n);
+   }
+
+   void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if (this->members_.m_map) {
+         this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+         this->members_.m_map = 0;
+         this->members_.m_map_size = 0;
+         this->members_.m_start = iterator();
+         this->members_.m_finish = this->members_.m_start;
+      }
+   }
+
+   enum { InitialMapSize = 8 };
+
+   protected:
+   struct members_holder
+      :  public ptr_alloc_t
+      ,  public allocator_type
+   {
+      members_holder()
+         :  map_allocator_type(), allocator_type()
+         ,  m_map(0), m_map_size(0)
+         ,  m_start(), m_finish(m_start)
+      {}
+
+      explicit members_holder(const allocator_type &a)
+         :  map_allocator_type(a), allocator_type(a)
+         ,  m_map(0), m_map_size(0)
+         ,  m_start(), m_finish(m_start)
+      {}
+
+      template<class ValAllocConvertible, class PtrAllocConvertible>
+      members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
+         : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
+         , allocator_type    (boost::forward<ValAllocConvertible>(va))
+         , m_map(0), m_map_size(0)
+         , m_start(), m_finish(m_start)
+      {}
+
+      ptr_alloc_ptr   m_map;
+      val_alloc_size  m_map_size;
+      iterator        m_start;
+      iterator        m_finish;
+   } members_;
+
+   ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return members_;  }
+
+   const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return members_;  }
+
+   allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return members_;  }
+
+   const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return members_;  }
+};
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+//! A double-ended queue is a sequence that supports random access to elements, constant time insertion
+//! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
+//!
+//! \tparam T The type of object that is stored in the deque
+//! \tparam Allocator The allocator used for all internal memory management
+template <class T, class Allocator = new_allocator<T> >
+#else
+template <class T, class Allocator>
+#endif
+class deque : protected deque_base<Allocator>
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   typedef deque_base<Allocator> Base;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef T                                                                           value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(allocator_type)                                      stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator)                             iterator;
+   typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator)                       const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   private:                      // Internal typedefs
+   BOOST_COPYABLE_AND_MOVABLE(deque)
+   typedef typename Base::ptr_alloc_ptr index_pointer;
+   static size_type s_buffer_size()
+      { return Base::s_buffer_size(); }
+   typedef allocator_traits<Allocator>                  allocator_traits_type;
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructors a deque.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   deque() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : Base()
+   {}
+
+   //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
+      : Base(a)
+   {}
+
+   //! <b>Effects</b>: Constructs a deque
+   //!   and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit deque(size_type n)
+      : Base(n, allocator_type())
+   {
+      dtl::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
+      proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
+      //deque_base will deallocate in case of exception...
+   }
+
+   //! <b>Effects</b>: Constructs a deque
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default initialization or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   deque(size_type n, default_init_t)
+      : Base(n, allocator_type())
+   {
+      dtl::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
+      proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
+      //deque_base will deallocate in case of exception...
+   }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit deque(size_type n, const allocator_type &a)
+      : Base(n, a)
+   {
+      dtl::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
+      proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
+      //deque_base will deallocate in case of exception...
+   }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default initialization or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   deque(size_type n, default_init_t, const allocator_type &a)
+      : Base(n, a)
+   {
+      dtl::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
+      proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
+      //deque_base will deallocate in case of exception...
+   }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   deque(size_type n, const value_type& value)
+      : Base(n, allocator_type())
+   { this->priv_fill_initialize(value); }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   deque(size_type n, const value_type& value, const allocator_type& a)
+      : Base(n, a)
+   { this->priv_fill_initialize(value); }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the deque.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+   template <class InIt>
+   deque(InIt first, InIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible
+         <InIt, size_type>::type * = 0
+      #endif
+      )
+      : Base(allocator_type())
+   {
+      this->priv_range_initialize(first, last);
+   }
+
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the deque.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+   template <class InIt>
+   deque(InIt first, InIt last, const allocator_type& a
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible
+         <InIt, size_type>::type * = 0
+      #endif
+      )
+      : Base(a)
+   {
+      this->priv_range_initialize(first, last);
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+   //!   and inserts a copy of the range [il.begin(), il.end()) in the deque.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   deque(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : Base(a)
+   {
+      this->priv_range_initialize(il.begin(), il.end());
+   }
+#endif
+
+   //! <b>Effects</b>: Copy constructs a deque.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   deque(const deque& x)
+      :  Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
+   {
+      if(x.size()){
+         this->priv_initialize_map(x.size());
+         boost::container::uninitialized_copy_alloc
+            (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+      }
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   deque(BOOST_RV_REF(deque) x) BOOST_NOEXCEPT_OR_NOTHROW
+      :  Base(BOOST_MOVE_BASE(Base, x))
+   {  this->swap_members(x);   }
+
+   //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocation
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   deque(const deque& x, const allocator_type &a)
+      :  Base(a)
+   {
+      if(x.size()){
+         this->priv_initialize_map(x.size());
+         boost::container::uninitialized_copy_alloc
+            (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+      }
+   }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves x's resources to *this if a == allocator_type().
+   //!                 Otherwise copies values from x to *this.
+   //!
+   //! <b>Throws</b>: If allocation or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   deque(BOOST_RV_REF(deque) x, const allocator_type &a)
+      :  Base(a)
+   {
+      if(x.alloc() == a){
+         this->swap_members(x);
+      }
+      else{
+         if(x.size()){
+            this->priv_initialize_map(x.size());
+            boost::container::uninitialized_copy_alloc
+               ( this->alloc(), boost::make_move_iterator(x.begin())
+               , boost::make_move_iterator(x.end()), this->members_.m_start);
+         }
+      }
+   }
+
+   //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements.
+   ~deque() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+   }
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+            this->shrink_to_fit();
+         }
+         dtl::assign_alloc(this->alloc(), x.alloc(), flag);
+         dtl::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+         this->assign(x.cbegin(), x.cend());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   deque& operator= (BOOST_RV_REF(deque) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(this != &x);
+      allocator_type &this_alloc = this->alloc();
+      allocator_type &x_alloc    = x.alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      dtl::bool_<propagate_alloc> flag;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy objects but retain memory in case x reuses it in the future
+         this->clear();
+         //Move allocator if needed
+         dtl::move_alloc(this_alloc, x_alloc, flag);
+         dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+         //Nothrow swap
+         this->swap_members(x);
+      }
+      //Else do a one by one move
+      else{
+         this->assign( boost::make_move_iterator(x.begin())
+                     , boost::make_move_iterator(x.end()));
+      }
+      return *this;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Makes *this contain the same elements as il.
+   //!
+   //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in il.
+   deque& operator=(std::initializer_list<value_type> il)
+   {
+      this->assign(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Assigns the n copies of val to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   void assign(size_type n, const T& val)
+   {
+      typedef constant_iterator<value_type, difference_type> c_it;
+      this->assign(c_it(val, n), c_it());
+   }
+
+   //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template <class InIt>
+   void assign(InIt first, InIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InIt, size_type>
+         , dtl::is_not_input_iterator<InIt>
+         >::type * = 0
+      #endif
+      )
+   {
+      iterator cur = this->begin();
+      for ( ; first != last && cur != end(); ++cur, ++first){
+         *cur = *first;
+      }
+      if (first == last){
+         this->erase(cur, this->cend());
+      }
+      else{
+         this->insert(this->cend(), first, last);
+      }
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   void assign(FwdIt first, FwdIt last
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<FwdIt, size_type>
+         , dtl::is_input_iterator<FwdIt>
+         >::type * = 0
+      )
+   {
+      const size_type len = boost::container::iterator_distance(first, last);
+      if (len > size()) {
+         FwdIt mid = first;
+         boost::container::iterator_advance(mid, this->size());
+         boost::container::copy(first, mid, begin());
+         this->insert(this->cend(), mid, last);
+      }
+      else{
+         this->erase(boost::container::copy(first, last, this->begin()), cend());
+      }
+   }
+   #endif
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to il.size().
+   void assign(std::initializer_list<value_type> il)
+   {   this->assign(il.begin(), il.end());   }
+#endif
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return Base::alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return Base::alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return Base::alloc(); }
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_start; }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_start; }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_finish; }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_finish; }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return reverse_iterator(this->members_.m_finish); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return const_reverse_iterator(this->members_.m_finish); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+      { return reverse_iterator(this->members_.m_start); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return const_reverse_iterator(this->members_.m_start); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_start; }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_finish; }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return const_reverse_iterator(this->members_.m_finish); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return const_reverse_iterator(this->members_.m_start); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the deque contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->members_.m_finish == this->members_.m_start; }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return this->members_.m_finish - this->members_.m_start; }
+
+   //! <b>Effects</b>: Returns the largest possible size of the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return allocator_traits_type::max_size(this->alloc()); }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {
+      const size_type len = size();
+      if (new_size < len)
+         this->priv_erase_last_n(len - new_size);
+      else{
+         const size_type n = new_size - this->size();
+         dtl::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
+         priv_insert_back_aux_impl(n, proxy);
+      }
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void resize(size_type new_size, default_init_t)
+   {
+      const size_type len = size();
+      if (new_size < len)
+         this->priv_erase_last_n(len - new_size);
+      else{
+         const size_type n = new_size - this->size();
+         dtl::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
+         priv_insert_back_aux_impl(n, proxy);
+      }
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const value_type& x)
+   {
+      const size_type len = size();
+      if (new_size < len)
+         this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+      else
+         this->insert(this->members_.m_finish, new_size - len, x);
+   }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the deque is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void shrink_to_fit()
+   {
+      //This deque implementation already
+      //deallocates excess nodes when erasing
+      //so there is nothing to do except for
+      //empty deque
+      if(this->empty()){
+         this->priv_clear_map();
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->members_.m_start;
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->members_.m_start;
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(end()-1);
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(cend()-1);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return this->members_.m_start[difference_type(n)];
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return this->members_.m_start[difference_type(n)];
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns an iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() >= n);
+      return iterator(this->begin()+n);
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns a const_iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() >= n);
+      return const_iterator(this->cbegin()+n);
+   }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //Range checked priv_index_of
+      return this->priv_index_of(p);
+   }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //Range checked priv_index_of
+      return this->priv_index_of(p);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference at(size_type n)
+   {
+      this->priv_throw_if_out_of_range(n);
+      return (*this)[n];
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference at(size_type n) const
+   {
+      this->priv_throw_if_out_of_range(n);
+      return (*this)[n];
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the beginning of the deque.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time
+   template <class... Args>
+   reference emplace_front(BOOST_FWD_REF(Args)... args)
+   {
+      if(this->priv_push_front_simple_available()){
+         reference r = *this->priv_push_front_simple_pos();
+         allocator_traits_type::construct
+            ( this->alloc()
+            , this->priv_push_front_simple_pos()
+            , boost::forward<Args>(args)...);
+         this->priv_push_front_simple_commit();
+         return r;
+      }
+      else{
+         typedef dtl::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
+         return *this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
+      }
+   }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the end of the deque.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time
+   template <class... Args>
+   reference emplace_back(BOOST_FWD_REF(Args)... args)
+   {
+      if(this->priv_push_back_simple_available()){
+         reference r = *this->priv_push_back_simple_pos();
+         allocator_traits_type::construct
+            ( this->alloc()
+            , this->priv_push_back_simple_pos()
+            , boost::forward<Args>(args)...);
+         this->priv_push_back_simple_commit();
+         return r;
+      }
+      else{
+         typedef dtl::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
+         return *this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
+      }
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... before p
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   template <class... Args>
+   iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      if(p == this->cbegin()){
+         this->emplace_front(boost::forward<Args>(args)...);
+         return this->begin();
+      }
+      else if(p == this->cend()){
+         this->emplace_back(boost::forward<Args>(args)...);
+         return (this->end()-1);
+      }
+      else{
+         typedef dtl::insert_emplace_proxy<Allocator, iterator, Args...> type;
+         return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
+      }
+   }
+
+   #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+   reference emplace_front(BOOST_MOVE_UREF##N)\
+   {\
+      if(priv_push_front_simple_available()){\
+         reference r = *this->priv_push_front_simple_pos();\
+         allocator_traits_type::construct\
+            ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+         priv_push_front_simple_commit();\
+         return r;\
+      }\
+      else{\
+         typedef dtl::insert_nonmovable_emplace_proxy##N\
+               <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+         return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
+      }\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+   reference emplace_back(BOOST_MOVE_UREF##N)\
+   {\
+      if(priv_push_back_simple_available()){\
+         reference r = *this->priv_push_back_simple_pos();\
+         allocator_traits_type::construct\
+            ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+         priv_push_back_simple_commit();\
+         return r;\
+      }\
+      else{\
+         typedef dtl::insert_nonmovable_emplace_proxy##N\
+               <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+         return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
+      }\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+   iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      BOOST_ASSERT(this->priv_in_range_or_end(p));\
+      if(p == this->cbegin()){\
+         this->emplace_front(BOOST_MOVE_FWD##N);\
+         return this->begin();\
+      }\
+      else if(p == cend()){\
+         this->emplace_back(BOOST_MOVE_FWD##N);\
+         return (--this->end());\
+      }\
+      else{\
+         typedef dtl::insert_emplace_proxy_arg##N\
+               <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+         return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
+      }\
+   }
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the front of the deque
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the end of the deque
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator p, const T &x);
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a new element before p with x's resources.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator p, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: pos must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert n copies of x before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   iterator insert(const_iterator pos, size_type n, const value_type& x)
+   {
+      //Range check of p is done by insert()
+      typedef constant_iterator<value_type, difference_type> c_it;
+      return this->insert(pos, c_it(x, n), c_it());
+   }
+
+   //! <b>Requires</b>: pos must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InIt throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [first, last).
+   template <class InIt>
+   iterator insert(const_iterator pos, InIt first, InIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InIt, size_type>
+         , dtl::is_not_input_iterator<InIt>
+         >::type * = 0
+      #endif
+      )
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(pos));
+      size_type n = 0;
+      iterator it(pos.unconst());
+      for(;first != last; ++first, ++n){
+         it = this->emplace(it, *first);
+         ++it;
+      }
+      it -= n;
+      return it;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: pos must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or pos if il.begin() == il.end().
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced std::initializer_list throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
+   iterator insert(const_iterator pos, std::initializer_list<value_type> il)
+   {
+      //Range check os pos is done in insert()
+      return insert(pos, il.begin(), il.end());
+   }
+#endif
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   iterator insert(const_iterator p, FwdIt first, FwdIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<FwdIt, size_type>
+         , dtl::is_input_iterator<FwdIt>
+         >::type * = 0
+      #endif
+      )
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      dtl::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
+      return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy);
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the first element from the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
+            );
+         ++this->members_.m_start.m_cur;
+      }
+      else
+         this->priv_pop_front_aux();
+   }
+
+   //! <b>Effects</b>: Removes the last element from the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
+         --this->members_.m_finish.m_cur;
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
+            );
+      }
+      else
+         this->priv_pop_back_aux();
+   }
+
+   //! <b>Effects</b>: Erases the element at p.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the elements between pos and the
+   //!   last element (if pos is near the end) or the first element
+   //!   if(pos is near the beginning).
+   //!   Constant if pos is the first or the last element.
+   iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->priv_in_range(pos));
+      iterator next = pos.unconst();
+      ++next;
+      size_type index = pos - this->members_.m_start;
+      if (index < (this->size()/2)) {
+         boost::container::move_backward(this->begin(), pos.unconst(), next);
+         pop_front();
+      }
+      else {
+         boost::container::move(next, this->end(), pos.unconst());
+         pop_back();
+      }
+      return this->members_.m_start + index;
+   }
+
+   //! <b>Effects</b>: Erases the elements pointed by [first, last).
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the distance between first and
+   //!   last plus the elements between pos and the
+   //!   last element (if pos is near the end) or the first element
+   //!   if(pos is near the beginning).
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(first == last ||
+         (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
+      if (first == this->members_.m_start && last == this->members_.m_finish) {
+         this->clear();
+         return this->members_.m_finish;
+      }
+      else {
+         const size_type n = static_cast<size_type>(last - first);
+         const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
+         if (elems_before < (this->size() - n) - elems_before) {
+            boost::container::move_backward(begin(), first.unconst(), last.unconst());
+            iterator new_start = this->members_.m_start + n;
+            this->priv_destroy_range(this->members_.m_start, new_start);
+            this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
+            this->members_.m_start = new_start;
+         }
+         else {
+            boost::container::move(last.unconst(), end(), first.unconst());
+            iterator new_finish = this->members_.m_finish - n;
+            this->priv_destroy_range(new_finish, this->members_.m_finish);
+            this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+            this->members_.m_finish = new_finish;
+         }
+         return this->members_.m_start + elems_before;
+      }
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(deque &x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+                               || allocator_traits_type::is_always_equal::value)
+   {
+      this->swap_members(x);
+      dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+      dtl::swap_alloc(this->alloc(), x.alloc(), flag);
+      dtl::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the deque.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the deque.
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      for (index_pointer node = this->members_.m_start.m_node + 1;
+            node < this->members_.m_finish.m_node;
+            ++node) {
+         this->priv_destroy_range(*node, *node + this->s_buffer_size());
+         this->priv_deallocate_node(*node);
+      }
+
+      if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
+         this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
+         this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
+         this->priv_deallocate_node(this->members_.m_finish.m_first);
+      }
+      else
+         this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
+
+      this->members_.m_finish = this->members_.m_start;
+   }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const deque& x, const deque& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const deque& x, const deque& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const deque& x, const deque& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const deque& x, const deque& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const deque& x, const deque& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const deque& x, const deque& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(deque& x, deque& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   size_type priv_index_of(const_iterator p) const
+   {
+      BOOST_ASSERT(this->cbegin() <= p);
+      BOOST_ASSERT(p <= this->cend());
+      return static_cast<size_type>(p - this->cbegin());
+   }
+
+   void priv_erase_last_n(size_type n)
+   {
+      if(n == this->size()) {
+         this->clear();
+      }
+      else {
+         iterator new_finish = this->members_.m_finish - n;
+         this->priv_destroy_range(new_finish, this->members_.m_finish);
+         this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+         this->members_.m_finish = new_finish;
+      }
+   }
+
+   void priv_throw_if_out_of_range(size_type n) const
+   {
+      if (n >= this->size())
+         throw_out_of_range("deque::at out of range");
+   }
+
+   bool priv_in_range(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos < this->end());
+   }
+
+   bool priv_in_range_or_end(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos <= this->end());
+   }
+
+   template <class U>
+   iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      if (p == cbegin()){
+         this->push_front(::boost::forward<U>(x));
+         return begin();
+      }
+      else if (p == cend()){
+         this->push_back(::boost::forward<U>(x));
+         return --end();
+      }
+      else {
+         return priv_insert_aux_impl
+            ( p, (size_type)1
+            , dtl::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
+      }
+   }
+
+   template <class U>
+   void priv_push_front(BOOST_FWD_REF(U) x)
+   {
+      if(this->priv_push_front_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
+         this->priv_push_front_simple_commit();
+      }
+      else{
+         priv_insert_aux_impl
+            ( this->cbegin(), (size_type)1
+            , dtl::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
+      }
+   }
+
+   template <class U>
+   void priv_push_back(BOOST_FWD_REF(U) x)
+   {
+      if(this->priv_push_back_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
+         this->priv_push_back_simple_commit();
+      }
+      else{
+         priv_insert_aux_impl
+            ( this->cend(), (size_type)1
+            , dtl::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
+      }
+   }
+
+   bool priv_push_back_simple_available() const
+   {
+      return this->members_.m_map &&
+         (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
+   }
+
+   T *priv_push_back_simple_pos() const
+   {
+      return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
+   }
+
+   void priv_push_back_simple_commit()
+   {
+      ++this->members_.m_finish.m_cur;
+   }
+
+   bool priv_push_front_simple_available() const
+   {
+      return this->members_.m_map &&
+         (this->members_.m_start.m_cur != this->members_.m_start.m_first);
+   }
+
+   T *priv_push_front_simple_pos() const
+   {  return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1;  }
+
+   void priv_push_front_simple_commit()
+   {  --this->members_.m_start.m_cur;   }
+
+   void priv_destroy_range(iterator p, iterator p2)
+   {
+      if(!Base::traits_t::trivial_dctr){
+         for(;p != p2; ++p){
+            allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
+         }
+      }
+   }
+
+   void priv_destroy_range(pointer p, pointer p2)
+   {
+      if(!Base::traits_t::trivial_dctr){
+         for(;p != p2; ++p){
+            allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
+         }
+      }
+   }
+
+   template<class InsertProxy>
+   iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
+   {
+      iterator pos(p.unconst());
+      const size_type pos_n = p - this->cbegin();
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+         pos = this->begin();
+      }
+
+      const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
+      const size_type length = this->size();
+      if (elemsbefore < length / 2) {
+         const iterator new_start = this->priv_reserve_elements_at_front(n);
+         const iterator old_start = this->members_.m_start;
+         if(!elemsbefore){
+            proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
+            this->members_.m_start = new_start;
+         }
+         else{
+            pos = this->members_.m_start + elemsbefore;
+            if (elemsbefore >= n) {
+               const iterator start_n = this->members_.m_start + n;
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), this->members_.m_start, start_n, new_start);
+               this->members_.m_start = new_start;
+               boost::container::move(start_n, pos, old_start);
+               proxy.copy_n_and_update(this->alloc(), pos - n, n);
+            }
+            else {
+               const size_type mid_count = n - elemsbefore;
+               const iterator mid_start = old_start - mid_count;
+               proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
+               this->members_.m_start = mid_start;
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), old_start, pos, new_start);
+               this->members_.m_start = new_start;
+               proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
+            }
+         }
+      }
+      else {
+         const iterator new_finish = this->priv_reserve_elements_at_back(n);
+         const iterator old_finish = this->members_.m_finish;
+         const size_type elemsafter = length - elemsbefore;
+         if(!elemsafter){
+            proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
+            this->members_.m_finish = new_finish;
+         }
+         else{
+            pos = old_finish - elemsafter;
+            if (elemsafter >= n) {
+               iterator finish_n = old_finish - difference_type(n);
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), finish_n, old_finish, old_finish);
+               this->members_.m_finish = new_finish;
+               boost::container::move_backward(pos, finish_n, old_finish);
+               proxy.copy_n_and_update(this->alloc(), pos, n);
+            }
+            else {
+               const size_type raw_gap = n - elemsafter;
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), pos, old_finish, old_finish + raw_gap);
+               BOOST_TRY{
+                  proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
+                  proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
+               }
+               BOOST_CATCH(...){
+                  this->priv_destroy_range(old_finish, old_finish + elemsafter);
+                  BOOST_RETHROW
+               }
+               BOOST_CATCH_END
+               this->members_.m_finish = new_finish;
+            }
+         }
+      }
+      return this->begin() + pos_n;
+   }
+
+   template <class InsertProxy>
+   iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
+   {
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+      }
+
+      iterator new_finish = this->priv_reserve_elements_at_back(n);
+      iterator old_finish = this->members_.m_finish;
+      proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
+      this->members_.m_finish = new_finish;
+      return iterator(this->members_.m_finish - n);
+   }
+
+   template <class InsertProxy>
+   iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
+   {
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+      }
+
+      iterator new_start = this->priv_reserve_elements_at_front(n);
+      proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
+      this->members_.m_start = new_start;
+      return new_start;
+   }
+
+   iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
+   {
+      typedef constant_iterator<value_type, difference_type> c_it;
+      return this->insert(pos, c_it(x, n), c_it());
+   }
+
+   // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
+   // but none of the deque's elements have yet been constructed.
+   void priv_fill_initialize(const value_type& value)
+   {
+      index_pointer cur = this->members_.m_start.m_node;
+      BOOST_TRY {
+         for ( ; cur < this->members_.m_finish.m_node; ++cur){
+            boost::container::uninitialized_fill_alloc
+               (this->alloc(), *cur, *cur + this->s_buffer_size(), value);
+         }
+         boost::container::uninitialized_fill_alloc
+            (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template <class InIt>
+   void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
+   {
+      this->priv_initialize_map(0);
+      BOOST_TRY {
+         for ( ; first != last; ++first)
+            this->emplace_back(*first);
+      }
+      BOOST_CATCH(...){
+         this->clear();
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template <class FwdIt>
+   void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
+   {
+      size_type n = 0;
+      n = boost::container::iterator_distance(first, last);
+      this->priv_initialize_map(n);
+
+      index_pointer cur_node = this->members_.m_start.m_node;
+      BOOST_TRY {
+         for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
+            FwdIt mid = first;
+            boost::container::iterator_advance(mid, this->s_buffer_size());
+            ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
+            first = mid;
+         }
+         ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
+   void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      this->priv_deallocate_node(this->members_.m_finish.m_first);
+      this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
+      this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
+         );
+   }
+
+   // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1.  Note that
+   // if the deque has at least one element (a precondition for this member
+   // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
+   // must have at least two nodes.
+   void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
+         );
+      this->priv_deallocate_node(this->members_.m_start.m_first);
+      this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
+      this->members_.m_start.m_cur = this->members_.m_start.m_first;
+   }
+
+   iterator priv_reserve_elements_at_front(size_type n)
+   {
+      size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
+      if (n > vacancies){
+         size_type new_elems = n-vacancies;
+         size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
+            this->s_buffer_size();
+         size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
+         if (new_nodes > s){
+            this->priv_reallocate_map(new_nodes, true);
+         }
+         size_type i = 1;
+         BOOST_TRY {
+            for (; i <= new_nodes; ++i)
+               *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
+         }
+         BOOST_CATCH(...) {
+            for (size_type j = 1; j < i; ++j)
+               this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      return this->members_.m_start - difference_type(n);
+   }
+
+   iterator priv_reserve_elements_at_back(size_type n)
+   {
+      size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
+      if (n > vacancies){
+         size_type new_elems = n - vacancies;
+         size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
+         size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
+         if (new_nodes + 1 > s){
+            this->priv_reallocate_map(new_nodes, false);
+         }
+         size_type i = 1;
+         BOOST_TRY {
+            for (; i <= new_nodes; ++i)
+               *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
+         }
+         BOOST_CATCH(...) {
+            for (size_type j = 1; j < i; ++j)
+               this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      return this->members_.m_finish + difference_type(n);
+   }
+
+   void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
+   {
+      size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
+      size_type new_num_nodes = old_num_nodes + nodes_to_add;
+
+      index_pointer new_nstart;
+      if (this->members_.m_map_size > 2 * new_num_nodes) {
+         new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+                           + (add_at_front ? nodes_to_add : 0);
+         if (new_nstart < this->members_.m_start.m_node)
+            boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+         else
+            boost::container::move_backward
+               (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
+      }
+      else {
+         size_type new_map_size =
+            this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2;
+
+         index_pointer new_map = this->priv_allocate_map(new_map_size);
+         new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+                              + (add_at_front ? nodes_to_add : 0);
+         boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+
+         this->members_.m_map = new_map;
+         this->members_.m_map_size = new_map_size;
+      }
+
+      this->members_.m_start.priv_set_node(new_nstart);
+      this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
+   }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+template <typename InputIterator>
+deque(InputIterator, InputIterator) -> deque<typename iterator_traits<InputIterator>::value_type>;
+template <typename InputIterator, typename Allocator>
+deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
+#endif
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //   #ifndef  BOOST_CONTAINER_DEQUE_HPP
diff --git a/include/boost/container/detail/adaptive_node_pool.hpp b/include/boost/container/detail/adaptive_node_pool.hpp
new file mode 100644
index 0000000..d14e865
--- /dev/null
+++ b/include/boost/container/detail/adaptive_node_pool.hpp
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_ADAPTIVE_NODE_POOL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/intrusive/set.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/pool_common_alloc.hpp>
+#include <boost/container/detail/mutex.hpp>
+#include <boost/container/detail/adaptive_node_pool_impl.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <cstddef>
+#include <cmath>
+#include <cassert>
+
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+//!Pooled memory allocator using an smart adaptive pool. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per block (NodesPerBlock) are known at compile time.
+template< std::size_t NodeSize
+        , std::size_t NodesPerBlock
+        , std::size_t MaxFreeBlocks
+        , std::size_t OverheadPercent
+        >
+class private_adaptive_node_pool
+   :  public private_adaptive_node_pool_impl_ct
+            < fake_segment_manager
+            , MaxFreeBlocks
+            , NodeSize
+            , NodesPerBlock
+            , OverheadPercent
+            , unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
+               | ::boost::container::adaptive_pool_flag::size_ordered
+               | ::boost::container::adaptive_pool_flag::address_ordered
+            >
+{
+   typedef private_adaptive_node_pool_impl_ct
+            < fake_segment_manager
+            , MaxFreeBlocks
+            , NodeSize
+            , NodesPerBlock
+            , OverheadPercent
+            , unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
+               | ::boost::container::adaptive_pool_flag::size_ordered
+               | ::boost::container::adaptive_pool_flag::address_ordered
+            > base_t;
+
+   //Non-copyable
+   private_adaptive_node_pool(const private_adaptive_node_pool &);
+   private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
+
+   public:
+   static const std::size_t nodes_per_block = NodesPerBlock;
+
+   //!Constructor. Never throws
+   private_adaptive_node_pool()
+      : base_t(0)
+   {}
+};
+
+//!Pooled memory allocator using adaptive pool. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per block (NodesPerBlock) are known at compile time
+template< std::size_t NodeSize
+        , std::size_t NodesPerBlock
+        , std::size_t MaxFreeBlocks
+        , std::size_t OverheadPercent
+        >
+class shared_adaptive_node_pool
+   : public private_adaptive_node_pool
+      <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
+{
+ private:
+   typedef private_adaptive_node_pool
+      <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
+ public:
+   typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
+
+   //!Constructor. Never throws
+   shared_adaptive_node_pool()
+   : private_node_allocator_t(){}
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~shared_adaptive_node_pool()
+   {}
+
+   //!Allocates array of count elements. Can throw std::bad_alloc
+   void *allocate_node()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      return private_node_allocator_t::allocate_node();
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *ptr)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_node(ptr);
+   }
+
+   //!Allocates a singly linked list of n nodes ending in null pointer.
+   //!can throw std::bad_alloc
+   void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      return private_node_allocator_t::allocate_nodes(n, chain);
+   }
+
+   void deallocate_nodes(multiallocation_chain &chain)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_nodes(chain);
+   }
+
+   //!Deallocates all the free blocks of memory. Never throws
+   void deallocate_free_blocks()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_free_blocks();
+   }
+
+   private:
+   default_mutex mutex_;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
diff --git a/include/boost/container/detail/adaptive_node_pool_impl.hpp b/include/boost/container/detail/adaptive_node_pool_impl.hpp
new file mode 100644
index 0000000..a92ba98
--- /dev/null
+++ b/include/boost/container/detail/adaptive_node_pool_impl.hpp
@@ -0,0 +1,1259 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/math_functions.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace container {
+
+namespace adaptive_pool_flag {
+
+static const unsigned int none            = 0u;
+static const unsigned int align_only      = 1u << 0u;
+static const unsigned int size_ordered    = 1u << 1u;
+static const unsigned int address_ordered = 1u << 2u;
+
+}  //namespace adaptive_pool_flag{
+
+namespace dtl {
+
+template<class size_type>
+struct hdr_offset_holder_t
+{
+   hdr_offset_holder_t(size_type offset = 0)
+      : hdr_offset(offset)
+   {}
+   size_type hdr_offset;
+};
+
+template<class SizeType, unsigned int Flags>
+struct less_func;
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::none>
+{
+   static bool less(SizeType, SizeType, const void *, const void *)
+   {  return true;   }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered>
+{
+   static bool less(SizeType ls, SizeType rs, const void *, const void *)
+   {  return ls < rs;   }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::address_ordered>
+{
+   static bool less(SizeType, SizeType, const void *la, const void *ra)
+   {  return la < ra;   }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered>
+{
+   static bool less(SizeType ls, SizeType rs, const void *la, const void *ra)
+   {  return (ls < rs) || ((ls == rs) && (la < ra));  }
+};
+
+template<class VoidPointer, class SizeType, unsigned OrderFlags>
+struct block_container_traits
+{
+   typedef typename bi::make_set_base_hook
+      < bi::void_pointer<VoidPointer>
+      , bi::optimize_size<true>
+      , bi::link_mode<bi::normal_link> >::type hook_t;
+
+   template<class T>
+   struct container
+   {
+      typedef typename bi::make_multiset
+         <T, bi::base_hook<hook_t>, bi::size_type<SizeType> >::type  type;
+   };
+
+   template<class Container>
+   static void reinsert_was_used(Container &container, typename Container::reference v, bool)
+   {
+      typedef typename Container::const_iterator const_block_iterator;
+      typedef typename Container::iterator       block_iterator;
+      typedef typename Container::value_compare  value_compare;
+
+      const block_iterator this_block(Container::s_iterator_to(v));
+      const const_block_iterator cendit(container.cend());
+      block_iterator next_block(this_block);
+
+      if(++next_block != cendit && value_compare()(*next_block, v)){
+         const_block_iterator next2_block(next_block);
+         //Test if v should be swapped with next (optimization)
+         if(++next2_block == cendit || !value_compare()(*next2_block, v)){
+            v.swap_nodes(*next_block);
+            BOOST_ASSERT(++next_block == this_block);
+         }
+         else{
+            container.erase(this_block);
+            container.insert(v);
+         }
+      }
+   }
+
+   template<class Container>
+   static void insert_was_empty(Container &container, typename Container::value_type &v, bool)
+   {
+      container.insert(v);
+   }
+
+   template<class Container>
+   static void erase_first(Container &container)
+   {
+      container.erase(container.cbegin());
+   }
+
+   template<class Container>
+   static void erase_last(Container &container)
+   {
+      container.erase(--container.cend());
+   }
+};
+
+template<class VoidPointer, class SizeType>
+struct block_container_traits<VoidPointer, SizeType, 0u>
+{
+   typedef typename bi::make_list_base_hook
+      < bi::void_pointer<VoidPointer>
+      , bi::link_mode<bi::normal_link> >::type hook_t;
+
+   template<class T>
+   struct container
+   {
+      typedef typename bi::make_list
+         <T, bi::base_hook<hook_t>, bi::size_type<SizeType>, bi::constant_time_size<false> >::type  type;
+   };
+
+   template<class Container>
+   static void reinsert_was_used(Container &container, typename Container::value_type &v, bool is_full)
+   {
+      if(is_full){
+         container.erase(Container::s_iterator_to(v));
+         container.push_back(v);
+      }
+   }
+
+   template<class Container>
+   static void insert_was_empty(Container &container, typename Container::value_type &v, bool is_full)
+   {
+      if(is_full){
+         container.push_back(v);
+      }
+      else{
+         container.push_front(v);
+      }
+   }
+
+   template<class Container>
+   static void erase_first(Container &container)
+   {
+      container.pop_front();
+   }
+
+   template<class Container>
+   static void erase_last(Container &container)
+   {
+      container.pop_back();
+   }
+};
+
+/////////////////////////////
+//
+//    adaptive_pool_types
+//
+/////////////////////////////
+template<class MultiallocationChain, class VoidPointer, class SizeType, unsigned int Flags>
+struct adaptive_pool_types
+{
+   typedef VoidPointer void_pointer;
+   static const unsigned ordered = (Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered));
+   typedef block_container_traits<VoidPointer, SizeType, ordered> block_container_traits_t;
+   typedef typename block_container_traits_t::hook_t hook_t;
+   typedef hdr_offset_holder_t<SizeType> hdr_offset_holder;
+   static const unsigned int order_flags = Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered);
+   typedef MultiallocationChain free_nodes_t;
+
+   struct block_info_t
+      : public hdr_offset_holder,
+        public hook_t
+   {
+      //An intrusive list of free node from this block
+      free_nodes_t free_nodes;
+      friend bool operator <(const block_info_t &l, const block_info_t &r)
+      {
+         return less_func<SizeType, order_flags>::
+            less(l.free_nodes.size(), r.free_nodes.size(), &l , &r);
+      }
+
+      friend bool operator ==(const block_info_t &l, const block_info_t &r)
+      {  return &l == &r;  }
+   };
+   typedef typename block_container_traits_t:: template container<block_info_t>::type  block_container_t;
+};
+
+
+/////////////////////////////////////////////
+//
+//       candidate_power_of_2_ct
+//
+/////////////////////////////////////////////
+template< std::size_t alignment
+        , std::size_t real_node_size
+        , std::size_t payload_per_allocation
+        , std::size_t min_elements_per_block
+        , std::size_t hdr_size
+        , std::size_t hdr_offset_size
+        , std::size_t overhead_percent>
+struct candidate_power_of_2_ct_helper
+{
+   static const std::size_t hdr_subblock_elements_alone = (alignment - hdr_size - payload_per_allocation)/real_node_size;
+   static const std::size_t hdr_subblock_elements_first = (alignment - hdr_size - payload_per_allocation)/real_node_size;
+   static const std::size_t elements_per_b_subblock_mid = (alignment - hdr_offset_size)/real_node_size;
+   static const std::size_t elements_per_b_subblock_end = (alignment - hdr_offset_size - payload_per_allocation)/real_node_size;
+   static const std::size_t num_b_subblock =
+      hdr_subblock_elements_alone >= min_elements_per_block
+         ? 0
+         : (   ((hdr_subblock_elements_first + elements_per_b_subblock_end) >= min_elements_per_block)
+               ? 1
+               : 2 + (min_elements_per_block - hdr_subblock_elements_first - elements_per_b_subblock_end - 1)/elements_per_b_subblock_mid
+            )
+         ;
+
+   static const std::size_t num_b_subblock_mid = (num_b_subblock > 1) ? (num_b_subblock - 1) : 0;
+
+   static const std::size_t total_nodes = (num_b_subblock == 0)
+                                         ? hdr_subblock_elements_alone
+                                         : ( (num_b_subblock == 1)
+                                           ? (hdr_subblock_elements_first + elements_per_b_subblock_end)
+                                           : (hdr_subblock_elements_first + num_b_subblock_mid*elements_per_b_subblock_mid + elements_per_b_subblock_end)
+                                           )
+                                         ;
+   static const std::size_t total_data = total_nodes*real_node_size;
+   static const std::size_t total_size = alignment*(num_b_subblock+1);
+   static const bool overhead_satisfied = (total_size - total_data)*100/total_size < overhead_percent;
+};
+
+template< std::size_t initial_alignment
+        , std::size_t real_node_size
+        , std::size_t payload_per_allocation
+        , std::size_t min_elements_per_block
+        , std::size_t hdr_size
+        , std::size_t hdr_offset_size
+        , std::size_t overhead_percent
+        , bool Loop = true>
+struct candidate_power_of_2_ct
+{
+   typedef candidate_power_of_2_ct_helper
+        < initial_alignment
+        , real_node_size
+        , payload_per_allocation
+        , min_elements_per_block
+        , hdr_size
+        , hdr_offset_size
+        , overhead_percent> helper_t;
+
+   static const std::size_t candidate_power_of_2 = initial_alignment << std::size_t(!helper_t::overhead_satisfied);
+
+   typedef typename candidate_power_of_2_ct
+      < candidate_power_of_2
+      , real_node_size
+      , payload_per_allocation
+      , min_elements_per_block
+      , hdr_size
+      , hdr_offset_size
+      , overhead_percent
+      , !helper_t::overhead_satisfied
+      >::type type;
+
+   static const std::size_t alignment     = type::alignment;
+   static const std::size_t num_subblocks = type::num_subblocks;
+   static const std::size_t real_num_node = type::real_num_node;
+};
+
+template< std::size_t initial_alignment
+        , std::size_t real_node_size
+        , std::size_t payload_per_allocation
+        , std::size_t min_elements_per_block
+        , std::size_t hdr_size
+        , std::size_t hdr_offset_size
+        , std::size_t overhead_percent
+        >
+struct candidate_power_of_2_ct
+      < initial_alignment
+      , real_node_size
+      , payload_per_allocation
+      , min_elements_per_block
+      , hdr_size
+      , hdr_offset_size
+      , overhead_percent
+      , false>
+{
+   typedef candidate_power_of_2_ct
+      < initial_alignment
+      , real_node_size
+      , payload_per_allocation
+      , min_elements_per_block
+      , hdr_size
+      , hdr_offset_size
+      , overhead_percent
+      , false> type;
+
+   typedef candidate_power_of_2_ct_helper
+        < initial_alignment
+        , real_node_size
+        , payload_per_allocation
+        , min_elements_per_block
+        , hdr_size
+        , hdr_offset_size
+        , overhead_percent> helper_t;
+
+   static const std::size_t alignment = initial_alignment;
+   static const std::size_t num_subblocks = helper_t::num_b_subblock+1;
+   static const std::size_t real_num_node = helper_t::total_nodes;
+};
+
+/////////////////////////////////////////////
+//
+//       candidate_power_of_2_rt
+//
+/////////////////////////////////////////////
+void candidate_power_of_2_rt  ( std::size_t initial_alignment
+                              , std::size_t real_node_size
+                              , std::size_t payload_per_allocation
+                              , std::size_t min_elements_per_block
+                              , std::size_t hdr_size
+                              , std::size_t hdr_offset_size
+                              , std::size_t overhead_percent
+                              , std::size_t &alignment
+                              , std::size_t &num_subblocks
+                              , std::size_t &real_num_node)
+{
+   bool overhead_satisfied = false;
+   std::size_t num_b_subblock = 0;
+   std::size_t total_nodes = 0;
+
+   while(!overhead_satisfied)
+   {
+      std::size_t hdr_subblock_elements_alone = (initial_alignment - hdr_size - payload_per_allocation)/real_node_size;
+      std::size_t hdr_subblock_elements_first = (initial_alignment - hdr_size - payload_per_allocation)/real_node_size;
+      std::size_t elements_per_b_subblock_mid = (initial_alignment - hdr_offset_size)/real_node_size;
+      std::size_t elements_per_b_subblock_end = (initial_alignment - hdr_offset_size - payload_per_allocation)/real_node_size;
+
+      num_b_subblock =
+         hdr_subblock_elements_alone >= min_elements_per_block
+            ? 0
+            : (   ((hdr_subblock_elements_first + elements_per_b_subblock_end) >= min_elements_per_block)
+                  ? 1
+                  : 2 + (min_elements_per_block - hdr_subblock_elements_first - elements_per_b_subblock_end - 1)/elements_per_b_subblock_mid
+               )
+            ;
+
+      std::size_t num_b_subblock_mid = (num_b_subblock > 1) ? (num_b_subblock - 1) : 0;
+
+      total_nodes = (num_b_subblock == 0)
+                                          ? hdr_subblock_elements_alone
+                                          : ( (num_b_subblock == 1)
+                                             ? (hdr_subblock_elements_first + elements_per_b_subblock_end)
+                                             : (hdr_subblock_elements_first + num_b_subblock_mid*elements_per_b_subblock_mid + elements_per_b_subblock_end)
+                                             )
+                                          ;
+      std::size_t total_data = total_nodes*real_node_size;
+      std::size_t total_size = initial_alignment*(num_b_subblock+1);
+      overhead_satisfied = (total_size - total_data)*100/total_size < overhead_percent;
+      initial_alignment = initial_alignment << std::size_t(!overhead_satisfied);
+   }
+   alignment     = initial_alignment;
+   num_subblocks = num_b_subblock+1;
+   real_num_node = total_nodes;
+}
+
+/////////////////////////////////////////////
+//
+// private_adaptive_node_pool_impl_common
+//
+/////////////////////////////////////////////
+template< class SegmentManagerBase, unsigned int Flags>
+class private_adaptive_node_pool_impl_common
+{
+   public:
+   //!Segment manager typedef
+   typedef SegmentManagerBase                                        segment_manager_base_type;
+   typedef typename SegmentManagerBase::multiallocation_chain        multiallocation_chain;
+   typedef typename SegmentManagerBase::size_type                    size_type;
+   //Flags
+   //align_only
+   static const bool AlignOnly      = (Flags & adaptive_pool_flag::align_only) != 0;
+   typedef bool_<AlignOnly>            IsAlignOnly;
+   typedef true_                       AlignOnlyTrue;
+   typedef false_                      AlignOnlyFalse;
+
+   typedef typename SegmentManagerBase::void_pointer void_pointer;
+   static const typename SegmentManagerBase::
+      size_type PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+
+   typedef typename boost::intrusive::pointer_traits
+      <void_pointer>::template rebind_pointer<segment_manager_base_type>::type   segment_mngr_base_ptr_t;
+
+   protected:
+   typedef adaptive_pool_types
+      <multiallocation_chain, void_pointer, size_type, Flags>        adaptive_pool_types_t;
+   typedef typename adaptive_pool_types_t::free_nodes_t              free_nodes_t;
+   typedef typename adaptive_pool_types_t::block_info_t              block_info_t;
+   typedef typename adaptive_pool_types_t::block_container_t         block_container_t;
+   typedef typename adaptive_pool_types_t::block_container_traits_t  block_container_traits_t;
+   typedef typename block_container_t::iterator                      block_iterator;
+   typedef typename block_container_t::const_iterator                const_block_iterator;
+   typedef typename adaptive_pool_types_t::hdr_offset_holder         hdr_offset_holder;
+   typedef private_adaptive_node_pool_impl_common                    this_type;
+
+   static const size_type MaxAlign = alignment_of<void_pointer>::value;
+   static const size_type HdrSize  = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
+   static const size_type HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
+
+   segment_mngr_base_ptr_t             mp_segment_mngr_base;   //Segment manager
+   block_container_t                   m_block_container;      //Intrusive block list
+   size_type                           m_totally_free_blocks;  //Free blocks
+
+   class block_destroyer;
+   friend class block_destroyer;
+
+   class block_destroyer
+   {
+      public:
+      block_destroyer(const this_type *impl, multiallocation_chain &chain, const size_type num_subblocks, const size_type real_block_alignment, const size_type real_num_node)
+         :  mp_impl(impl), m_chain(chain), m_num_subblocks(num_subblocks), m_real_block_alignment(real_block_alignment), m_real_num_node(real_num_node)
+      {}
+
+      void operator()(typename block_container_t::pointer to_deallocate)
+      {  return this->do_destroy(to_deallocate, IsAlignOnly()); }
+
+      private:
+      void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyTrue)
+      {
+         BOOST_ASSERT(to_deallocate->free_nodes.size() == m_real_num_node);
+         m_chain.push_back(to_deallocate);
+      }
+
+      void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyFalse)
+      {
+         BOOST_ASSERT(to_deallocate->free_nodes.size() == m_real_num_node);
+         BOOST_ASSERT(0 == to_deallocate->hdr_offset);
+         hdr_offset_holder *hdr_off_holder =
+            mp_impl->priv_first_subblock_from_block(boost::movelib::to_raw_pointer(to_deallocate), m_num_subblocks, m_real_block_alignment);
+         m_chain.push_back(hdr_off_holder);
+      }
+
+      const this_type *mp_impl;
+      multiallocation_chain &m_chain;
+      const size_type m_num_subblocks;
+      const size_type m_real_block_alignment;
+      const size_type m_real_num_node;
+   };
+
+   //This macro will activate invariant checking. Slow, but helpful for debugging the code.
+   //#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+   void priv_invariants(const size_type real_num_node, const size_type num_subblocks, const size_type real_block_alignment) const
+   {
+      (void)real_num_node; (void)num_subblocks; (void)real_block_alignment;
+   #ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+      //Check that the total totally free blocks are correct
+      BOOST_ASSERT(m_block_container.size() >= m_totally_free_blocks);
+
+      const const_block_iterator itend(m_block_container.cend());
+      const const_block_iterator itbeg(m_block_container.cbegin());
+
+      {  //Try to do checks in a single iteration
+         const_block_iterator it(itbeg);
+         size_type total_free_nodes = 0;
+         size_type total_free_blocks = 0u;
+         for(; it != itend; ++it){
+            if(it != itbeg){
+               //Check order invariant
+               const_block_iterator prev(it);
+               --prev;
+               BOOST_ASSERT(!(m_block_container.key_comp()(*it, *prev)));
+               (void)prev;   (void)it;
+            }
+
+            //free_nodes invariant
+            const size_type free_nodes = it->free_nodes.size();
+            BOOST_ASSERT(free_nodes <= real_num_node);
+            BOOST_ASSERT(free_nodes != 0);
+
+            //Acummulate total_free_nodes and total_free_blocks
+            total_free_nodes += free_nodes;
+            total_free_blocks += it->free_nodes.size() == real_num_node;
+
+            if (!AlignOnly) {
+               //Check that header offsets are correct
+               hdr_offset_holder *hdr_off_holder = this->priv_first_subblock_from_block(const_cast<block_info_t *>(&*it), num_subblocks, real_block_alignment);
+               for (size_type i = 0, max = num_subblocks; i < max; ++i) {
+                  const size_type offset = reinterpret_cast<char*>(const_cast<block_info_t *>(&*it)) - reinterpret_cast<char*>(hdr_off_holder);
+                  (void)offset;
+                  BOOST_ASSERT(hdr_off_holder->hdr_offset == offset);
+                  BOOST_ASSERT(0 == (reinterpret_cast<std::size_t>(hdr_off_holder) & (real_block_alignment - 1)));
+                  BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (real_block_alignment - 1)));
+                  hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + real_block_alignment);
+               }
+            }
+         }
+         BOOST_ASSERT(total_free_blocks == m_totally_free_blocks);
+         BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*real_num_node);
+      }
+   #endif
+   }
+
+   void priv_deallocate_free_blocks( const size_type max_free_blocks, const size_type real_num_node
+                                   , const size_type num_subblocks, const size_type real_block_alignment)
+   {  //Trampoline function to ease inlining
+      if(m_totally_free_blocks > max_free_blocks){
+         this->priv_deallocate_free_blocks_impl(max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+      }
+   }
+
+   hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, const size_type num_subblocks, const size_type real_block_alignment) const
+   {  return this->priv_first_subblock_from_block(block, num_subblocks, real_block_alignment, IsAlignOnly());   }
+
+   hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, const size_type num_subblocks, const size_type real_block_alignment, AlignOnlyFalse) const
+   {
+      hdr_offset_holder *const hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+            (reinterpret_cast<char*>(block) - (num_subblocks-1)*real_block_alignment);
+      BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
+      BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (real_block_alignment - 1)));
+      BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (real_block_alignment - 1)));
+      return hdr_off_holder;
+   }
+
+   hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, const size_type num_subblocks, const size_type real_block_alignment, AlignOnlyTrue) const
+   {
+      (void)num_subblocks; (void)real_block_alignment;
+      return reinterpret_cast<hdr_offset_holder*>(block);
+   }
+
+   void priv_deallocate_free_blocks_impl( const size_type max_free_blocks, const size_type real_num_node
+                                        , const size_type num_subblocks, const size_type real_block_alignment)
+   {
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+      //Now check if we've reached the free nodes limit
+      //and check if we have free blocks. If so, deallocate as much
+      //as we can to stay below the limit
+      multiallocation_chain chain;
+      {
+         if(Flags & adaptive_pool_flag::size_ordered){
+            const_block_iterator it = m_block_container.cend();
+            --it;
+            size_type totally_free_blocks = m_totally_free_blocks;
+
+            for( ; totally_free_blocks > max_free_blocks; --totally_free_blocks){
+               BOOST_ASSERT(it->free_nodes.size() == real_num_node);
+               void *addr = priv_first_subblock_from_block(const_cast<block_info_t*>(&*it), num_subblocks, real_block_alignment);
+               --it;
+               block_container_traits_t::erase_last(m_block_container);
+               chain.push_front(void_pointer(addr));
+            }
+         }
+         else{
+            const_block_iterator it = m_block_container.cend();
+            size_type totally_free_blocks = m_totally_free_blocks;
+
+            while(totally_free_blocks > max_free_blocks){
+               --it;
+               if(it->free_nodes.size() == real_num_node){
+                  void *addr = priv_first_subblock_from_block(const_cast<block_info_t*>(&*it), num_subblocks, real_block_alignment);
+                  it = m_block_container.erase(it);
+                  chain.push_front(void_pointer(addr));
+                  --totally_free_blocks;
+               }
+            }
+         }
+         BOOST_ASSERT((m_totally_free_blocks - max_free_blocks) == chain.size());
+         m_totally_free_blocks = max_free_blocks;
+      }
+      this->mp_segment_mngr_base->deallocate_many(chain);
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+   }
+
+   void priv_fill_chain_remaining_to_block
+      ( multiallocation_chain &chain, size_type target_elem_in_chain, block_info_t &c_info
+      , char *mem_address, size_type max_node_in_mem
+      , const size_type real_node_size)
+   {
+      BOOST_ASSERT(chain.size() <= target_elem_in_chain);
+
+      //First add all possible nodes to the chain
+      const size_type left = target_elem_in_chain - chain.size();
+      const size_type add_to_chain = (max_node_in_mem < left) ? max_node_in_mem : left;
+      char *free_mem_address = static_cast<char *>(boost::movelib::to_raw_pointer
+         (chain.incorporate_after(chain.last(), void_pointer(mem_address), real_node_size, add_to_chain)));
+      //Now store remaining nodes in the free list
+      if(const size_type free = max_node_in_mem - add_to_chain){
+         free_nodes_t & free_nodes = c_info.free_nodes;
+         free_nodes.incorporate_after(free_nodes.last(), void_pointer(free_mem_address), real_node_size, free);
+      }
+   }
+
+   //!Allocates a several blocks of nodes. Can throw
+   void priv_append_from_new_blocks( size_type min_elements, multiallocation_chain &chain
+                                   , const size_type max_free_blocks
+                                   , const size_type real_block_alignment, const size_type real_node_size
+                                   , const size_type real_num_node, const size_type num_subblocks
+                                   , AlignOnlyTrue)
+   {
+      (void)num_subblocks;
+      BOOST_ASSERT(m_block_container.empty());
+      BOOST_ASSERT(min_elements > 0);
+      const size_type n = (min_elements - 1)/real_num_node + 1;
+      const size_type real_block_size = real_block_alignment - PayloadPerAllocation;
+      const size_type target_elem_in_chain = chain.size() + min_elements;
+      for(size_type i = 0; i != n; ++i){
+         //We allocate a new NodeBlock and put it the last
+         //element of the tree
+         char *mem_address = static_cast<char*>
+            (mp_segment_mngr_base->allocate_aligned(real_block_size, real_block_alignment));
+         if(!mem_address){
+            //In case of error, free memory deallocating all nodes (the new ones allocated
+            //in this function plus previously stored nodes in chain).
+            this->priv_deallocate_nodes(chain, max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+            throw_bad_alloc();
+         }
+         block_info_t &c_info = *new(mem_address)block_info_t();
+         mem_address += HdrSize;
+         this->priv_fill_chain_remaining_to_block(chain, target_elem_in_chain, c_info, mem_address, real_num_node, real_node_size);
+         const size_type free_nodes = c_info.free_nodes.size();
+         if(free_nodes){
+            const bool is_full = free_nodes == real_num_node;
+            BOOST_ASSERT(free_nodes < real_num_node);
+            m_totally_free_blocks += static_cast<size_type>(is_full);
+            block_container_traits_t::insert_was_empty(m_block_container, c_info, is_full);
+         }
+      }
+   }
+
+   void priv_append_from_new_blocks( size_type min_elements, multiallocation_chain &chain
+                                   , const size_type max_free_blocks
+                                   , const size_type real_block_alignment, const size_type real_node_size
+                                   , const size_type real_num_node, const size_type num_subblocks
+                                   , AlignOnlyFalse)
+   {
+      BOOST_ASSERT(m_block_container.empty());
+      BOOST_ASSERT(min_elements > 0);
+      const size_type n = (min_elements - 1)/real_num_node + 1;
+      const size_type real_block_size = real_block_alignment*num_subblocks - PayloadPerAllocation;
+      const size_type elements_per_subblock_mid = (real_block_alignment - HdrOffsetSize)/real_node_size;
+      const size_type elements_per_subblock_end = (real_block_alignment - HdrOffsetSize - PayloadPerAllocation) / real_node_size;
+      const size_type hdr_subblock_elements = (real_block_alignment - HdrSize - PayloadPerAllocation)/real_node_size;
+      const size_type target_elem_in_chain = chain.size() + min_elements;
+
+      for(size_type i = 0; i != n; ++i){
+         //We allocate a new NodeBlock and put it the last
+         //element of the tree
+         char *mem_address = static_cast<char*>
+            (mp_segment_mngr_base->allocate_aligned(real_block_size, real_block_alignment));
+         if(!mem_address){
+            //In case of error, free memory deallocating all nodes (the new ones allocated
+            //in this function plus previously stored nodes in chain).
+            this->priv_deallocate_nodes(chain, max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+            throw_bad_alloc();
+         }
+         //First initialize header information on the last subblock
+         char *hdr_addr = mem_address + real_block_alignment*(num_subblocks-1);
+         block_info_t &c_info = *new(hdr_addr)block_info_t();
+         //Some structural checks
+         BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder&>(c_info).hdr_offset) ==
+                      static_cast<void*>(&c_info));   (void)c_info;
+         for( size_type subblock = 0, maxsubblock = num_subblocks - 1
+            ; subblock < maxsubblock
+            ; ++subblock, mem_address += real_block_alignment){
+            //Initialize header offset mark
+            new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+            const size_type elements_per_subblock = (subblock != (maxsubblock - 1)) ? elements_per_subblock_mid : elements_per_subblock_end;
+            this->priv_fill_chain_remaining_to_block
+               (chain, target_elem_in_chain, c_info, mem_address + HdrOffsetSize, elements_per_subblock, real_node_size);
+         }
+         this->priv_fill_chain_remaining_to_block
+            (chain, target_elem_in_chain, c_info, hdr_addr + HdrSize, hdr_subblock_elements, real_node_size);
+         m_totally_free_blocks += static_cast<size_type>(c_info.free_nodes.size() == real_num_node);
+         if (c_info.free_nodes.size())
+            m_block_container.push_front(c_info);
+      }
+   }
+
+   //!Allocates array of count elements. Can throw
+   void *priv_allocate_node( const size_type max_free_blocks, const size_type real_block_alignment, const size_type real_node_size
+                           , const size_type real_num_node, const size_type num_subblocks)
+   {
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+      //If there are no free nodes we allocate a new block
+      if(!m_block_container.empty()){
+         //We take the first free node the multiset can't be empty
+         free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
+         BOOST_ASSERT(!free_nodes.empty());
+         const size_type free_nodes_count = free_nodes.size();
+         void *first_node = boost::movelib::to_raw_pointer(free_nodes.pop_front());
+         if(free_nodes.empty()){
+            block_container_traits_t::erase_first(m_block_container);
+         }
+         m_totally_free_blocks -= static_cast<size_type>(free_nodes_count == real_num_node);
+         this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+         return first_node;
+      }
+      else{
+         multiallocation_chain chain;
+         this->priv_append_from_new_blocks
+            (1, chain, max_free_blocks, real_block_alignment, real_node_size, real_num_node, num_subblocks, IsAlignOnly());
+         void *node = boost::movelib::to_raw_pointer(chain.pop_front());
+         this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+         return node;
+      }
+   }
+
+   void priv_allocate_nodes( const size_type n, multiallocation_chain &chain
+                           , const size_type max_free_blocks, const size_type real_block_alignment, const size_type real_node_size
+                           , const size_type real_num_node, const size_type num_subblocks)
+   {
+      size_type i = 0;
+      BOOST_TRY{
+         this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+         while(i != n){
+            //If there are no free nodes we allocate all needed blocks
+            if (m_block_container.empty()){
+               this->priv_append_from_new_blocks
+                  (n - i, chain, max_free_blocks, real_block_alignment, real_node_size, real_num_node, num_subblocks, IsAlignOnly());
+               BOOST_ASSERT(m_block_container.empty() || (++m_block_container.cbegin() == m_block_container.cend()));
+               BOOST_ASSERT(chain.size() == n);
+               break;
+            }
+            free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
+            const size_type free_nodes_count_before = free_nodes.size();
+            m_totally_free_blocks -= static_cast<size_type>(free_nodes_count_before == real_num_node);
+            const size_type num_left  = n-i;
+            const size_type num_elems = (num_left < free_nodes_count_before) ? num_left : free_nodes_count_before;
+            typedef typename free_nodes_t::iterator free_nodes_iterator;
+
+            if(num_left < free_nodes_count_before){
+               const free_nodes_iterator it_bbeg(free_nodes.before_begin());
+               free_nodes_iterator it_bend(it_bbeg);
+               for(size_type j = 0; j != num_elems; ++j){
+                  ++it_bend;
+               }
+               free_nodes_iterator it_end = it_bend; ++it_end;
+               free_nodes_iterator it_beg = it_bbeg; ++it_beg;
+               free_nodes.erase_after(it_bbeg, it_end, num_elems);
+               chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+               //chain.splice_after(chain.last(), free_nodes, it_bbeg, it_bend, num_elems);
+               BOOST_ASSERT(!free_nodes.empty());
+            }
+            else{
+               const free_nodes_iterator it_beg(free_nodes.begin()), it_bend(free_nodes.last());
+               free_nodes.clear();
+               chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+               block_container_traits_t::erase_first(m_block_container);
+            }
+            i += num_elems;
+         }
+      }
+      BOOST_CATCH(...){
+         this->priv_deallocate_nodes(chain, max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+         this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void priv_deallocate_node( void *pElem
+                            , const size_type max_free_blocks, const size_type real_num_node
+                            , const size_type num_subblocks, const size_type real_block_alignment)
+   {
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+      block_info_t &block_info = *this->priv_block_from_node(pElem, real_block_alignment);
+      const size_type prev_free_nodes = block_info.free_nodes.size();
+      BOOST_ASSERT(block_info.free_nodes.size() < real_num_node);
+
+      //We put the node at the beginning of the free node list
+      block_info.free_nodes.push_back(void_pointer(pElem));
+
+      //The loop reinserts all blocks except the last one
+      this->priv_reinsert_block(block_info, prev_free_nodes == 0, real_num_node);
+      this->priv_deallocate_free_blocks(max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+   }
+
+   void priv_deallocate_nodes( multiallocation_chain &nodes
+                             , const size_type max_free_blocks, const size_type real_num_node
+                             , const size_type num_subblocks, const size_type real_block_alignment)
+   {
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+      //To take advantage of node locality, wait until two
+      //nodes belong to different blocks. Only then reinsert
+      //the block of the first node in the block tree.
+      //Cache of the previous block
+      block_info_t *prev_block_info = 0;
+
+      //If block was empty before this call, it's not already
+      //inserted in the block tree.
+      bool prev_block_was_empty     = false;
+      typedef typename free_nodes_t::iterator free_nodes_iterator;
+      {
+         const free_nodes_iterator itbb(nodes.before_begin()), ite(nodes.end());
+         free_nodes_iterator itf(nodes.begin()), itbf(itbb);
+         size_type splice_node_count = size_type(-1);
+         while(itf != ite){
+            void *pElem = boost::movelib::to_raw_pointer(boost::movelib::iterator_to_raw_pointer(itf));
+            block_info_t &block_info = *this->priv_block_from_node(pElem, real_block_alignment);
+            BOOST_ASSERT(block_info.free_nodes.size() < real_num_node);
+            ++splice_node_count;
+
+            //If block change is detected calculate the cached block position in the tree
+            if(&block_info != prev_block_info){
+               if(prev_block_info){ //Make sure we skip the initial "dummy" cache
+                  free_nodes_iterator it(itbb); ++it;
+                  nodes.erase_after(itbb, itf, splice_node_count);
+                  prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*it, &*itbf, splice_node_count);
+                  this->priv_reinsert_block(*prev_block_info, prev_block_was_empty, real_num_node);
+                  splice_node_count = 0;
+               }
+               //Update cache with new data
+               prev_block_was_empty = block_info.free_nodes.empty();
+               prev_block_info = &block_info;
+            }
+            itbf = itf;
+            ++itf;
+         }
+      }
+      if(prev_block_info){
+         //The loop reinserts all blocks except the last one
+         const free_nodes_iterator itfirst(nodes.begin()), itlast(nodes.last());
+         const size_type splice_node_count = nodes.size();
+         nodes.clear();
+         prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*itfirst, &*itlast, splice_node_count);
+         this->priv_reinsert_block(*prev_block_info, prev_block_was_empty, real_num_node);
+         this->priv_deallocate_free_blocks(max_free_blocks, real_num_node, num_subblocks, real_block_alignment);
+      }
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+   }
+
+   void priv_reinsert_block(block_info_t &prev_block_info, const bool prev_block_was_empty, const size_type real_num_node)
+   {
+      //Cache the free nodes from the block
+      const size_type this_block_free_nodes = prev_block_info.free_nodes.size();
+      const bool is_full = this_block_free_nodes == real_num_node;
+
+      //Update free block count
+      m_totally_free_blocks += static_cast<size_type>(is_full);
+      if(prev_block_was_empty){
+         block_container_traits_t::insert_was_empty(m_block_container, prev_block_info, is_full);
+      }
+      else{
+         block_container_traits_t::reinsert_was_used(m_block_container, prev_block_info, is_full);
+      }
+   }
+
+   block_info_t *priv_block_from_node(void *node, const size_type real_block_alignment, AlignOnlyFalse) const
+   {
+      hdr_offset_holder *hdr_off_holder =
+         reinterpret_cast<hdr_offset_holder*>((std::size_t)node & size_type(~(real_block_alignment - 1)));
+      BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (real_block_alignment - 1)));
+      BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (real_block_alignment - 1)));
+      block_info_t *block = reinterpret_cast<block_info_t *>
+         (reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
+      BOOST_ASSERT(block->hdr_offset == 0);
+      return block;
+   }
+
+   block_info_t *priv_block_from_node(void *node, const size_type real_block_alignment, AlignOnlyTrue) const
+   {
+      return (block_info_t *)((std::size_t)node & std::size_t(~(real_block_alignment - 1)));
+   }
+
+   block_info_t *priv_block_from_node(void *node, const size_type real_block_alignment) const
+   {  return this->priv_block_from_node(node, real_block_alignment, IsAlignOnly());   }
+
+   //!Deallocates all used memory. Never throws
+   void priv_clear(const size_type num_subblocks, const size_type real_block_alignment, const size_type real_num_node)
+   {
+      #ifndef NDEBUG
+      block_iterator it    = m_block_container.begin();
+      block_iterator itend = m_block_container.end();
+      size_type n_free_nodes = 0;
+      for(; it != itend; ++it){
+         //Check for memory leak
+         BOOST_ASSERT(it->free_nodes.size() == real_num_node);
+         ++n_free_nodes;
+      }
+      BOOST_ASSERT(n_free_nodes == m_totally_free_blocks);
+      #endif
+      //Check for memory leaks
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+      multiallocation_chain chain;
+      m_block_container.clear_and_dispose(block_destroyer(this, chain, num_subblocks, real_block_alignment, real_num_node));
+      this->mp_segment_mngr_base->deallocate_many(chain);
+      m_totally_free_blocks = 0;
+      this->priv_invariants(real_num_node, num_subblocks, real_block_alignment);
+   }
+
+   public:
+   private_adaptive_node_pool_impl_common(segment_manager_base_type *segment_mngr_base)
+      //General purpose allocator
+   :  mp_segment_mngr_base(segment_mngr_base)
+   ,  m_block_container()
+   ,  m_totally_free_blocks(0)
+   {}
+
+   size_type num_free_nodes()
+   {
+      typedef typename block_container_t::const_iterator citerator;
+      size_type count = 0;
+      citerator it (m_block_container.begin()), itend(m_block_container.end());
+      for(; it != itend; ++it){
+         count += it->free_nodes.size();
+      }
+      return count;
+   }
+
+   void swap(private_adaptive_node_pool_impl_common &other)
+   {
+      std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+      std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
+      m_block_container.swap(other.m_block_container);
+   }
+
+   //!Returns the segment manager. Never throws
+   segment_manager_base_type* get_segment_manager_base()const
+   {  return boost::movelib::to_raw_pointer(mp_segment_mngr_base);  }
+};
+
+template< class SizeType
+        , std::size_t HdrSize
+        , std::size_t PayloadPerAllocation
+        , std::size_t RealNodeSize
+        , std::size_t NodesPerBlock
+        , std::size_t HdrOffsetSize
+        , std::size_t OverheadPercent
+        , bool AlignOnly>
+struct calculate_alignment_ct
+{
+   static const std::size_t alignment     = upper_power_of_2_ct<SizeType, HdrSize + RealNodeSize*NodesPerBlock>::value;
+   static const std::size_t num_subblocks = 0;
+   static const std::size_t real_num_node = (alignment - PayloadPerAllocation - HdrSize)/RealNodeSize;
+};
+
+template< class SizeType
+        , std::size_t HdrSize
+        , std::size_t PayloadPerAllocation
+        , std::size_t RealNodeSize
+        , std::size_t NodesPerBlock
+        , std::size_t HdrOffsetSize
+        , std::size_t OverheadPercent>
+struct calculate_alignment_ct
+   < SizeType
+   , HdrSize
+   , PayloadPerAllocation
+   , RealNodeSize
+   , NodesPerBlock
+   , HdrOffsetSize
+   , OverheadPercent
+   , false>
+{
+   typedef typename candidate_power_of_2_ct
+      < upper_power_of_2_ct<SizeType, HdrSize + PayloadPerAllocation + RealNodeSize>::value
+      , RealNodeSize
+      , PayloadPerAllocation
+      , NodesPerBlock
+      , HdrSize
+      , HdrOffsetSize
+      , OverheadPercent
+      >::type type;
+
+   static const std::size_t alignment     = type::alignment;
+   static const std::size_t num_subblocks = type::num_subblocks;
+   static const std::size_t real_num_node = type::real_num_node;
+};
+
+
+/////////////////////////////////////////////
+//
+//    private_adaptive_node_pool_impl_ct
+//
+/////////////////////////////////////////////
+template< class SegmentManagerBase
+        , std::size_t MaxFreeBlocks
+        , std::size_t NodeSize
+        , std::size_t NodesPerBlock
+        , std::size_t OverheadPercent
+        , unsigned int Flags>
+class private_adaptive_node_pool_impl_ct
+   : public private_adaptive_node_pool_impl_common<SegmentManagerBase, Flags>
+{
+   typedef private_adaptive_node_pool_impl_common<SegmentManagerBase, Flags> base_t;
+
+   //Non-copyable
+   private_adaptive_node_pool_impl_ct();
+   private_adaptive_node_pool_impl_ct(const private_adaptive_node_pool_impl_ct &);
+   private_adaptive_node_pool_impl_ct &operator=(const private_adaptive_node_pool_impl_ct &);
+
+   public:
+   typedef typename base_t::void_pointer              void_pointer;
+   typedef typename base_t::size_type                 size_type;
+   typedef typename base_t::multiallocation_chain     multiallocation_chain;
+   typedef typename base_t::segment_manager_base_type segment_manager_base_type;
+
+   static const typename base_t::size_type PayloadPerAllocation = base_t::PayloadPerAllocation;
+
+   //align_only
+   static const bool AlignOnly      = base_t::AlignOnly;
+
+   private:
+   static const size_type MaxAlign = base_t::MaxAlign;
+   static const size_type HdrSize  = base_t::HdrSize;
+   static const size_type HdrOffsetSize = base_t::HdrOffsetSize;
+
+   static const size_type RealNodeSize = lcm_ct<NodeSize, alignment_of<void_pointer>::value>::value;
+
+   typedef calculate_alignment_ct
+      < size_type, HdrSize, PayloadPerAllocation
+      , RealNodeSize, NodesPerBlock, HdrOffsetSize, OverheadPercent, AlignOnly> data_t;
+
+   //Round the size to a power of two value.
+   //This is the total memory size (including payload) that we want to
+   //allocate from the general-purpose allocator
+   static const size_type NumSubBlocks       = data_t::num_subblocks;
+   static const size_type RealNumNode        = data_t::real_num_node;
+   static const size_type RealBlockAlignment = data_t::alignment;
+
+   public:
+
+   //!Constructor from a segment manager. Never throws
+   private_adaptive_node_pool_impl_ct(typename base_t::segment_manager_base_type *segment_mngr_base)
+      //General purpose allocator
+   :  base_t(segment_mngr_base)
+   {}
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~private_adaptive_node_pool_impl_ct()
+   {  this->priv_clear(NumSubBlocks, data_t::alignment, RealNumNode);  }
+
+   size_type get_real_num_node() const
+   {  return RealNumNode; }
+
+   //!Allocates array of count elements. Can throw
+   void *allocate_node()
+   {
+      return this->priv_allocate_node
+         (MaxFreeBlocks, data_t::alignment, RealNodeSize, RealNumNode, NumSubBlocks);
+   }
+
+   //!Allocates n nodes.
+   //!Can throw
+   void allocate_nodes(const size_type n, multiallocation_chain &chain)
+   {
+      this->priv_allocate_nodes
+         (n, chain, MaxFreeBlocks, data_t::alignment, RealNodeSize, RealNumNode, NumSubBlocks);
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *pElem)
+   {
+      this->priv_deallocate_node(pElem, MaxFreeBlocks, RealNumNode, NumSubBlocks, RealBlockAlignment);
+   }
+
+   //!Deallocates a linked list of nodes. Never throws
+   void deallocate_nodes(multiallocation_chain &nodes)
+   {
+      this->priv_deallocate_nodes(nodes, MaxFreeBlocks, RealNumNode, NumSubBlocks, data_t::alignment);
+   }
+
+   void deallocate_free_blocks()
+   {  this->priv_deallocate_free_blocks(0, RealNumNode, NumSubBlocks, data_t::alignment);  }
+
+   //Deprecated, use deallocate_free_blocks
+   void deallocate_free_chunks()
+   {  this->priv_deallocate_free_blocks(0, RealNumNode, NumSubBlocks, data_t::alignment);   }
+};
+
+/////////////////////////////////////////////
+//
+//    private_adaptive_node_pool_impl_rt
+//
+/////////////////////////////////////////////
+template<class SizeType>
+struct private_adaptive_node_pool_impl_rt_data
+{
+   typedef SizeType size_type;
+
+   private_adaptive_node_pool_impl_rt_data(size_type max_free_blocks, size_type real_node_size)
+      : m_max_free_blocks(max_free_blocks), m_real_node_size(real_node_size)
+      , m_real_block_alignment(), m_num_subblocks(), m_real_num_node()
+   {}
+
+   const size_type m_max_free_blocks;
+   const size_type m_real_node_size;
+   //Round the size to a power of two value.
+   //This is the total memory size (including payload) that we want to
+   //allocate from the general-purpose allocator
+   size_type m_real_block_alignment;
+   size_type m_num_subblocks;
+   //This is the real number of nodes per block
+   size_type m_real_num_node;
+};
+
+
+template<class SegmentManagerBase, unsigned int Flags>
+class private_adaptive_node_pool_impl_rt
+   : private private_adaptive_node_pool_impl_rt_data<typename SegmentManagerBase::size_type>
+   , public  private_adaptive_node_pool_impl_common<SegmentManagerBase, Flags> 
+{
+   typedef private_adaptive_node_pool_impl_common<SegmentManagerBase, Flags> impl_t;
+   typedef private_adaptive_node_pool_impl_rt_data<typename SegmentManagerBase::size_type> data_t;
+
+   //Non-copyable
+   private_adaptive_node_pool_impl_rt();
+   private_adaptive_node_pool_impl_rt(const private_adaptive_node_pool_impl_rt &);
+   private_adaptive_node_pool_impl_rt &operator=(const private_adaptive_node_pool_impl_rt &);
+
+   protected:
+
+   typedef typename impl_t::void_pointer           void_pointer;
+   typedef typename impl_t::size_type              size_type;
+   typedef typename impl_t::multiallocation_chain  multiallocation_chain;
+
+   static const typename impl_t::size_type PayloadPerAllocation = impl_t::PayloadPerAllocation;
+
+   //Flags
+   //align_only
+   static const bool AlignOnly      = impl_t::AlignOnly;
+
+   static const size_type HdrSize  = impl_t::HdrSize;
+   static const size_type HdrOffsetSize = impl_t::HdrOffsetSize;
+
+   public:
+
+   //!Segment manager typedef
+   typedef SegmentManagerBase                 segment_manager_base_type;
+
+   //!Constructor from a segment manager. Never throws
+   private_adaptive_node_pool_impl_rt
+      ( segment_manager_base_type *segment_mngr_base
+      , size_type node_size
+      , size_type nodes_per_block
+      , size_type max_free_blocks
+      , unsigned char overhead_percent
+      )
+   :  data_t(max_free_blocks, lcm(node_size, size_type(alignment_of<void_pointer>::value)))
+   ,  impl_t(segment_mngr_base)
+   {
+      if(AlignOnly){
+         this->m_real_block_alignment = upper_power_of_2(HdrSize + this->m_real_node_size*nodes_per_block);
+         this->m_real_num_node = (this->m_real_block_alignment - PayloadPerAllocation - HdrSize)/this->m_real_node_size;
+      }
+      else{
+         candidate_power_of_2_rt ( upper_power_of_2(HdrSize + PayloadPerAllocation + this->m_real_node_size)
+                                 , this->m_real_node_size
+                                 , PayloadPerAllocation
+                                 , nodes_per_block
+                                 , HdrSize
+                                 , HdrOffsetSize
+                                 , overhead_percent
+                                 , this->m_real_block_alignment
+                                 , this->m_num_subblocks
+                                 , this->m_real_num_node);
+      }
+   }
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~private_adaptive_node_pool_impl_rt()
+   {  this->priv_clear(this->m_num_subblocks, this->m_real_block_alignment, this->m_real_num_node);  }
+
+   size_type get_real_num_node() const
+   {  return this->m_real_num_node; }
+
+   //!Allocates array of count elements. Can throw
+   void *allocate_node()
+   {
+      return this->priv_allocate_node
+         (this->m_max_free_blocks, this->m_real_block_alignment, this->m_real_node_size, this->m_real_num_node, this->m_num_subblocks);
+   }
+
+   //!Allocates n nodes.
+   //!Can throw
+   void allocate_nodes(const size_type n, multiallocation_chain &chain)
+   {
+
+      this->priv_allocate_nodes
+         (n, chain, this->m_max_free_blocks, this->m_real_block_alignment, this->m_real_node_size, this->m_real_num_node, this->m_num_subblocks);
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *pElem)
+   {
+      this->priv_deallocate_node(pElem, this->m_max_free_blocks, this->m_real_num_node, this->m_num_subblocks, this->m_real_block_alignment);
+   }
+
+   //!Deallocates a linked list of nodes. Never throws
+   void deallocate_nodes(multiallocation_chain &nodes)
+   {
+      this->priv_deallocate_nodes(nodes, this->m_max_free_blocks, this->m_real_num_node, this->m_num_subblocks, this->m_real_block_alignment);
+   }
+
+   void deallocate_free_blocks()
+   {  this->priv_deallocate_free_blocks(0, this->m_real_num_node, this->m_num_subblocks, this->m_real_block_alignment);  }
+
+   //Deprecated, use deallocate_free_blocks
+   void deallocate_free_chunks()
+   {  this->priv_deallocate_free_blocks(0, this->m_real_num_node, this->m_num_subblocks, this->m_real_block_alignment);   }
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/include/boost/container/detail/addressof.hpp b/include/boost/container/detail/addressof.hpp
new file mode 100644
index 0000000..b3b8a4d
--- /dev/null
+++ b/include/boost/container/detail/addressof.hpp
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_DETAIL_ADDRESSOF_HPP
+#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template <typename T>
+BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj)
+{
+   return static_cast<T*>(
+      static_cast<void*>(
+         const_cast<char*>(
+            &reinterpret_cast<const volatile char&>(obj)
+   )));
+}
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
diff --git a/include/boost/container/detail/advanced_insert_int.hpp b/include/boost/container/detail/advanced_insert_int.hpp
new file mode 100644
index 0000000..fc8a33a
--- /dev/null
+++ b/include/boost/container/detail/advanced_insert_int.hpp
@@ -0,0 +1,495 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2013. 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_ADVANCED_INSERT_INT_HPP
+#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/copy_move_algo.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+// move
+#include <boost/move/utility_core.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+
+namespace boost { namespace container { namespace dtl {
+
+template<class Allocator, class FwdIt, class Iterator>
+struct move_insert_range_proxy
+{
+   typedef typename allocator_traits<Allocator>::size_type size_type;
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+
+   explicit move_insert_range_proxy(FwdIt first)
+      :  first_(first)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
+   {
+      this->first_ = ::boost::container::uninitialized_move_alloc_n_source
+         (a, this->first_, n, p);
+   }
+
+   void copy_n_and_update(Allocator &, Iterator p, size_type n)
+   {
+      this->first_ = ::boost::container::move_n_source(this->first_, n, p);
+   }
+
+   FwdIt first_;
+};
+
+
+template<class Allocator, class FwdIt, class Iterator>
+struct insert_range_proxy
+{
+   typedef typename allocator_traits<Allocator>::size_type size_type;
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+
+   explicit insert_range_proxy(FwdIt first)
+      :  first_(first)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
+   {
+      this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
+   }
+
+   void copy_n_and_update(Allocator &, Iterator p, size_type n)
+   {
+      this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
+   }
+
+   FwdIt first_;
+};
+
+
+template<class Allocator, class Iterator>
+struct insert_n_copies_proxy
+{
+   typedef typename allocator_traits<Allocator>::size_type size_type;
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+
+   explicit insert_n_copies_proxy(const value_type &v)
+      :  v_(v)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {  boost::container::uninitialized_fill_alloc_n(a, v_, n, p);  }
+
+   void copy_n_and_update(Allocator &, Iterator p, size_type n) const
+   {
+      for (; 0 < n; --n, ++p){
+         *p = v_;
+      }
+   }
+
+   const value_type &v_;
+};
+
+template<class Allocator, class Iterator>
+struct insert_value_initialized_n_proxy
+{
+   typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
+   typedef typename allocator_traits<Allocator>::size_type size_type;
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {  boost::container::uninitialized_value_init_alloc_n(a, n, p);  }
+
+   void copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {
+      for (; 0 < n; --n, ++p){
+         typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type stor;
+         value_type &v = *static_cast<value_type *>(static_cast<void *>(stor.data));
+         alloc_traits::construct(a, &v);
+         value_destructor<Allocator> on_exit(a, v); (void)on_exit;
+         *p = ::boost::move(v);
+      }
+   }
+};
+
+template<class Allocator, class Iterator>
+struct insert_default_initialized_n_proxy
+{
+   typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
+   typedef typename allocator_traits<Allocator>::size_type size_type;
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {  boost::container::uninitialized_default_init_alloc_n(a, n, p);  }
+
+   void copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {
+      if(!is_pod<value_type>::value){
+         for (; 0 < n; --n, ++p){
+            typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type stor;
+            value_type &v = *static_cast<value_type *>(static_cast<void *>(stor.data));
+            alloc_traits::construct(a, &v, default_init);
+            value_destructor<Allocator> on_exit(a, v); (void)on_exit;
+            *p = ::boost::move(v);
+         }
+      }
+   }
+};
+
+template<class Allocator, class Iterator>
+struct insert_copy_proxy
+{
+   typedef boost::container::allocator_traits<Allocator> alloc_traits;
+   typedef typename alloc_traits::size_type size_type;
+   typedef typename alloc_traits::value_type value_type;
+
+   explicit insert_copy_proxy(const value_type &v)
+      :  v_(v)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {
+      BOOST_ASSERT(n == 1);  (void)n;
+      alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
+   }
+
+   void copy_n_and_update(Allocator &, Iterator p, size_type n) const
+   {
+      BOOST_ASSERT(n == 1);  (void)n;
+      *p = v_;
+   }
+
+   const value_type &v_;
+};
+
+
+template<class Allocator, class Iterator>
+struct insert_move_proxy
+{
+   typedef boost::container::allocator_traits<Allocator> alloc_traits;
+   typedef typename alloc_traits::size_type size_type;
+   typedef typename alloc_traits::value_type value_type;
+
+   explicit insert_move_proxy(value_type &v)
+      :  v_(v)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
+   {
+      BOOST_ASSERT(n == 1);  (void)n;
+      alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) );
+   }
+
+   void copy_n_and_update(Allocator &, Iterator p, size_type n) const
+   {
+      BOOST_ASSERT(n == 1);  (void)n;
+      *p = ::boost::move(v_);
+   }
+
+   value_type &v_;
+};
+
+template<class It, class Allocator>
+insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
+{
+   return insert_move_proxy<Allocator, It>(v);
+}
+
+template<class It, class Allocator>
+insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
+{
+   return insert_copy_proxy<Allocator, It>(v);
+}
+
+}}}   //namespace boost { namespace container { namespace dtl {
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#include <boost/container/detail/variadic_templates_tools.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class Allocator, class Iterator, class ...Args>
+struct insert_nonmovable_emplace_proxy
+{
+   typedef boost::container::allocator_traits<Allocator>   alloc_traits;
+   typedef typename alloc_traits::size_type        size_type;
+   typedef typename alloc_traits::value_type       value_type;
+
+   typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+   explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
+      : args_(args...)
+   {}
+
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
+   {  this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n);  }
+
+   private:
+   template<std::size_t ...IdxPack>
+   void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
+   {
+      BOOST_ASSERT(n == 1); (void)n;
+      alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
+   }
+
+   protected:
+   tuple<Args&...> args_;
+};
+
+template<class Allocator, class Iterator, class ...Args>
+struct insert_emplace_proxy
+   :  public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
+{
+   typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
+   typedef boost::container::allocator_traits<Allocator>   alloc_traits;
+   typedef typename base_t::value_type             value_type;
+   typedef typename base_t::size_type              size_type;
+   typedef typename base_t::index_tuple_t          index_tuple_t;
+
+   explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
+      : base_t(::boost::forward<Args>(args)...)
+   {}
+
+   void copy_n_and_update(Allocator &a, Iterator p, size_type n)
+   {  this->priv_copy_some_and_update(a, index_tuple_t(), p, n);  }
+
+   private:
+
+   template<std::size_t ...IdxPack>
+   void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
+   {
+      BOOST_ASSERT(n ==1); (void)n;
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
+      value_type *vp = static_cast<value_type *>(static_cast<void *>(v.data));
+      alloc_traits::construct(a, vp,
+         ::boost::forward<Args>(get<IdxPack>(this->args_))...);
+      BOOST_TRY{
+         *p = ::boost::move(*vp);
+      }
+      BOOST_CATCH(...){
+         alloc_traits::destroy(a, vp);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+      alloc_traits::destroy(a, vp);
+   }
+};
+
+//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+   : public insert_move_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
+   : insert_move_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
+//compiler error C2752 ("more than one partial specialization matches").
+//Any problem is solvable with an extra layer of indirection? ;-)
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator
+   , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
+   >
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator
+   , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
+   >
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+}}}   //namespace boost { namespace container { namespace dtl {
+
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#include <boost/container/detail/value_init.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
+template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+struct insert_nonmovable_emplace_proxy##N\
+{\
+   typedef boost::container::allocator_traits<Allocator> alloc_traits;\
+   typedef typename alloc_traits::size_type size_type;\
+   typedef typename alloc_traits::value_type value_type;\
+   \
+   explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
+      BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
+   \
+   void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
+   {\
+      BOOST_ASSERT(n == 1); (void)n;\
+      alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
+   }\
+   \
+   void copy_n_and_update(Allocator &, Iterator, size_type)\
+   {  BOOST_ASSERT(false);   }\
+   \
+   protected:\
+   BOOST_MOVE_MREF##N\
+};\
+\
+template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+struct insert_emplace_proxy_arg##N\
+   : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
+{\
+   typedef insert_nonmovable_emplace_proxy##N\
+      < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
+   typedef typename base_t::value_type value_type;\
+   typedef typename base_t::size_type size_type;\
+   typedef boost::container::allocator_traits<Allocator> alloc_traits;\
+   \
+   explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
+      : base_t(BOOST_MOVE_FWD##N){}\
+   \
+   void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
+   {\
+      BOOST_ASSERT(n == 1); (void)n;\
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+      BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
+      value_type *vp = static_cast<value_type *>(static_cast<void *>(v.data));\
+      alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
+      BOOST_TRY{\
+         *p = ::boost::move(*vp);\
+      }\
+      BOOST_CATCH(...){\
+         alloc_traits::destroy(a, vp);\
+         BOOST_RETHROW\
+      }\
+      BOOST_CATCH_END\
+      alloc_traits::destroy(a, vp);\
+   }\
+};\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
+#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
+   : public insert_move_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_move_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+#else //e.g. MSVC10 & MSVC11
+
+//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+   : public insert_move_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
+   : insert_move_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
+//compiler error C2752 ("more than one partial specialization matches").
+//Any problem is solvable with an extra layer of indirection? ;-)
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator
+   , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
+   >
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator
+   , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
+   >
+   : public insert_copy_proxy<Allocator, Iterator>
+{
+   explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+   : insert_copy_proxy<Allocator, Iterator>(v)
+   {}
+};
+
+#endif
+
+}}}   //namespace boost { namespace container { namespace dtl {
+
+#endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
diff --git a/include/boost/container/detail/algorithm.hpp b/include/boost/container/detail/algorithm.hpp
new file mode 100644
index 0000000..1184422
--- /dev/null
+++ b/include/boost/container/detail/algorithm.hpp
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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_DETAIL_ALGORITHM_HPP
+#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/intrusive/detail/algorithm.hpp>
+
+namespace boost {
+namespace container {
+
+using boost::intrusive::algo_equal;
+using boost::intrusive::algo_lexicographical_compare;
+
+template<class Func>
+class binder1st
+{
+   public:
+	typedef typename Func::second_argument_type  argument_type;
+	typedef typename Func::result_type           result_type;
+
+	binder1st(const Func& func, const typename Func::first_argument_type& arg)
+   	: op(func), value(arg)
+	{}
+
+	result_type operator()(const argument_type& arg) const
+   {	return op(value, arg);  }
+
+	result_type operator()(argument_type& arg) const
+   {  return op(value, arg);   }
+
+   private:
+	Func op;
+	typename Func::first_argument_type value;
+};
+
+template<class Func, class T> 
+inline binder1st<Func> bind1st(const Func& func, const T& arg)
+{	return boost::container::binder1st<Func>(func, arg);  }
+
+template<class Func>
+class binder2nd
+{
+   public:
+	typedef typename Func::first_argument_type   argument_type;
+	typedef typename Func::result_type           result_type;
+
+	binder2nd(const Func& func, const typename Func::second_argument_type& arg)
+	   : op(func), value(arg)
+   {}
+
+	result_type operator()(const argument_type& arg) const
+   {  return op(arg, value);  }
+
+	result_type operator()(argument_type& arg) const
+	{  return op(arg, value);  }
+
+   private:
+	Func op;
+	typename Func::second_argument_type value;
+};
+
+template<class Func, class T>
+inline binder2nd<Func> bind2nd(const Func& func, const T& arg)
+{
+   return (boost::container::binder2nd<Func>(func, arg));
+}
+
+template<class Func>
+class unary_negate
+{
+   public:
+   typedef typename Func::argument_type   argument_type;
+   typedef typename Func::result_type     result_type;
+
+	explicit unary_negate(const Func& func)
+		: m_func(func)
+   {}
+
+	bool operator()(const typename Func::argument_type& arg) const
+	{  return !m_func(arg);  }
+
+   private:
+	Func m_func;
+};
+
+template<class Func> inline
+unary_negate<Func> not1(const Func& func)
+{
+   return boost::container::unary_negate<Func>(func);
+}
+
+template<class InputIt, class UnaryPredicate>
+InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
+{
+   for (; first != last; ++first) {
+      if (p(*first)) {
+         return first;
+      }
+   }
+   return last;
+}
+
+template<class InputIt, class ForwardIt, class BinaryPredicate>
+InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p)
+{
+   for (; first1 != last1; ++first1) {
+      for (ForwardIt it = first2; it != last2; ++it) {
+         if (p(*first1, *it)) {
+            return first1;
+         }
+      }
+   }
+   return last1;
+}
+
+template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
+ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
+                        ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p)
+{
+   for (; ; ++first1) {
+      ForwardIt1 it = first1;
+      for (ForwardIt2 it2 = first2; ; ++it, ++it2) {
+         if (it2 == last2) {
+            return first1;
+         }
+         if (it == last1) {
+            return last1;
+         }
+         if (!p(*it, *it2)) {
+            break;
+         }
+      }
+   }
+}
+
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
diff --git a/include/boost/container/detail/alloc_helpers.hpp b/include/boost/container/detail/alloc_helpers.hpp
new file mode 100644
index 0000000..57c59e4
--- /dev/null
+++ b/include/boost/container/detail/alloc_helpers.hpp
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_DETAIL_ALLOC_TRAITS_HPP
+#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class AllocatorType>
+inline void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
+   BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
+{  boost::adl_move_swap(l, r);   }
+
+template<class AllocatorType>
+inline void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type)
+   BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type)
+{  l = r;   }
+
+template<class AllocatorType>
+inline void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
+   BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
+{  l = ::boost::move(r);   }
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
diff --git a/include/boost/container/detail/alloc_lib.h b/include/boost/container/detail/alloc_lib.h
new file mode 100644
index 0000000..950ff72
--- /dev/null
+++ b/include/boost/container/detail/alloc_lib.h
@@ -0,0 +1,314 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_ALLOC_LIB_EXT_H
+#define BOOST_CONTAINER_ALLOC_LIB_EXT_H
+
+#include <stddef.h>
+
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable : 4127)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!An forward iterator to traverse the elements of a memory chain container.*/
+typedef struct multialloc_node_impl
+{
+   struct multialloc_node_impl *next_node_ptr;
+} boost_cont_memchain_node;
+
+
+/*!An forward iterator to traverse the elements of a memory chain container.*/
+typedef struct multialloc_it_impl
+{
+   boost_cont_memchain_node *node_ptr;
+} boost_cont_memchain_it;
+
+/*!Memory chain: A container holding memory portions allocated by boost_cont_multialloc_nodes
+   and boost_cont_multialloc_arrays functions.*/
+typedef struct boost_cont_memchain_impl
+{
+   size_t                   num_mem;
+   boost_cont_memchain_node  root_node;
+   boost_cont_memchain_node *last_node_ptr;
+} boost_cont_memchain;
+
+/*!Advances the iterator one position so that it points to the next element in the memory chain*/
+#define BOOST_CONTAINER_MEMIT_NEXT(IT)         (IT.node_ptr = IT.node_ptr->next_node_ptr)
+
+/*!Returns the address of the memory chain currently pointed by the iterator*/
+#define BOOST_CONTAINER_MEMIT_ADDR(IT)      ((void*)IT.node_ptr)
+
+/*!Initializer for an iterator pointing to the position before the first element*/
+#define BOOST_CONTAINER_MEMCHAIN_BEFORE_BEGIN_IT(PMEMCHAIN)   { &((PMEMCHAIN)->root_node) }
+
+/*!Initializer for an iterator pointing to the first element*/
+#define BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(PMEMCHAIN)   {(PMEMCHAIN)->root_node.next_node_ptr }
+
+/*!Initializer for an iterator pointing to the last element*/
+#define BOOST_CONTAINER_MEMCHAIN_LAST_IT(PMEMCHAIN)    {(PMEMCHAIN)->last_node_ptr }
+
+/*!Initializer for an iterator pointing to one past the last element (end iterator)*/
+#define BOOST_CONTAINER_MEMCHAIN_END_IT(PMEMCHAIN)     {(boost_cont_memchain_node *)0 }
+
+/*!True if IT is the end iterator, false otherwise*/
+#define BOOST_CONTAINER_MEMCHAIN_IS_END_IT(PMEMCHAIN, IT) (!(IT).node_ptr)
+
+/*!The address of the first memory portion hold by the memory chain*/
+#define BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(PMEMCHAIN)((void*)((PMEMCHAIN)->root_node.next_node_ptr))
+
+/*!The address of the last memory portion hold by the memory chain*/
+#define BOOST_CONTAINER_MEMCHAIN_LASTMEM(PMEMCHAIN) ((void*)((PMEMCHAIN)->last_node_ptr))
+
+/*!The number of memory portions hold by the memory chain*/
+#define BOOST_CONTAINER_MEMCHAIN_SIZE(PMEMCHAIN) ((PMEMCHAIN)->num_mem)
+
+/*!Initializes the memory chain from the first memory portion, the last memory
+   portion and number of portions obtained from another memory chain*/
+#define BOOST_CONTAINER_MEMCHAIN_INIT_FROM(PMEMCHAIN, FIRST, LAST, NUM)\
+   (PMEMCHAIN)->last_node_ptr = (boost_cont_memchain_node *)(LAST), \
+   (PMEMCHAIN)->root_node.next_node_ptr  = (boost_cont_memchain_node *)(FIRST), \
+   (PMEMCHAIN)->num_mem  = (NUM);\
+/**/
+
+/*!Default initializes a memory chain. Postconditions: begin iterator is end iterator,
+   the number of portions is zero.*/
+#define BOOST_CONTAINER_MEMCHAIN_INIT(PMEMCHAIN)\
+   ((PMEMCHAIN)->root_node.next_node_ptr = 0, (PMEMCHAIN)->last_node_ptr = &((PMEMCHAIN)->root_node), (PMEMCHAIN)->num_mem = 0)\
+/**/
+
+/*!True if the memory chain is empty (holds no memory portions*/
+#define BOOST_CONTAINER_MEMCHAIN_EMPTY(PMEMCHAIN)\
+   ((PMEMCHAIN)->num_mem == 0)\
+/**/
+
+/*!Inserts a new memory portions in the front of the chain*/
+#define BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(PMEMCHAIN, MEM)\
+   do{\
+      boost_cont_memchain *____chain____ = (PMEMCHAIN);\
+      boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
+      ____chain____->last_node_ptr->next_node_ptr = ____tmp_mem____;\
+      ____tmp_mem____->next_node_ptr = 0;\
+      ____chain____->last_node_ptr = ____tmp_mem____;\
+      ++____chain____->num_mem;\
+   }while(0)\
+/**/
+
+/*!Inserts a new memory portions in the back of the chain*/
+#define BOOST_CONTAINER_MEMCHAIN_PUSH_FRONT(PMEMCHAIN, MEM)\
+   do{\
+      boost_cont_memchain *____chain____ = (PMEMCHAIN);\
+      boost_cont_memchain_node *____tmp_mem____   = (boost_cont_memchain_node *)(MEM);\
+      boost_cont_memchain *____root____  = &((PMEMCHAIN)->root_node);\
+      if(!____chain____->root_node.next_node_ptr){\
+         ____chain____->last_node_ptr = ____tmp_mem____;\
+      }\
+      boost_cont_memchain_node *____old_first____ = ____root____->next_node_ptr;\
+      ____tmp_mem____->next_node_ptr = ____old_first____;\
+      ____root____->next_node_ptr = ____tmp_mem____;\
+      ++____chain____->num_mem;\
+   }while(0)\
+/**/
+
+/*!Erases the memory portion after the portion pointed by BEFORE_IT from the memory chain*/
+/*!Precondition: BEFORE_IT must be a valid iterator of the memory chain and it can't be the end iterator*/
+#define BOOST_CONTAINER_MEMCHAIN_ERASE_AFTER(PMEMCHAIN, BEFORE_IT)\
+   do{\
+      boost_cont_memchain *____chain____ = (PMEMCHAIN);\
+      boost_cont_memchain_node *____prev_node____  = (BEFORE_IT).node_ptr;\
+      boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
+      if(____chain____->last_node_ptr == ____erase_node____){\
+         ____chain____->last_node_ptr = &____chain____->root_node;\
+      }\
+      ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
+      --____chain____->num_mem;\
+   }while(0)\
+/**/
+
+/*!Erases the first portion from the memory chain.
+   Precondition: the memory chain must not be empty*/
+#define BOOST_CONTAINER_MEMCHAIN_POP_FRONT(PMEMCHAIN)\
+   do{\
+      boost_cont_memchain *____chain____ = (PMEMCHAIN);\
+      boost_cont_memchain_node *____prev_node____  = &____chain____->root_node;\
+      boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
+      if(____chain____->last_node_ptr == ____erase_node____){\
+         ____chain____->last_node_ptr = &____chain____->root_node;\
+      }\
+      ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
+      --____chain____->num_mem;\
+   }while(0)\
+/**/
+
+/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
+/*
+#define BOOST_CONTAINER_MEMCHAIN_SPLICE_BACK(PMEMCHAIN, PMEMCHAIN2)\
+   do{\
+      boost_cont_memchain *____chain____  = (PMEMCHAIN);\
+      boost_cont_memchain *____chain2____ = (PMEMCHAIN2);\
+      if(!____chain2____->root_node.next_node_ptr){\
+         break;\
+      }\
+      else if(!____chain____->first_mem){\
+         ____chain____->first_mem  = ____chain2____->first_mem;\
+         ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
+         ____chain____->num_mem  = ____chain2____->num_mem;\
+         BOOST_CONTAINER_MEMCHAIN_INIT(*____chain2____);\
+      }\
+      else{\
+         ____chain____->last_node_ptr->next_node_ptr = ____chain2____->first_mem;\
+         ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
+         ____chain____->num_mem += ____chain2____->num_mem;\
+      }\
+   }while(0)\*/
+/**/
+
+/*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
+#define BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(PMEMCHAIN, BEFORE_IT, FIRST, BEFORELAST, NUM)\
+   do{\
+      boost_cont_memchain *____chain____  = (PMEMCHAIN);\
+      boost_cont_memchain_node *____pnode____  = (BEFORE_IT).node_ptr;\
+      boost_cont_memchain_node *____next____   = ____pnode____->next_node_ptr;\
+      boost_cont_memchain_node *____first____  = (boost_cont_memchain_node *)(FIRST);\
+      boost_cont_memchain_node *____blast____  = (boost_cont_memchain_node *)(BEFORELAST);\
+      size_t ____num____ = (NUM);\
+      if(!____num____){\
+         break;\
+      }\
+      if(____pnode____ == ____chain____->last_node_ptr){\
+         ____chain____->last_node_ptr = ____blast____;\
+      }\
+      ____pnode____->next_node_ptr  = ____first____;\
+      ____blast____->next_node_ptr  = ____next____;\
+      ____chain____->num_mem  += ____num____;\
+   }while(0)\
+/**/
+
+/*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
+   must be contiguous.*/
+#define DL_MULTIALLOC_ALL_CONTIGUOUS        ((size_t)(-1))
+
+/*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
+   should be selected by those functions.*/
+#define DL_MULTIALLOC_DEFAULT_CONTIGUOUS    ((size_t)(0))
+
+typedef struct boost_cont_malloc_stats_impl
+{
+   size_t max_system_bytes;
+   size_t system_bytes;
+   size_t in_use_bytes;
+} boost_cont_malloc_stats_t;
+
+typedef unsigned int allocation_type;
+
+enum
+{
+   // constants for allocation commands
+   BOOST_CONTAINER_ALLOCATE_NEW          = 0X01,
+   BOOST_CONTAINER_EXPAND_FWD            = 0X02,
+   BOOST_CONTAINER_EXPAND_BWD            = 0X04,
+   BOOST_CONTAINER_SHRINK_IN_PLACE       = 0X08,
+   BOOST_CONTAINER_NOTHROW_ALLOCATION    = 0X10,
+//   BOOST_CONTAINER_ZERO_MEMORY           = 0X20,
+   BOOST_CONTAINER_TRY_SHRINK_IN_PLACE   = 0X40,
+   BOOST_CONTAINER_EXPAND_BOTH           = BOOST_CONTAINER_EXPAND_FWD | BOOST_CONTAINER_EXPAND_BWD,
+   BOOST_CONTAINER_EXPAND_OR_NEW         = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH
+};
+
+//#define BOOST_CONTAINERDLMALLOC__FOOTERS
+#ifndef BOOST_CONTAINERDLMALLOC__FOOTERS
+enum {   BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)   };
+#else
+enum {   BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2   };
+#endif
+
+typedef struct boost_cont_command_ret_impl
+{
+   void *first;
+   int   second;
+}boost_cont_command_ret_t;
+
+size_t boost_cont_size(const void *p);
+
+void* boost_cont_malloc(size_t bytes);
+
+void  boost_cont_free(void* mem);
+
+void* boost_cont_memalign(size_t bytes, size_t alignment);
+
+int boost_cont_multialloc_nodes
+   (size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
+
+int boost_cont_multialloc_arrays
+   (size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
+
+void boost_cont_multidealloc(boost_cont_memchain *pchain);
+
+size_t boost_cont_footprint();
+
+size_t boost_cont_allocated_memory();
+
+size_t boost_cont_chunksize(const void *p);
+
+int boost_cont_all_deallocated();
+
+boost_cont_malloc_stats_t boost_cont_malloc_stats();
+
+size_t boost_cont_in_use_memory();
+
+int boost_cont_trim(size_t pad);
+
+int boost_cont_mallopt(int parameter_number, int parameter_value);
+
+int boost_cont_grow
+   (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
+
+int boost_cont_shrink
+   (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
+
+void* boost_cont_alloc
+   (size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
+
+int boost_cont_malloc_check();
+
+boost_cont_command_ret_t boost_cont_allocation_command
+   ( allocation_type command
+   , size_t sizeof_object
+   , size_t limit_objects
+   , size_t preferred_objects
+   , size_t *received_objects
+   , void *reuse_ptr
+   );
+
+void *boost_cont_sync_create();
+
+void boost_cont_sync_destroy(void *sync);
+
+int boost_cont_sync_lock(void *sync);
+
+void boost_cont_sync_unlock(void *sync);
+
+int boost_cont_global_sync_lock();
+
+void boost_cont_global_sync_unlock();
+
+#ifdef __cplusplus
+}  //extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+
+#endif   //#define BOOST_CONTAINERDLMALLOC__EXT_H
diff --git a/include/boost/container/detail/allocation_type.hpp b/include/boost/container/detail/allocation_type.hpp
new file mode 100644
index 0000000..1e8aa67
--- /dev/null
+++ b/include/boost/container/detail/allocation_type.hpp
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_ALLOCATION_TYPE_HPP
+#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+enum allocation_type_v
+{
+   // constants for allocation commands
+   allocate_new_v   = 0x01,
+   expand_fwd_v     = 0x02,
+   expand_bwd_v     = 0x04,
+//   expand_both    = expand_fwd | expand_bwd,
+//   expand_or_new  = allocate_new | expand_both,
+   shrink_in_place_v = 0x08,
+   nothrow_allocation_v = 0x10,
+   zero_memory_v = 0x20,
+   try_shrink_in_place_v = 0x40
+};
+
+typedef unsigned int allocation_type;
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+static const allocation_type allocate_new       = (allocation_type)allocate_new_v;
+static const allocation_type expand_fwd         = (allocation_type)expand_fwd_v;
+static const allocation_type expand_bwd         = (allocation_type)expand_bwd_v;
+static const allocation_type shrink_in_place    = (allocation_type)shrink_in_place_v;
+static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
+static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
+static const allocation_type zero_memory        = (allocation_type)zero_memory_v;
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_ALLOCATION_TYPE_HPP
diff --git a/include/boost/container/detail/allocator_version_traits.hpp b/include/boost/container/detail/allocator_version_traits.hpp
new file mode 100644
index 0000000..18460bd
--- /dev/null
+++ b/include/boost/container/detail/allocator_version_traits.hpp
@@ -0,0 +1,162 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2013. 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_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
+#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/allocator_traits.hpp>             //allocator_traits
+#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
+#include <boost/container/detail/version_type.hpp>          //version_type
+#include <boost/container/detail/allocation_type.hpp>       //allocation_type
+#include <boost/container/detail/mpl.hpp>                   //integral_constant
+#include <boost/intrusive/pointer_traits.hpp>               //pointer_traits
+#include <boost/core/no_exceptions_support.hpp>             //BOOST_TRY
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class Allocator, unsigned Version = boost::container::dtl::version<Allocator>::value>
+struct allocator_version_traits
+{
+   typedef ::boost::container::dtl::integral_constant
+      <unsigned, Version> alloc_version;
+
+   typedef typename Allocator::multiallocation_chain multiallocation_chain;
+
+   typedef typename boost::container::allocator_traits<Allocator>::pointer    pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::size_type  size_type;
+
+   //Node allocation interface
+   static pointer allocate_one(Allocator &a)
+   {  return a.allocate_one();   }
+
+   static void deallocate_one(Allocator &a, const pointer &p)
+   {  a.deallocate_one(p);   }
+
+   static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
+   {  return a.allocate_individual(n, m);   }
+
+   static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
+   {  a.deallocate_individual(holder);   }
+
+   static pointer allocation_command(Allocator &a, allocation_type command,
+                         size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
+   {  return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);  }
+};
+
+template<class Allocator>
+struct allocator_version_traits<Allocator, 1>
+{
+   typedef ::boost::container::dtl::integral_constant
+      <unsigned, 1> alloc_version;
+
+   typedef typename boost::container::allocator_traits<Allocator>::pointer    pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::size_type  size_type;
+   typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
+
+   typedef typename boost::intrusive::pointer_traits<pointer>::
+         template rebind_pointer<void>::type                void_ptr;
+   typedef dtl::basic_multiallocation_chain
+      <void_ptr>                                            multialloc_cached_counted;
+   typedef boost::container::dtl::
+      transform_multiallocation_chain
+         < multialloc_cached_counted, value_type>           multiallocation_chain;
+
+   //Node allocation interface
+   static pointer allocate_one(Allocator &a)
+   {  return a.allocate(1);   }
+
+   static void deallocate_one(Allocator &a, const pointer &p)
+   {  a.deallocate(p, 1);   }
+
+   static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
+   {
+      size_type n = holder.size();
+      typename multiallocation_chain::iterator it = holder.begin();
+      while(n--){
+         pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
+         ++it;
+         a.deallocate(p, 1);
+      }
+   }
+
+   struct allocate_individual_rollback
+   {
+      allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
+         : mr_a(a), mp_chain(&chain)
+      {}
+
+      ~allocate_individual_rollback()
+      {
+         if(mp_chain)
+            allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
+      }
+
+      void release()
+      {
+         mp_chain = 0;
+      }
+
+      Allocator &mr_a;
+      multiallocation_chain * mp_chain;
+   };
+
+   static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
+   {
+      allocate_individual_rollback rollback(a, m);
+      while(n--){
+         m.push_front(a.allocate(1));
+      }
+      rollback.release();
+   }
+
+   static pointer allocation_command(Allocator &a, allocation_type command,
+                         size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
+   {
+      pointer ret = pointer();
+      if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
+         throw_logic_error("version 1 allocator without allocate_new flag");
+      }
+      else{
+         BOOST_TRY{
+            ret = a.allocate(prefer_in_recvd_out_size);
+         }
+         BOOST_CATCH(...){
+            if(!(command & nothrow_allocation)){
+               BOOST_RETHROW
+            }
+         }
+         BOOST_CATCH_END
+         reuse = pointer();
+      }
+      return ret;
+   }
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)
diff --git a/include/boost/container/detail/auto_link.hpp b/include/boost/container/detail/auto_link.hpp
new file mode 100644
index 0000000..264b1ba
--- /dev/null
+++ b/include/boost/container/detail/auto_link.hpp
@@ -0,0 +1,51 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013. 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_DETAIL_AUTO_LINK_HPP_INCLUDED
+#define BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+//Define BOOST_CONTAINER_DYNAMIC_LINKING which is independent from BOOST_*_NO_LIB
+//and is needed is some tests that need to disable some checks (like operator new replacements)
+//that don't work across DLL boundaries
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
+#  define BOOST_CONTAINER_DYNAMIC_LINKING
+#endif
+
+//
+// Automatically link to the correct build variant where possible.
+//
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CONTAINER_NO_LIB) && !defined(BOOST_CONTAINER_SOURCE)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_container
+
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_CONTAINER_DYNAMIC_LINKING)
+#  define BOOST_DYN_LINK
+#endif
+
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
diff --git a/include/boost/container/detail/block_list.hpp b/include/boost/container/detail/block_list.hpp
new file mode 100644
index 0000000..1a6057c
--- /dev/null
+++ b/include/boost/container/detail/block_list.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_DETAIL_BLOCK_LIST_HEADER
+#define BOOST_CONTAINER_DETAIL_BLOCK_LIST_HEADER
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/throw_exception.hpp>
+#include <boost/intrusive/circular_list_algorithms.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/assert.hpp>
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace pmr {
+
+struct list_node
+{
+   list_node *next;
+   list_node *previous;
+};
+
+struct list_node_traits
+{
+   typedef list_node         node;
+   typedef list_node*        node_ptr;
+   typedef const list_node*  const_node_ptr;
+
+   static node_ptr get_next(const_node_ptr n)
+   {  return n->next;  }
+
+   static node_ptr get_previous(const_node_ptr n)
+   {  return n->previous;  }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->next = next;  }
+
+   static void set_previous(const node_ptr & n, const node_ptr & previous)
+   {  n->previous = previous;  }
+};
+
+struct block_list_header
+   : public list_node
+{
+   std::size_t size;
+};
+
+typedef bi::circular_list_algorithms<list_node_traits> list_algo;
+
+
+template<class DerivedFromBlockListHeader = block_list_header>
+class block_list_base
+{
+   list_node m_list;
+
+   static const std::size_t MaxAlignMinus1 = memory_resource::max_align-1u;
+
+   public:
+
+   static const std::size_t header_size = std::size_t(sizeof(DerivedFromBlockListHeader) + MaxAlignMinus1) & std::size_t(~MaxAlignMinus1);
+
+   explicit block_list_base()
+   {  list_algo::init_header(&m_list);  }
+
+   #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   block_list_base(const block_list_base&) = delete;
+   block_list_base operator=(const block_list_base&) = delete;
+   #else
+   private:
+   block_list_base          (const block_list_base&);
+   block_list_base operator=(const block_list_base&);
+   public:
+   #endif
+
+   ~block_list_base()
+   {}
+
+   void *allocate(std::size_t size, memory_resource &mr)
+   {
+      if((size_t(-1) - header_size) < size)
+         throw_bad_alloc();
+      void *p = mr.allocate(size+header_size);
+      block_list_header &mb  = *::new((void*)p) DerivedFromBlockListHeader;
+      mb.size = size+header_size;
+      list_algo::link_after(&m_list, &mb);
+      return (char *)p + header_size;
+   }
+
+   void deallocate(void *p, memory_resource &mr) BOOST_NOEXCEPT
+   {
+      DerivedFromBlockListHeader *pheader = static_cast<DerivedFromBlockListHeader*>
+         (static_cast<void*>((char*)p - header_size));
+      list_algo::unlink(pheader);
+      const std::size_t size = pheader->size;
+      static_cast<DerivedFromBlockListHeader*>(pheader)->~DerivedFromBlockListHeader();
+      mr.deallocate(pheader, size, memory_resource::max_align);
+   }
+
+   void release(memory_resource &mr) BOOST_NOEXCEPT
+   {
+      list_node *n = list_algo::node_traits::get_next(&m_list);
+      while(n != &m_list){
+         DerivedFromBlockListHeader &d = static_cast<DerivedFromBlockListHeader&>(*n);
+         n = list_algo::node_traits::get_next(n);
+         std::size_t size = d.size;
+         d.~DerivedFromBlockListHeader();
+         mr.deallocate(reinterpret_cast<char*>(&d), size, memory_resource::max_align);         
+      }
+      list_algo::init_header(&m_list);
+   }
+};
+
+}  //namespace pmr {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_BLOCK_LIST_HEADER
diff --git a/include/boost/container/detail/block_slist.hpp b/include/boost/container/detail/block_slist.hpp
new file mode 100644
index 0000000..278e641
--- /dev/null
+++ b/include/boost/container/detail/block_slist.hpp
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_DETAIL_BLOCK_SLIST_HEADER
+#define BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/throw_exception.hpp>
+
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/intrusive/linear_slist_algorithms.hpp>
+#include <boost/assert.hpp>
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace pmr {
+
+struct slist_node
+{
+   slist_node *next;
+};
+
+struct slist_node_traits
+{
+   typedef slist_node         node;
+   typedef slist_node*        node_ptr;
+   typedef const slist_node*  const_node_ptr;
+
+   static node_ptr get_next(const_node_ptr n)
+   {  return n->next;  }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->next = next;  }
+};
+
+struct block_slist_header
+   : public slist_node
+{
+   std::size_t size;
+};
+
+typedef bi::linear_slist_algorithms<slist_node_traits> slist_algo;
+
+template<class DerivedFromBlockSlistHeader = block_slist_header>
+class block_slist_base
+{
+   slist_node m_slist;
+
+   static const std::size_t MaxAlignMinus1 = memory_resource::max_align-1u;
+
+   public:
+
+   static const std::size_t header_size = std::size_t(sizeof(DerivedFromBlockSlistHeader) + MaxAlignMinus1) & std::size_t(~MaxAlignMinus1);
+
+   explicit block_slist_base()
+   {  slist_algo::init_header(&m_slist);  }
+
+   #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   block_slist_base(const block_slist_base&) = delete;
+   block_slist_base operator=(const block_slist_base&) = delete;
+   #else
+   private:
+   block_slist_base          (const block_slist_base&);
+   block_slist_base operator=(const block_slist_base&);
+   public:
+   #endif
+
+   ~block_slist_base()
+   {}
+
+   void *allocate(std::size_t size, memory_resource &mr)
+   {
+      if((size_t(-1) - header_size) < size)
+         throw_bad_alloc();
+      void *p = mr.allocate(size+header_size);
+      block_slist_header &mb  = *::new((void*)p) DerivedFromBlockSlistHeader;
+      mb.size = size+header_size;
+      slist_algo::link_after(&m_slist, &mb);
+      return (char *)p + header_size;
+   }
+
+   void release(memory_resource &mr) BOOST_NOEXCEPT
+   {
+      slist_node *n = slist_algo::node_traits::get_next(&m_slist);
+      while(n){
+         DerivedFromBlockSlistHeader &d = static_cast<DerivedFromBlockSlistHeader&>(*n);
+         n = slist_algo::node_traits::get_next(n);
+         std::size_t size = d.block_slist_header::size;
+         d.~DerivedFromBlockSlistHeader();
+         mr.deallocate(reinterpret_cast<char*>(&d), size, memory_resource::max_align);         
+      }
+      slist_algo::init_header(&m_slist);
+   }
+};
+
+class block_slist
+   : public block_slist_base<>
+{
+   memory_resource &m_upstream_rsrc;
+
+   public:
+
+   explicit block_slist(memory_resource &upstream_rsrc)
+      : block_slist_base<>(), m_upstream_rsrc(upstream_rsrc)
+   {}
+
+   #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   block_slist(const block_slist&) = delete;
+   block_slist operator=(const block_slist&) = delete;
+   #else
+   private:
+   block_slist          (const block_slist&);
+   block_slist operator=(const block_slist&);
+   public:
+   #endif
+
+   ~block_slist()
+   {  this->release();  }
+
+   void *allocate(std::size_t size)
+   {  return this->block_slist_base<>::allocate(size, m_upstream_rsrc);  }
+
+   void release() BOOST_NOEXCEPT
+   {  return this->block_slist_base<>::release(m_upstream_rsrc);  }
+
+   memory_resource& upstream_resource() const BOOST_NOEXCEPT
+   {  return m_upstream_rsrc;   }
+};
+
+}  //namespace pmr {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_BLOCK_SLIST_HEADER
diff --git a/include/boost/container/detail/compare_functors.hpp b/include/boost/container/detail/compare_functors.hpp
new file mode 100644
index 0000000..28f9093
--- /dev/null
+++ b/include/boost/container/detail/compare_functors.hpp
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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_DETAIL_COMPARE_FUNCTORS_HPP
+#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+namespace boost {
+namespace container {
+
+template<class Allocator>
+class equal_to_value
+{
+   typedef typename Allocator::value_type value_type;
+   const value_type &t_;
+
+   public:
+   explicit equal_to_value(const value_type &t)
+      :  t_(t)
+   {}
+
+   bool operator()(const value_type &t)const
+   {  return t_ == t;   }
+};
+
+template<class Node, class Pred>
+struct value_to_node_compare
+   :  Pred
+{
+   typedef Pred predicate_type;
+   typedef Node node_type;
+
+   value_to_node_compare()
+      : Pred()
+   {}
+
+   explicit value_to_node_compare(Pred pred)
+      :  Pred(pred)
+   {}
+
+   bool operator()(const Node &a, const Node &b) const
+   {  return static_cast<const Pred&>(*this)(a.get_data(), b.get_data());  }
+
+   bool operator()(const Node &a) const
+   {  return static_cast<const Pred&>(*this)(a.get_data());  }
+
+   bool operator()(const Node &a, const Node &b)
+   {  return static_cast<Pred&>(*this)(a.get_data(), b.get_data());  }
+
+   bool operator()(const Node &a)
+   {  return static_cast<Pred&>(*this)(a.get_data());  }
+
+   predicate_type &       predicate()        { return static_cast<predicate_type&>(*this); }
+   const predicate_type & predicate()  const { return static_cast<predicate_type&>(*this); }
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
diff --git a/include/boost/container/detail/config_begin.hpp b/include/boost/container/detail/config_begin.hpp
new file mode 100644
index 0000000..4df9e35
--- /dev/null
+++ b/include/boost/container/detail/config_begin.hpp
@@ -0,0 +1,53 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_CONTAINER_DETAIL_CONFIG_INCLUDED
+#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+
+#endif   //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
+
+#ifdef BOOST_MSVC
+   #pragma warning (push)
+   #pragma warning (disable : 4127) // conditional expression is constant
+   #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+   #pragma warning (disable : 4197) // top-level volatile in cast is ignored
+   #pragma warning (disable : 4244) // possible loss of data
+   #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
+   #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
+   #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
+   #pragma warning (disable : 4284) // odd return type for operator->
+   #pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
+   #pragma warning (disable : 4324) // structure was padded due to __declspec(align(
+   #pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
+   #pragma warning (disable : 4355) // "this" : used in base member initializer list
+   #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
+   #pragma warning (disable : 4510) //  default constructor could not be generated
+   #pragma warning (disable : 4511) // copy constructor could not be generated
+   #pragma warning (disable : 4512) // assignment operator could not be generated
+   #pragma warning (disable : 4514) // unreferenced inline removed
+   #pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
+   #pragma warning (disable : 4522) // "class" : multiple assignment operators specified
+   #pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result
+   #pragma warning (disable : 4584) //  X is already a base-class of Y
+   #pragma warning (disable : 4610) //  struct can never be instantiated - user defined constructor required
+   #pragma warning (disable : 4671) //  the copy constructor is inaccessible
+   #pragma warning (disable : 4673) //  throwing '' the following types will not be considered at the catch site
+   #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
+   #pragma warning (disable : 4702) // unreachable code
+   #pragma warning (disable : 4706) // assignment within conditional expression
+   #pragma warning (disable : 4710) // function not inlined
+   #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
+   #pragma warning (disable : 4711) // function selected for automatic inline expansion
+   #pragma warning (disable : 4786) // identifier truncated in debug info
+   #pragma warning (disable : 4996) // "function": was declared deprecated
+ 
+#endif   //BOOST_MSVC
diff --git a/include/boost/container/detail/config_end.hpp b/include/boost/container/detail/config_end.hpp
new file mode 100644
index 0000000..f93c8f6
--- /dev/null
+++ b/include/boost/container/detail/config_end.hpp
@@ -0,0 +1,13 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+   #pragma warning (pop)
+#endif
+
diff --git a/include/boost/container/detail/construct_in_place.hpp b/include/boost/container/detail/construct_in_place.hpp
new file mode 100644
index 0000000..b131f06
--- /dev/null
+++ b/include/boost/container/detail/construct_in_place.hpp
@@ -0,0 +1,96 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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_DETAIL_CONSTRUCT_IN_PLACE_HPP
+#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/value_init.hpp>
+
+namespace boost {
+namespace container {
+
+//In place construction
+
+template<class Allocator, class T, class InpIt>
+BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source)
+{     boost::container::allocator_traits<Allocator>::construct(a, dest, *source);  }
+
+template<class Allocator, class T, class U, class D>
+BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
+{
+   boost::container::allocator_traits<Allocator>::construct(a, dest);
+}
+
+template <class T, class Difference>
+class default_init_construct_iterator;
+
+template<class Allocator, class T, class U, class D>
+BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
+{
+   boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
+}
+
+template <class T, class EmplaceFunctor, class Difference>
+class emplace_iterator;
+
+template<class Allocator, class T, class U, class EF, class D>
+BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
+{
+   ei.construct_in_place(a, dest);
+}
+
+//Assignment
+
+template<class DstIt, class InpIt>
+BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source)
+{  *dest = *source;  }
+
+template<class DstIt, class U, class D>
+BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>)
+{
+   dtl::value_init<U> val;
+   *dest = boost::move(val.get());
+}
+
+template <class DstIt, class Difference>
+class default_init_construct_iterator;
+
+template<class DstIt, class U, class D>
+BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>)
+{
+   U u;
+   *dest = boost::move(u);
+}
+
+template <class T, class EmplaceFunctor, class Difference>
+class emplace_iterator;
+
+template<class DstIt, class U, class EF, class D>
+BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei)
+{
+   ei.assign_in_place(dest);
+}
+
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
diff --git a/include/boost/container/detail/container_or_allocator_rebind.hpp b/include/boost/container/detail/container_or_allocator_rebind.hpp
new file mode 100644
index 0000000..d74df6c
--- /dev/null
+++ b/include/boost/container/detail/container_or_allocator_rebind.hpp
@@ -0,0 +1,49 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017. 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_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
+#define BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/container_rebind.hpp>
+#include <boost/container/detail/is_container.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class AllocatorOrContainer, class ToType, bool = is_container<AllocatorOrContainer>::value>
+struct container_or_allocator_rebind_impl
+   : container_rebind<AllocatorOrContainer, ToType>
+{};
+
+template<class AllocatorOrContainer, class ToType>
+struct container_or_allocator_rebind_impl<AllocatorOrContainer, ToType, false>
+   : allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc<ToType>
+
+{};
+
+template<class AllocatorOrContainer, class ToType>
+struct container_or_allocator_rebind
+   : container_or_allocator_rebind_impl<AllocatorOrContainer, ToType>
+{};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
diff --git a/include/boost/container/detail/container_rebind.hpp b/include/boost/container/detail/container_rebind.hpp
new file mode 100644
index 0000000..0ebb478
--- /dev/null
+++ b/include/boost/container/detail/container_rebind.hpp
@@ -0,0 +1,258 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017. 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_DETAIL_CONTAINER_REBIND_HPP
+#define BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/allocator_traits.hpp>
+
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+   template <class Cont, class U>
+   struct container_rebind;
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U>
+   struct container_rebind<Cont<V, A, An...>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
+   };
+
+   //Needed for non-conforming compilers like GCC 4.3
+   template <template <class, class> class Cont, typename V, typename A, class U>
+   struct container_rebind<Cont<V, A>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
+   };
+
+   template <template <class> class Cont, typename V, class U>
+   struct container_rebind<Cont<V>, U>
+   {
+      typedef Cont<U> type;
+   };
+
+   //for small_vector,static_vector
+
+   template <template <class, std::size_t, class, class...> class Cont, typename V, std::size_t N, typename A, class... An, class U>
+   struct container_rebind<Cont<V, N, A, An...>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
+   };
+
+   //Needed for non-conforming compilers like GCC 4.3
+   template <template <class, std::size_t, class> class Cont, typename V, std::size_t N, typename A, class U>
+   struct container_rebind<Cont<V, N, A>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
+   };
+
+   template <template <class, std::size_t> class Cont, typename V, std::size_t N, class U>
+   struct container_rebind<Cont<V, N>, U>
+   {
+      typedef Cont<U, N> type;
+   };
+
+#else //C++03 compilers
+
+   template <template <class> class Cont  //0arg
+      , typename V
+      , class U>
+      struct container_rebind<Cont<V>, U>
+   {
+      typedef Cont<U> type;
+   };
+
+   template <template <class, class> class Cont  //0arg
+      , typename V, typename A
+      , class U>
+      struct container_rebind<Cont<V, A>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
+   };
+
+   template <template <class, class, class> class Cont  //1arg
+      , typename V, typename A, class P0
+      , class U>
+      struct container_rebind<Cont<V, A, P0>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
+   };
+
+   template <template <class, class, class, class> class Cont  //2arg
+      , typename V, typename A, class P0, class P1
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
+   };
+
+   template <template <class, class, class, class, class> class Cont  //3arg
+      , typename V, typename A, class P0, class P1, class P2
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
+   };
+
+   template <template <class, class, class, class, class, class> class Cont  //4arg
+      , typename V, typename A, class P0, class P1, class P2, class P3
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
+   };
+
+   template <template <class, class, class, class, class, class, class> class Cont  //5arg
+      , typename V, typename A, class P0, class P1, class P2, class P3, class P4
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
+   };
+
+   template <template <class, class, class, class, class, class, class, class> class Cont  //6arg
+      , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
+   };
+
+   template <template <class, class, class, class, class, class, class, class, class> class Cont  //7arg
+      , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
+   };
+
+   template <template <class, class, class, class, class, class, class, class, class, class> class Cont  //8arg
+      , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
+   };
+
+   template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont  //9arg
+      , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
+      , class U>
+      struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
+   {
+      typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
+   };
+
+   //For small_vector/static_vector
+   template <template <class, std::size_t> class Cont  //0arg
+      , typename V, std::size_t N
+      , class U>
+      struct container_rebind<Cont<V, N>, U>
+   {
+      typedef Cont<U, N> type;
+   };
+
+   template <template <class, std::size_t, class> class Cont  //0arg
+      , typename V, std::size_t N, typename A
+      , class U>
+      struct container_rebind<Cont<V, N, A>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
+   };
+
+   template <template <class, std::size_t, class, class> class Cont  //1arg
+      , typename V, std::size_t N, typename A, class P0
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
+   };
+
+   template <template <class, std::size_t, class, class, class> class Cont  //2arg
+      , typename V, std::size_t N, typename A, class P0, class P1
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class> class Cont  //3arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class> class Cont  //4arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class, class> class Cont  //5arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class, class, class> class Cont  //6arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class, class, class, class> class Cont  //7arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class, class, class, class, class> class Cont  //8arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
+   };
+
+   template <template <class, std::size_t, class, class, class, class, class, class, class, class, class, class> class Cont  //9arg
+      , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
+      , class U>
+      struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
+   {
+      typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
+   };
+
+#endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
diff --git a/include/boost/container/detail/copy_move_algo.hpp b/include/boost/container/detail/copy_move_algo.hpp
new file mode 100644
index 0000000..f03800a
--- /dev/null
+++ b/include/boost/container/detail/copy_move_algo.hpp
@@ -0,0 +1,1154 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_COPY_MOVE_ALGO_HPP
+#define BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+// container
+#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/iterator.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
+
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/utility_core.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#include <cstring> //for memmove/memcpy
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 80000)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
+#endif
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class I>
+struct are_elements_contiguous
+{
+   static const bool value = false;
+};
+
+/////////////////////////
+//    raw pointers
+/////////////////////////
+
+template<class T>
+struct are_elements_contiguous<T*>
+{
+   static const bool value = true;
+};
+
+/////////////////////////
+//    move iterators
+/////////////////////////
+
+template<class It>
+struct are_elements_contiguous< ::boost::move_iterator<It> >
+   : are_elements_contiguous<It>
+{};
+
+}  //namespace dtl {
+
+/////////////////////////
+//    predeclarations
+/////////////////////////
+
+template <class Pointer, bool IsConst>
+class vec_iterator;
+
+}  //namespace container {
+
+namespace interprocess {
+
+template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
+class offset_ptr;
+
+}  //namespace interprocess {
+
+namespace container {
+
+namespace dtl {
+
+/////////////////////////
+//vector_[const_]iterator
+/////////////////////////
+
+template <class Pointer, bool IsConst>
+struct are_elements_contiguous<boost::container::vec_iterator<Pointer, IsConst> >
+{
+   static const bool value = true;
+};
+
+/////////////////////////
+//    offset_ptr
+/////////////////////////
+
+template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
+struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> >
+{
+   static const bool value = true;
+};
+
+template <typename I, typename O>
+struct are_contiguous_and_same
+   : boost::move_detail::and_
+      < are_elements_contiguous<I>
+      , are_elements_contiguous<O>
+      , is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
+               , typename ::boost::container::iterator_traits<O>::value_type
+               >
+      >
+{};
+
+template <typename I, typename O>
+struct is_memtransfer_copy_assignable
+   : boost::move_detail::and_
+      < are_contiguous_and_same<I, O>
+      , dtl::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >
+      >
+{};
+
+template <typename I, typename O>
+struct is_memtransfer_copy_constructible
+   : boost::move_detail::and_
+      < are_contiguous_and_same<I, O>
+      , dtl::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >
+      >
+{};
+
+template <typename I, typename O, typename R>
+struct enable_if_memtransfer_copy_constructible
+   : enable_if<dtl::is_memtransfer_copy_constructible<I, O>, R>
+{};
+
+template <typename I, typename O, typename R>
+struct disable_if_memtransfer_copy_constructible
+   : disable_if<dtl::is_memtransfer_copy_constructible<I, O>, R>
+{};
+
+template <typename I, typename O, typename R>
+struct enable_if_memtransfer_copy_assignable
+   : enable_if<dtl::is_memtransfer_copy_assignable<I, O>, R>
+{};
+
+template <typename I, typename O, typename R>
+struct disable_if_memtransfer_copy_assignable
+   : disable_if<dtl::is_memtransfer_copy_assignable<I, O>, R>
+{};
+
+template
+   <typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+   typedef typename boost::container::iterator_traits<I>::value_type value_type;
+   typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
+   if(n){
+      std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
+      boost::container::iterator_advance(r, n);
+   }
+   return r;
+}
+
+template
+   <typename I, // I models InputIterator
+    typename U, // U models unsigned integral constant
+    typename F> // F models ForwardIterator
+F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+   typedef typename boost::container::iterator_traits<I>::value_type value_type;
+   if(n){
+      std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
+      boost::container::iterator_advance(r, n);
+   }
+   return r;
+}
+
+template
+   <typename I, // I models InputIterator
+    typename U, // U models unsigned integral constant
+    typename F> // F models ForwardIterator
+I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+   if(n){
+      typedef typename boost::container::iterator_traits<I>::value_type value_type;
+      std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
+      boost::container::iterator_advance(f, n);
+   }
+   return f;
+}
+
+template
+   <typename I, // I models InputIterator
+    typename U, // U models unsigned integral constant
+    typename F> // F models ForwardIterator
+I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+   typedef typename boost::container::iterator_traits<I>::value_type value_type;
+   if(n){
+      std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
+      boost::container::iterator_advance(f, n);
+      boost::container::iterator_advance(r, n);
+   }
+   return f;
+}
+
+template <typename O>
+struct is_memzero_initializable
+{
+   typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
+   static const bool value = are_elements_contiguous<O>::value &&
+      (  dtl::is_integral<value_type>::value || dtl::is_enum<value_type>::value
+      #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
+      || dtl::is_pointer<value_type>::value
+      #endif
+      #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
+      || dtl::is_floating_point<value_type>::value
+      #endif
+      #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
+      || dtl::is_pod<value_type>::value
+      #endif
+      );
+};
+
+template <typename O, typename R>
+struct enable_if_memzero_initializable
+   : enable_if_c<dtl::is_memzero_initializable<O>::value, R>
+{};
+
+template <typename O, typename R>
+struct disable_if_memzero_initializable
+   : enable_if_c<!dtl::is_memzero_initializable<O>::value, R>
+{};
+
+template <typename I, typename R>
+struct enable_if_trivially_destructible
+   : enable_if_c < dtl::is_trivially_destructible
+                  <typename boost::container::iterator_traits<I>::value_type>::value
+               , R>
+{};
+
+template <typename I, typename R>
+struct disable_if_trivially_destructible
+   : enable_if_c <!dtl::is_trivially_destructible
+                  <typename boost::container::iterator_traits<I>::value_type>::value
+               , R>
+{};
+
+}  //namespace dtl {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; f != l; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, boost::move(*f));
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_move_alloc(Allocator &a, I f, I l, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (f != l) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove(f, l, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, boost::move(*f));
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, boost::move(*f));
+//!   \endcode
+//!
+//! <b>Returns</b>: f (after incremented)
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type
+   uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return f;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
+   uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_copy_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; f != l; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, *f);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (f != l) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove(f, l, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_copy_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, *f);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
+   uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_copy_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, *f);
+//!   \endcode
+//!
+//! <b>Returns</b>: f (after incremented)
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type
+   uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f);
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return f;
+}
+
+template
+   <typename Allocator,
+    typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
+   uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_value_init_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename F> // F models ForwardIterator
+inline typename dtl::disable_if_memzero_initializable<F, F>::type
+   uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r));
+         ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+template
+   <typename Allocator,
+    typename F> // F models ForwardIterator
+inline typename dtl::enable_if_memzero_initializable<F, F>::type
+   uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   typedef typename boost::container::iterator_traits<F>::value_type value_type;
+   std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
+   boost::container::iterator_advance(r, n);
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_default_init_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename F> // F models ForwardIterator
+inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init);
+         ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_fill_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; f != l; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, *f);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename F, // F models ForwardIterator
+    typename T>
+inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
+{
+   F back = f;
+   BOOST_TRY{
+      while (f != l) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(f), t);
+         ++f;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != l; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_fill_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; n--; ++r, ++f)
+//!      allocator_traits::construct(a, &*r, v);
+//!   \endcode
+//!
+//! <b>Returns</b>: r
+template
+   <typename Allocator,
+    typename T,
+    typename F> // F models ForwardIterator
+inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
+{
+   F back = r;
+   BOOST_TRY{
+      while (n--) {
+         allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v);
+         ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               copy
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename F>    // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
+   copy(I f, I l, F r)
+{
+   while (f != l) {
+      *r = *f;
+      ++f; ++r;
+   }
+   return r;
+}
+
+template
+<typename I,   // I models InputIterator
+typename F>    // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
+   copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove(f, l, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               copy_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
+   copy_n(I f, U n, F r)
+{
+   while (n--) {
+      *r = *f;
+      ++f; ++r;
+   }
+   return r;
+}
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
+   copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            copy_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
+   copy_n_source(I f, U n, F r)
+{
+   while (n--) {
+      boost::container::assign_in_place(r, f);
+      ++f; ++r;
+   }
+   return f;
+}
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
+   copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            copy_n_source_dest
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
+   copy_n_source_dest(I f, U n, F &r)
+{
+   while (n--) {
+      *r = *f;
+      ++f; ++r;
+   }
+   return f;
+}
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
+   copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source_dest(f, n, r);  }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
+   move(I f, I l, F r)
+{
+   while (f != l) {
+      *r = ::boost::move(*f);
+      ++f; ++r;
+   }
+   return r;
+}
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
+   move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove(f, l, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
+   move_n(I f, U n, F r)
+{
+   while (n--) {
+      *r = ::boost::move(*f);
+      ++f; ++r;
+   }
+   return r;
+}
+
+template
+<typename I,   // I models InputIterator
+typename U,   // U models unsigned integral constant
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
+   move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n(f, n, r); }
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move_backward
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I,   // I models BidirectionalIterator
+typename F>    // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
+   move_backward(I f, I l, F r)
+{
+   while (f != l) {
+      --l; --r;
+      *r = ::boost::move(*l);
+   }
+   return r;
+}
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
+   move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+   typedef typename boost::container::iterator_traits<I>::value_type value_type;
+   const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
+   r -= n;
+   std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move_n_source_dest
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I    // I models InputIterator
+,typename U    // U models unsigned integral constant
+,typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
+   move_n_source_dest(I f, U n, F &r)
+{
+   while (n--) {
+      *r = ::boost::move(*f);
+      ++f; ++r;
+   }
+   return f;
+}
+
+template
+<typename I    // I models InputIterator
+,typename U    // U models unsigned integral constant
+,typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
+   move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source_dest(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I    // I models InputIterator
+,typename U    // U models unsigned integral constant
+,typename F>   // F models ForwardIterator
+inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
+   move_n_source(I f, U n, F r)
+{
+   while (n--) {
+      *r = ::boost::move(*f);
+      ++f; ++r;
+   }
+   return f;
+}
+
+template
+<typename I    // I models InputIterator
+,typename U    // U models unsigned integral constant
+,typename F>   // F models ForwardIterator
+inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
+   move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{  return dtl::memmove_n_source(f, n, r); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               destroy_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+   <typename Allocator
+   ,typename I   // I models InputIterator
+   ,typename U>  // U models unsigned integral constant
+inline typename dtl::disable_if_trivially_destructible<I, void>::type
+   destroy_alloc_n(Allocator &a, I f, U n)
+{
+   while(n){
+      --n;
+      allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(f));
+      ++f;
+   }
+}
+
+template
+   <typename Allocator
+   ,typename I   // I models InputIterator
+   ,typename U>  // U models unsigned integral constant
+inline typename dtl::enable_if_trivially_destructible<I, void>::type
+   destroy_alloc_n(Allocator &, I, U)
+{}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         deep_swap_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+   <std::size_t MaxTmpBytes
+   ,typename Allocator
+   ,typename F // F models ForwardIterator
+   ,typename G // G models ForwardIterator
+   >
+inline typename dtl::disable_if_memtransfer_copy_assignable<F, G, void>::type
+   deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+                    , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
+{
+   typename allocator_traits<Allocator>::size_type n = 0;
+   for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
+      boost::adl_move_swap(*short_range_f, *large_range_f);
+   }
+   boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f);  // may throw
+   boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
+}
+
+static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
+
+template
+   <std::size_t MaxTmpBytes
+   ,typename Allocator
+   ,typename F // F models ForwardIterator
+   ,typename G // G models ForwardIterator
+   >
+inline typename dtl::enable_if_c
+   < dtl::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
+   , void>::type
+   deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+                    , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
+{
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+   typedef typename dtl::aligned_storage
+      <MaxTmpBytes, dtl::alignment_of<value_type>::value>::type storage_type;
+   storage_type storage;
+
+   const std::size_t n_i_bytes = sizeof(value_type)*n_i;
+   void *const large_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f));
+   void *const short_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f));
+   void *const stora_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(storage.data));
+   std::memcpy(stora_ptr, large_ptr, n_i_bytes);
+   std::memcpy(large_ptr, short_ptr, n_i_bytes);
+   std::memcpy(short_ptr, stora_ptr, n_i_bytes);
+   boost::container::iterator_advance(large_range_f, n_i);
+   boost::container::iterator_advance(short_range_f, n_i);
+   boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f);  // may throw
+   boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
+}
+
+template
+   <std::size_t MaxTmpBytes
+   ,typename Allocator
+   ,typename F // F models ForwardIterator
+   ,typename G // G models ForwardIterator
+   >
+inline typename dtl::enable_if_c
+   < dtl::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
+   , void>::type
+   deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+                    , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
+{
+   typedef typename allocator_traits<Allocator>::value_type value_type;
+   typedef typename dtl::aligned_storage
+      <DeepSwapAllocNMaxStorage, dtl::alignment_of<value_type>::value>::type storage_type;
+   storage_type storage;
+   const std::size_t sizeof_storage = sizeof(storage);
+
+   std::size_t n_i_bytes = sizeof(value_type)*n_i;
+   char *large_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f)));
+   char *short_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f)));
+   char *stora_ptr = static_cast<char*>(static_cast<void*>(storage.data));
+
+   std::size_t szt_times = n_i_bytes/sizeof_storage;
+   const std::size_t szt_rem = n_i_bytes%sizeof_storage;
+
+   //Loop unrolling using Duff's device, as it seems it helps on some architectures
+   const std::size_t Unroll = 4;
+   std::size_t n = (szt_times + (Unroll-1))/Unroll;
+   const std::size_t branch_number = (!szt_times)*Unroll + (szt_times % Unroll);
+   switch(branch_number){
+      case 4:
+         break;
+      case 0: do{
+         std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+         std::memcpy(large_ptr, short_ptr, sizeof_storage);
+         std::memcpy(short_ptr, stora_ptr, sizeof_storage);
+         large_ptr += sizeof_storage;
+         short_ptr += sizeof_storage;
+         BOOST_FALLTHROUGH;
+      case 3:
+         std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+         std::memcpy(large_ptr, short_ptr, sizeof_storage);
+         std::memcpy(short_ptr, stora_ptr, sizeof_storage);
+         large_ptr += sizeof_storage;
+         short_ptr += sizeof_storage;
+         BOOST_FALLTHROUGH;
+      case 2:
+         std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+         std::memcpy(large_ptr, short_ptr, sizeof_storage);
+         std::memcpy(short_ptr, stora_ptr, sizeof_storage);
+         large_ptr += sizeof_storage;
+         short_ptr += sizeof_storage;
+         BOOST_FALLTHROUGH;
+      case 1:
+         std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+         std::memcpy(large_ptr, short_ptr, sizeof_storage);
+         std::memcpy(short_ptr, stora_ptr, sizeof_storage);
+         large_ptr += sizeof_storage;
+         short_ptr += sizeof_storage;
+         } while(--n);
+   }
+   std::memcpy(stora_ptr, large_ptr, szt_rem);
+   std::memcpy(large_ptr, short_ptr, szt_rem);
+   std::memcpy(short_ptr, stora_ptr, szt_rem);
+   boost::container::iterator_advance(large_range_f, n_i);
+   boost::container::iterator_advance(short_range_f, n_i);
+   boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f);  // may throw
+   boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         copy_assign_range_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+   <typename Allocator
+   ,typename I // F models InputIterator
+   ,typename O // G models OutputIterator
+   >
+void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
+                              , O out_start, typename allocator_traits<Allocator>::size_type n_o )
+{
+   if (n_o < n_i){
+      inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start);     // may throw
+      boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw
+   }
+   else{
+      out_start = boost::container::copy_n(inp_start, n_i, out_start);  // may throw
+      boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
+   }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         move_assign_range_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+   <typename Allocator
+   ,typename I // F models InputIterator
+   ,typename O // G models OutputIterator
+   >
+void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
+                              , O out_start, typename allocator_traits<Allocator>::size_type n_o )
+{
+   if (n_o < n_i){
+      inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start);  // may throw
+      boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start);  // may throw
+   }
+   else{
+      out_start = boost::container::move_n(inp_start, n_i, out_start);  // may throw
+      boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
+   }
+}
+
+}  //namespace container {
+}  //namespace boost {
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 80000)
+#pragma GCC diagnostic pop
+#endif
+
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
diff --git a/include/boost/container/detail/destroyers.hpp b/include/boost/container/detail/destroyers.hpp
new file mode 100644
index 0000000..9b0be44
--- /dev/null
+++ b/include/boost/container/detail/destroyers.hpp
@@ -0,0 +1,378 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+//
+// 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_DESTROYERS_HPP
+#define BOOST_CONTAINER_DESTROYERS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an object using a STL allocator.
+template <class Allocator>
+struct scoped_deallocator
+{
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   typedef typename allocator_traits_type::pointer pointer;
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::
+         version<Allocator>::value>                   alloc_version;
+
+   private:
+   void priv_deallocate(version_1)
+   {  m_alloc.deallocate(m_ptr, 1); }
+
+   void priv_deallocate(version_2)
+   {  m_alloc.deallocate_one(m_ptr); }
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
+
+   public:
+
+   pointer     m_ptr;
+   Allocator&  m_alloc;
+
+   scoped_deallocator(pointer p, Allocator& a)
+      : m_ptr(p), m_alloc(a)
+   {}
+
+   ~scoped_deallocator()
+   {  if (m_ptr)priv_deallocate(alloc_version());  }
+
+   scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
+      :  m_ptr(o.m_ptr), m_alloc(o.m_alloc)
+   {  o.release();  }
+
+   pointer get() const
+   {  return m_ptr;  }
+
+   void set(const pointer &p)
+   {  m_ptr = p;  }
+
+   void release()
+   {  m_ptr = 0; }
+};
+
+template <class Allocator>
+struct null_scoped_deallocator
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+
+   null_scoped_deallocator(pointer, Allocator&, size_type)
+   {}
+
+   void release()
+   {}
+
+   pointer get() const
+   {  return pointer();  }
+
+   void set(const pointer &)
+   {}
+};
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an array of objects using a STL allocator.
+template <class Allocator>
+struct scoped_array_deallocator
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+
+   scoped_array_deallocator(pointer p, Allocator& a, size_type length)
+      : m_ptr(p), m_alloc(a), m_length(length) {}
+
+   ~scoped_array_deallocator()
+   {  if (m_ptr) m_alloc.deallocate(m_ptr, m_length);  }
+
+   void release()
+   {  m_ptr = 0; }
+
+   private:
+   pointer     m_ptr;
+   Allocator&  m_alloc;
+   size_type   m_length;
+};
+
+template <class Allocator>
+struct null_scoped_array_deallocator
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+
+   null_scoped_array_deallocator(pointer, Allocator&, size_type)
+   {}
+
+   void release()
+   {}
+};
+
+template <class Allocator>
+struct scoped_destroy_deallocator
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::
+         version<Allocator>::value>                          alloc_version;
+
+   scoped_destroy_deallocator(pointer p, Allocator& a)
+      : m_ptr(p), m_alloc(a) {}
+
+   ~scoped_destroy_deallocator()
+   {
+      if(m_ptr){
+         AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr));
+         priv_deallocate(m_ptr, alloc_version());
+      }
+   }
+
+   void release()
+   {  m_ptr = 0; }
+
+   private:
+
+   void priv_deallocate(const pointer &p, version_1)
+   {  AllocTraits::deallocate(m_alloc, p, 1); }
+
+   void priv_deallocate(const pointer &p, version_2)
+   {  m_alloc.deallocate_one(p); }
+
+   pointer     m_ptr;
+   Allocator&  m_alloc;
+};
+
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct scoped_destructor_n
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::value_type value_type;
+   typedef typename AllocTraits::size_type  size_type;
+
+   scoped_destructor_n(pointer p, Allocator& a, size_type n)
+      : m_p(p), m_a(a), m_n(n)
+   {}
+
+   void release()
+   {  m_p = 0; }
+
+   void increment_size(size_type inc)
+   {  m_n += inc;   }
+
+   void increment_size_backwards(size_type inc)
+   {  m_n += inc;   m_p -= inc;  }
+
+   void shrink_forward(size_type inc)
+   {  m_n -= inc;   m_p += inc;  }
+
+   ~scoped_destructor_n()
+   {
+      if(!m_p) return;
+      value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
+      while(m_n--){
+         AllocTraits::destroy(m_a, raw_ptr++);
+      }
+   }
+
+   private:
+   pointer     m_p;
+   Allocator & m_a;
+   size_type   m_n;
+};
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct null_scoped_destructor_n
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::pointer pointer;
+   typedef typename AllocTraits::size_type size_type;
+
+   null_scoped_destructor_n(pointer, Allocator&, size_type)
+   {}
+
+   void increment_size(size_type)
+   {}
+
+   void increment_size_backwards(size_type)
+   {}
+
+   void shrink_forward(size_type)
+   {}
+
+   void release()
+   {}
+};
+
+template<class Allocator>
+class scoped_destructor
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   public:
+   typedef typename Allocator::value_type value_type;
+   scoped_destructor(Allocator &a, value_type *pv)
+      : pv_(pv), a_(a)
+   {}
+
+   ~scoped_destructor()
+   {
+      if(pv_){
+         AllocTraits::destroy(a_, pv_);
+      }
+   }
+
+   void release()
+   {  pv_ = 0; }
+
+
+   void set(value_type *ptr) { pv_ = ptr; }
+
+   value_type *get() const { return pv_; }
+
+   private:
+   value_type *pv_;
+   Allocator &a_;
+};
+
+
+template<class Allocator, class Value = typename Allocator::value_type>
+class value_destructor
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   public:
+   typedef Value value_type;
+   value_destructor(Allocator &a, value_type &rv)
+      : rv_(rv), a_(a)
+   {}
+
+   ~value_destructor()
+   {
+      AllocTraits::destroy(a_, &rv_);
+   }
+
+   private:
+   value_type &rv_;
+   Allocator &a_;
+};
+
+template <class Allocator>
+class allocator_destroyer
+{
+   typedef boost::container::allocator_traits<Allocator> AllocTraits;
+   typedef typename AllocTraits::value_type value_type;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::
+         version<Allocator>::value>                           alloc_version;
+
+   private:
+   Allocator & a_;
+
+   private:
+   void priv_deallocate(const pointer &p, version_1)
+   {  AllocTraits::deallocate(a_,p, 1); }
+
+   void priv_deallocate(const pointer &p, version_2)
+   {  a_.deallocate_one(p); }
+
+   public:
+   explicit allocator_destroyer(Allocator &a)
+      : a_(a)
+   {}
+
+   void operator()(const pointer &p)
+   {
+      AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p));
+      this->priv_deallocate(p, alloc_version());
+   }
+};
+
+template <class Allocator>
+class allocator_destroyer_and_chain_builder
+{
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename Allocator::multiallocation_chain    multiallocation_chain;
+
+   Allocator & a_;
+   multiallocation_chain &c_;
+
+   public:
+   allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
+      :  a_(a), c_(c)
+   {}
+
+   void operator()(const typename Allocator::pointer &p)
+   {
+      allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));
+      c_.push_back(p);
+   }
+};
+
+template <class Allocator>
+class allocator_multialloc_chain_node_deallocator
+{
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename Allocator::multiallocation_chain    multiallocation_chain;
+   typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
+
+   Allocator & a_;
+   multiallocation_chain c_;
+
+   public:
+   allocator_multialloc_chain_node_deallocator(Allocator &a)
+      :  a_(a), c_()
+   {}
+
+   chain_builder get_chain_builder()
+   {  return chain_builder(a_, c_);  }
+
+   ~allocator_multialloc_chain_node_deallocator()
+   {
+      a_.deallocate_individual(c_);
+   }
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
diff --git a/include/boost/container/detail/dispatch_uses_allocator.hpp b/include/boost/container/detail/dispatch_uses_allocator.hpp
new file mode 100644
index 0000000..0b8cfea
--- /dev/null
+++ b/include/boost/container/detail/dispatch_uses_allocator.hpp
@@ -0,0 +1,461 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_DISPATCH_USES_ALLOCATOR_HPP
+#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
+
+#if defined (_MSC_VER)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/uses_allocator.hpp>
+
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/utility_core.hpp>
+
+#include <boost/core/no_exceptions_support.hpp>
+
+namespace boost { namespace container {
+
+namespace dtl {
+
+
+// Check if we can detect is_convertible using advanced SFINAE expressions
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
+   //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
+   //! Thanks Mathias!
+
+   //With variadic templates, we need a single class to implement the trait
+   template<class T, class ...Args>
+   struct is_constructible
+   {
+      typedef char yes_type;
+      struct no_type
+      { char padding[2]; };
+
+      template<std::size_t N>
+      struct dummy;
+
+      template<class X>
+      static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
+
+      template<class X>
+      static no_type test(...);
+
+      static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+   };
+
+   template <class T, class InnerAlloc, class ...Args>
+   struct is_constructible_with_allocator_prefix
+      : is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
+   {};
+
+#else    // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   //Without advanced SFINAE expressions, we can't use is_constructible
+   //so backup to constructible_with_allocator_xxx
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <class T, class InnerAlloc, class ...Args>
+   struct is_constructible_with_allocator_prefix
+      : constructible_with_allocator_prefix<T>
+   {};
+
+   template <class T, class InnerAlloc, class ...Args>
+   struct is_constructible_with_allocator_suffix
+      : constructible_with_allocator_suffix<T>
+   {};
+
+   #else    // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
+   struct is_constructible_with_allocator_prefix
+      : constructible_with_allocator_prefix<T>
+   {};
+
+   template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
+   struct is_constructible_with_allocator_suffix
+      : constructible_with_allocator_suffix<T>
+   {};
+
+   #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#endif   // #if !defined(BOOST_NO_SFINAE_EXPR)
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , typename T
+         , class ...Args
+         >
+inline typename dtl::enable_if_and
+   < void
+   , dtl::is_not_pair<T>
+   , dtl::not_< uses_allocator<T, ArgAlloc> >
+   >::type dispatch_uses_allocator
+   ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
+{
+   (void)arg_alloc;
+   allocator_traits<ConstructAlloc>::construct(construct_alloc, p, ::boost::forward<Args>(args)...);
+}
+
+// allocator_arg_t
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , typename T
+         , class ...Args
+         >
+inline typename dtl::enable_if_and
+   < void
+   , dtl::is_not_pair<T>
+   , uses_allocator<T, ArgAlloc>
+   , is_constructible_with_allocator_prefix<T, ArgAlloc, Args...>
+   >::type dispatch_uses_allocator
+   ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args)
+{
+   allocator_traits<ConstructAlloc>::construct
+      ( construct_alloc, p, allocator_arg
+      , ::boost::forward<ArgAlloc>(arg_alloc), ::boost::forward<Args>(args)...);
+}
+
+// allocator suffix
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , typename T
+         , class ...Args
+         >
+inline typename dtl::enable_if_and
+   < void
+   , dtl::is_not_pair<T>
+   , uses_allocator<T, ArgAlloc>
+   , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >
+   >::type dispatch_uses_allocator
+   ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
+{
+   allocator_traits<ConstructAlloc>::construct
+      (construct_alloc, p, ::boost::forward<Args>(args)..., ::boost::forward<ArgAlloc>(arg_alloc));
+}
+
+#else    //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
+   template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+   inline typename dtl::enable_if_and\
+      < void\
+      , dtl::is_not_pair<T>\
+      , dtl::not_<uses_allocator<T, ArgAlloc> >\
+      >::type\
+      dispatch_uses_allocator\
+      (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      (void)arg_alloc;\
+      allocator_traits<ConstructAlloc>::construct(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+   }\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
+
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
+   template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+   inline typename dtl::enable_if_and\
+      < void\
+      , dtl::is_not_pair<T>\
+      , uses_allocator<T, ArgAlloc>\
+      , is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\
+      >::type\
+      dispatch_uses_allocator\
+      (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      allocator_traits<ConstructAlloc>::construct\
+         (construct_alloc, p, allocator_arg, ::boost::forward<ArgAlloc>(arg_alloc) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+   }\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
+
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
+   template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+   inline typename dtl::enable_if_and\
+      < void\
+      , dtl::is_not_pair<T>\
+      , uses_allocator<T, ArgAlloc>\
+      , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\
+      >::type\
+      dispatch_uses_allocator\
+      (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      allocator_traits<ConstructAlloc>::construct\
+         (construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, ::boost::forward<ArgAlloc>(arg_alloc));\
+   }\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
+
+#endif   //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , typename Pair
+         > inline 
+BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type)
+   dispatch_uses_allocator
+   ( ConstructAlloc & construct_alloc
+   , BOOST_FWD_REF(ArgAlloc) arg_alloc
+   , Pair* p)
+{
+   (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first));
+   BOOST_TRY{
+      (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second));
+   }
+   BOOST_CATCH(...) {
+      allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
+      BOOST_RETHROW
+   }
+   BOOST_CATCH_END
+}
+
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , class Pair, class U, class V>
+BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type)
+   dispatch_uses_allocator
+   ( ConstructAlloc & construct_alloc
+   , BOOST_FWD_REF(ArgAlloc) arg_alloc
+   , Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+{
+   (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x));
+   BOOST_TRY{
+      (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y));
+   }
+   BOOST_CATCH(...){
+      allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
+      BOOST_RETHROW
+   }
+   BOOST_CATCH_END
+}
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , class Pair, class Pair2>
+BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> >::type)
+   dispatch_uses_allocator
+   (ConstructAlloc & construct_alloc
+   , BOOST_FWD_REF(ArgAlloc) arg_alloc
+   , Pair* p, Pair2& x)
+{  (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, x.first, x.second);  }
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , class Pair, class Pair2>
+typename dtl::enable_if_and
+   < void
+   , dtl::is_pair<Pair>
+   , dtl::not_<boost::move_detail::is_reference<Pair2> > >::type //This is needed for MSVC10 and ambiguous overloads
+   dispatch_uses_allocator
+   (ConstructAlloc & construct_alloc
+      , BOOST_FWD_REF(ArgAlloc) arg_alloc
+      , Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x)
+{  (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second));  }
+
+
+//piecewise construction from boost::tuple
+#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
+template< typename ConstructAlloc, typename ArgAlloc, class Pair \
+        , template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
+         BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+typename dtl::enable_if< dtl::is_pair<Pair> >::type\
+   dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
+      , BoostTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
+      , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
+{\
+   (void)p; (void)q;\
+   (dispatch_uses_allocator)\
+      (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\
+   BOOST_TRY{\
+      (dispatch_uses_allocator)\
+         (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\
+   }\
+   BOOST_CATCH(...) {\
+      allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
+      BOOST_RETHROW\
+   }\
+   BOOST_CATCH_END\
+}\
+//
+BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
+#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
+
+//piecewise construction from Std Tuple
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template< typename ConstructAlloc, typename ArgAlloc, class Pair
+           , template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
+   void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair
+                                    , Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
+   {
+      (void)t1; (void)t2;
+      (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...);
+      BOOST_TRY{
+         (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...);
+      }
+      BOOST_CATCH(...){
+         allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template< typename ConstructAlloc, typename ArgAlloc, class Pair
+           , template<class ...> class Tuple, class... Args1, class... Args2>
+   typename dtl::enable_if< dtl::is_pair<Pair> >::type
+      dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t
+                             , Tuple<Args1...> t1, Tuple<Args2...> t2)
+   {
+      (dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2
+                                     , typename build_number_seq<sizeof...(Args1)>::type()
+                                     , typename build_number_seq<sizeof...(Args2)>::type());
+   }
+
+#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
+
+   //MSVC 2010 tuple implementation
+   #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
+   template< typename ConstructAlloc, typename ArgAlloc, class Pair\
+           , template<class, class, class, class, class, class, class, class, class, class> class StdTuple\
+            BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+   typename dtl::enable_if< dtl::is_pair<Pair> >::type\
+      dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
+                           , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
+                           , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
+   {\
+      (void)p; (void)q;\
+      (dispatch_uses_allocator)\
+         (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
+      BOOST_TRY{\
+         (dispatch_uses_allocator)\
+            (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
+      }\
+      BOOST_CATCH(...) {\
+         allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
+         BOOST_RETHROW\
+      }\
+      BOOST_CATCH_END\
+   }\
+   //
+   BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
+   #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
+
+#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
+   #if _VARIADIC_MAX >= 9
+   #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
+   #else
+   #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
+   #endif
+
+   //MSVC 2012 tuple implementation
+   #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
+   template< typename ConstructAlloc, typename ArgAlloc, class Pair\
+            , template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
+            BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+   typename dtl::enable_if< dtl::is_pair<Pair> >::type\
+      dispatch_uses_allocator\
+         ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
+         , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
+         , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
+   {\
+      (void)p; (void)q;\
+      (dispatch_uses_allocator)\
+         (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
+      BOOST_TRY{\
+         (dispatch_uses_allocator)\
+            (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
+      }\
+      BOOST_CATCH(...) {\
+         allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
+         BOOST_RETHROW\
+      }\
+      BOOST_CATCH_END\
+   }\
+   //
+   BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
+   #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
+   #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
+
+#endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template < typename ConstructAlloc
+         , typename ArgAlloc
+         , class Pair, class KeyType, class ... Args>
+typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
+   dispatch_uses_allocator
+   (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
+{
+   (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));
+   BOOST_TRY{
+      (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...);
+   }
+   BOOST_CATCH(...) {
+      allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
+      BOOST_RETHROW
+   }
+   BOOST_CATCH_END
+}
+
+#else
+
+#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \
+   template <typename ConstructAlloc, typename ArgAlloc, class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+   inline typename dtl::enable_if\
+      < dtl::is_pair<Pair>, void >::type\
+      dispatch_uses_allocator\
+      (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \
+       BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
+      BOOST_TRY{\
+         (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      }\
+      BOOST_CATCH(...) {\
+         allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));\
+         BOOST_RETHROW\
+      }\
+      BOOST_CATCH_END\
+   }\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE)
+#undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE
+
+#endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+}  //namespace dtl
+
+}} // namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //  BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
diff --git a/include/boost/container/detail/dlmalloc.hpp b/include/boost/container/detail/dlmalloc.hpp
new file mode 100644
index 0000000..15086c3
--- /dev/null
+++ b/include/boost/container/detail/dlmalloc.hpp
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_DETAIL_ALLOC_LIB_HPP
+#define BOOST_CONTAINER_DETAIL_ALLOC_LIB_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/detail/alloc_lib.h>
+
+namespace boost{
+namespace container{
+
+typedef boost_cont_command_ret_t dlmalloc_command_ret_t;
+typedef boost_cont_memchain dlmalloc_memchain;
+typedef boost_cont_memchain_it dlmalloc_memchain_it;
+typedef boost_cont_malloc_stats_t dlmalloc_malloc_stats_t;
+
+BOOST_CONTAINER_DECL size_t dlmalloc_size(const void *p);
+
+BOOST_CONTAINER_DECL void* dlmalloc_malloc(size_t bytes);
+
+BOOST_CONTAINER_DECL void  dlmalloc_free(void* mem);
+
+BOOST_CONTAINER_DECL void* dlmalloc_memalign(size_t bytes, size_t alignment);
+
+BOOST_CONTAINER_DECL int dlmalloc_multialloc_nodes
+   (size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
+
+BOOST_CONTAINER_DECL int dlmalloc_multialloc_arrays
+   (size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
+
+BOOST_CONTAINER_DECL void dlmalloc_multidealloc(boost_cont_memchain *pchain);
+
+BOOST_CONTAINER_DECL size_t dlmalloc_footprint();
+
+BOOST_CONTAINER_DECL size_t dlmalloc_allocated_memory();
+
+BOOST_CONTAINER_DECL size_t dlmalloc_chunksize(const void *p);
+
+BOOST_CONTAINER_DECL int dlmalloc_all_deallocated();
+
+BOOST_CONTAINER_DECL boost_cont_malloc_stats_t dlmalloc_malloc_stats();
+
+BOOST_CONTAINER_DECL size_t dlmalloc_in_use_memory();
+
+BOOST_CONTAINER_DECL int dlmalloc_trim(size_t pad);
+
+BOOST_CONTAINER_DECL int dlmalloc_mallopt(int parameter_number, int parameter_value);
+
+BOOST_CONTAINER_DECL int dlmalloc_grow(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
+
+BOOST_CONTAINER_DECL int dlmalloc_shrink(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
+
+BOOST_CONTAINER_DECL void* dlmalloc_alloc(size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
+
+BOOST_CONTAINER_DECL int dlmalloc_malloc_check();
+
+BOOST_CONTAINER_DECL boost_cont_command_ret_t dlmalloc_allocation_command
+   ( allocation_type command
+   , size_t sizeof_object
+   , size_t limit_objects
+   , size_t preferred_objects
+   , size_t *received_objects
+   , void *reuse_ptr
+   );
+
+BOOST_CONTAINER_DECL int dlmalloc_mallopt(int param_number, int value);
+
+BOOST_CONTAINER_DECL void *dlmalloc_sync_create();
+
+BOOST_CONTAINER_DECL void dlmalloc_sync_destroy(void *sync);
+
+BOOST_CONTAINER_DECL bool dlmalloc_sync_lock(void *sync);
+
+BOOST_CONTAINER_DECL void dlmalloc_sync_unlock(void *sync);
+
+BOOST_CONTAINER_DECL bool dlmalloc_global_sync_lock();
+
+BOOST_CONTAINER_DECL void dlmalloc_global_sync_unlock();
+
+}  //namespace container{
+}  //namespace boost{
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_ALLOC_LIB_HPP
diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp
new file mode 100644
index 0000000..e9cbe38
--- /dev/null
+++ b/include/boost/container/detail/flat_tree.hpp
@@ -0,0 +1,1621 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_FLAT_TREE_HPP
+#define BOOST_CONTAINER_FLAT_TREE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/utility_core.hpp>
+
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/allocator_traits.hpp>
+
+#include <boost/container/detail/value_init.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/is_sorted.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/is_contiguous_container.hpp>
+#include <boost/container/detail/is_container.hpp>
+
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+
+#include <boost/move/make_unique.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/algo/adaptive_sort.hpp>
+#include <boost/move/algo/detail/pdqsort.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//merge_unique
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME merge_unique
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//merge_equal
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME merge
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//index_of
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME index_of
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//nth
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME nth
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//reserve
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME reserve
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//capacity
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME capacity
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+///////////////////////////////////////
+//
+// Helper functions to merge elements
+//
+///////////////////////////////////////
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
+
+///////////////////////////////////////
+//
+//  flat_tree_container_inplace_merge
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Compare>
+void flat_tree_container_inplace_merge //is_contiguous_container == true
+   (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_)
+{
+   typedef typename SequenceContainer::value_type  value_type;
+   value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
+   value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
+   value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
+   boost::movelib::adaptive_merge(braw, iraw, eraw, comp, eraw, dest.capacity()- dest.size());
+}
+
+template<class SequenceContainer, class Compare>
+void flat_tree_container_inplace_merge //is_contiguous_container == false
+   (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::false_)
+{
+   boost::movelib::adaptive_merge(dest.begin(), it, dest.end(), comp);
+}
+
+///////////////////////////////////////
+//
+//  flat_tree_container_inplace_sort_ending
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Compare>
+void flat_tree_container_inplace_sort_ending //is_contiguous_container == true
+   (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::true_)
+{
+   typedef typename SequenceContainer::value_type  value_type;
+   value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
+   value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
+   boost::movelib::adaptive_sort(iraw, eraw, comp, eraw, dest.capacity()- dest.size());
+}
+
+template<class SequenceContainer, class Compare>
+void flat_tree_container_inplace_sort_ending //is_contiguous_container == false
+   (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::false_)
+{
+   boost::movelib::adaptive_sort(it, dest.end(), comp);
+}
+
+///////////////////////////////////////
+//
+//          flat_tree_merge
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Iterator, class Compare>
+BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
+   (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_)
+{
+   dest.merge(first, last, comp);
+}
+
+template<class SequenceContainer, class Iterator, class Compare>
+BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal   //has_merge_unique == false
+   (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_)
+{
+   typedef typename SequenceContainer::iterator    iterator;
+   iterator const it = dest.insert( dest.end(), first, last );
+   dtl::bool_<is_contiguous_container<SequenceContainer>::value> contiguous_tag;
+   (flat_tree_container_inplace_merge)(dest, it, comp, contiguous_tag);
+}
+
+///////////////////////////////////////
+//
+//       flat_tree_merge_unique
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Iterator, class Compare>
+BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique  //has_merge_unique == true
+   (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_)
+{
+   dest.merge_unique(first, last, comp);
+}
+
+template<class SequenceContainer, class Iterator, class Compare>
+BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique  //has_merge_unique == false
+   (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_)
+{
+   typedef typename SequenceContainer::iterator    iterator;
+   typedef typename SequenceContainer::size_type   size_type;
+
+   size_type const old_sz = dest.size();
+   iterator const first_new = dest.insert(dest.cend(), first, last );
+   iterator e = boost::movelib::inplace_set_difference(first_new, dest.end(), dest.begin(), first_new, comp);
+   dest.erase(e, dest.end());
+   dtl::bool_<is_contiguous_container<SequenceContainer>::value> contiguous_tag;
+   (flat_tree_container_inplace_merge)(dest, dest.begin()+old_sz, comp, contiguous_tag);
+}
+
+///////////////////////////////////////
+//
+//         flat_tree_index_of
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Iterator>
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
+   flat_tree_index_of   // has_index_of == true
+      (SequenceContainer& cont, Iterator p, dtl::true_)
+{
+   return cont.index_of(p);
+}
+
+template<class SequenceContainer, class Iterator>
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
+   flat_tree_index_of   // has_index_of == false
+      (SequenceContainer& cont, Iterator p, dtl::false_)
+{
+   typedef typename SequenceContainer::size_type size_type;
+   return static_cast<size_type>(p - cont.begin());
+}
+
+///////////////////////////////////////
+//
+//         flat_tree_nth
+//
+///////////////////////////////////////
+template<class Iterator, class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE Iterator
+   flat_tree_nth  // has_nth == true
+      (SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::true_)
+{
+   return cont.nth(n);
+}
+
+template<class Iterator, class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE Iterator
+   flat_tree_nth  // has_nth == false
+      (SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::false_)
+{
+   return cont.begin()+ n;
+}
+
+///////////////////////////////////////
+//
+//    flat_tree_get_stored_allocator
+//
+///////////////////////////////////////
+template<class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::stored_allocator_type &
+   flat_tree_get_stored_allocator   // has_get_stored_allocator == true
+      (SequenceContainer& cont, dtl::true_)
+{
+   return cont.get_stored_allocator();
+}
+
+template<class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_type &
+   flat_tree_get_stored_allocator   // has_get_stored_allocator == true
+      (const SequenceContainer& cont, dtl::true_)
+{
+   return cont.get_stored_allocator();
+}
+
+template<class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type
+   flat_tree_get_stored_allocator   // has_get_stored_allocator == false
+      (SequenceContainer& cont, dtl::false_)
+{
+   return cont.get_allocator();
+}
+
+///////////////////////////////////////
+//
+//    flat_tree_adopt_sequence_equal
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Compare>
+void flat_tree_sort_contiguous_to_adopt // is_contiguous_container == true
+   (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp)
+{
+   if(tseq.capacity() >= (seq.capacity() - seq.size())) {
+      tseq.clear();
+      boost::movelib::adaptive_sort
+      (boost::movelib::iterator_to_raw_pointer(seq.begin())
+         , boost::movelib::iterator_to_raw_pointer(seq.end())
+         , comp
+         , boost::movelib::iterator_to_raw_pointer(tseq.begin())
+         , tseq.capacity());
+   }
+   else{
+      boost::movelib::adaptive_sort
+      (boost::movelib::iterator_to_raw_pointer(seq.begin())
+         , boost::movelib::iterator_to_raw_pointer(seq.end())
+         , comp
+         , boost::movelib::iterator_to_raw_pointer(seq.end())
+         , seq.capacity() - seq.size());
+   }
+}
+
+template<class SequenceContainer, class Compare>
+void flat_tree_adopt_sequence_equal // is_contiguous_container == true
+   (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_)
+{
+   flat_tree_sort_contiguous_to_adopt(tseq, boost::move(seq), comp);
+   tseq = boost::move(seq);
+}
+
+template<class SequenceContainer, class Compare>
+void flat_tree_adopt_sequence_equal // is_contiguous_container == false
+   (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_)
+{
+   boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
+   tseq = boost::move(seq);
+}
+
+///////////////////////////////////////
+//
+//    flat_tree_adopt_sequence_unique
+//
+///////////////////////////////////////
+template<class SequenceContainer, class Compare>
+void flat_tree_adopt_sequence_unique// is_contiguous_container == true
+   (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_)
+{
+   boost::movelib::pdqsort
+      ( boost::movelib::iterator_to_raw_pointer(seq.begin())
+      , boost::movelib::iterator_to_raw_pointer(seq.end())
+      , comp);
+   seq.erase(boost::movelib::unique
+      (seq.begin(), seq.end(), boost::movelib::negate<Compare>(comp)), seq.cend());
+   tseq = boost::move(seq);
+}
+
+template<class SequenceContainer, class Compare>
+void flat_tree_adopt_sequence_unique// is_contiguous_container == false
+   (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_)
+{
+   boost::movelib::pdqsort(seq.begin(), seq.end(), comp);
+   seq.erase(boost::movelib::unique
+      (seq.begin(), seq.end(), boost::movelib::negate<Compare>(comp)), seq.cend());
+   tseq = boost::move(seq);
+}
+
+///////////////////////////////////////
+//
+//       flat_tree_reserve
+//
+///////////////////////////////////////
+template<class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE void // has_reserve == true
+   flat_tree_reserve(SequenceContainer &tseq, typename SequenceContainer::size_type cap, dtl::true_)
+{
+   tseq.reserve(cap);
+}
+
+template<class SequenceContainer>
+BOOST_CONTAINER_FORCEINLINE void // has_reserve == false
+   flat_tree_reserve(SequenceContainer &, typename SequenceContainer::size_type, dtl::false_)
+{
+}
+
+///////////////////////////////////////
+//
+//       flat_tree_capacity
+//
+///////////////////////////////////////
+template<class SequenceContainer>   // has_capacity == true
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
+   flat_tree_capacity(const SequenceContainer &tseq, dtl::true_)
+{
+   return tseq.capacity();
+}
+
+template<class SequenceContainer>   // has_capacity == false
+BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
+   flat_tree_capacity(const SequenceContainer &tseq, dtl::false_)
+{
+   return tseq.size();
+}
+
+///////////////////////////////////////
+//
+//       flat_tree_value_compare
+//
+///////////////////////////////////////
+
+template<class Compare, class Value, class KeyOfValue>
+class flat_tree_value_compare
+   : private Compare
+{
+   typedef Value              first_argument_type;
+   typedef Value              second_argument_type;
+   typedef bool               return_type;
+   public:
+   flat_tree_value_compare()
+      : Compare()
+   {}
+
+   flat_tree_value_compare(const Compare &pred)
+      : Compare(pred)
+   {}
+
+   bool operator()(const Value& lhs, const Value& rhs) const
+   {
+      KeyOfValue key_extract;
+      return Compare::operator()(key_extract(lhs), key_extract(rhs));
+   }
+
+   const Compare &get_comp() const
+      {  return *this;  }
+
+   Compare &get_comp()
+      {  return *this;  }
+};
+
+///////////////////////////////////////
+//
+//       select_container_type
+//
+///////////////////////////////////////
+template < class Value, class AllocatorOrContainer
+         , bool = boost::container::dtl::is_container<AllocatorOrContainer>::value >
+struct select_container_type
+{
+   typedef AllocatorOrContainer type;
+};
+
+template <class Value, class AllocatorOrContainer>
+struct select_container_type<Value, AllocatorOrContainer, false>
+{
+   typedef boost::container::vector<Value, AllocatorOrContainer> type;
+};
+
+
+///////////////////////////////////////
+//
+//          flat_tree
+//
+///////////////////////////////////////
+template <class Value, class KeyOfValue,
+          class Compare, class AllocatorOrContainer>
+class flat_tree
+{
+   public:
+   typedef typename select_container_type<Value, AllocatorOrContainer>::type container_type;
+   typedef container_type sequence_type;  //For backwards compatibility
+
+   private:
+   typedef typename container_type::allocator_type        allocator_t;
+   typedef allocator_traits<allocator_t>                 allocator_traits_type;
+
+   public:
+   typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
+
+   private:
+   
+   struct Data
+      //Inherit from value_compare to do EBO
+      : public value_compare
+   {
+      BOOST_COPYABLE_AND_MOVABLE(Data)
+
+      public:
+      Data()
+         : value_compare(), m_seq()
+      {}
+
+      explicit Data(const allocator_t &alloc)
+         : value_compare(), m_seq(alloc)
+      {}
+
+      explicit Data(const Compare &comp)
+         : value_compare(comp), m_seq()
+      {}
+
+      Data(const Compare &comp, const allocator_t &alloc)
+         : value_compare(comp), m_seq(alloc)
+      {}
+
+      explicit Data(const Data &d)
+         : value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq)
+      {}
+
+      Data(BOOST_RV_REF(Data) d)
+         : value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq))
+      {}
+
+      Data(const Data &d, const allocator_t &a)
+         : value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq, a)
+      {}
+
+      Data(BOOST_RV_REF(Data) d, const allocator_t &a)
+         : value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq), a)
+      {}
+
+      Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d)
+      {
+         this->value_compare::operator=(d);
+         m_seq = d.m_seq;
+         return *this;
+      }
+
+      Data& operator=(BOOST_RV_REF(Data) d)
+      {
+         this->value_compare::operator=(boost::move(static_cast<value_compare &>(d)));
+         m_seq = boost::move(d.m_seq);
+         return *this;
+      }
+
+      void swap(Data &d)
+      {
+         value_compare& mycomp    = *this, & othercomp = d;
+         boost::adl_move_swap(mycomp, othercomp);
+         this->m_seq.swap(d.m_seq);
+      }
+
+      container_type m_seq;
+   };
+
+   Data m_data;
+   BOOST_COPYABLE_AND_MOVABLE(flat_tree)
+
+   public:
+
+   typedef typename container_type::value_type               value_type;
+   typedef typename container_type::pointer                  pointer;
+   typedef typename container_type::const_pointer            const_pointer;
+   typedef typename container_type::reference                reference;
+   typedef typename container_type::const_reference          const_reference;
+   typedef typename KeyOfValue::type                        key_type;
+   typedef Compare                                          key_compare;
+   typedef typename container_type::allocator_type           allocator_type;
+   typedef typename container_type::size_type                size_type;
+   typedef typename container_type::difference_type          difference_type;
+   typedef typename container_type::iterator                 iterator;
+   typedef typename container_type::const_iterator           const_iterator;
+   typedef typename container_type::reverse_iterator         reverse_iterator;
+   typedef typename container_type::const_reverse_iterator   const_reverse_iterator;
+
+   //!Standard extension
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+      (boost::container::dtl::, container_type
+      ,stored_allocator_type, allocator_type)               stored_allocator_type;
+
+   static const bool has_stored_allocator_type =
+      BOOST_INTRUSIVE_HAS_TYPE(boost::container::dtl::, container_type, stored_allocator_type);
+
+   private:
+   typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
+
+   public:
+   typedef typename dtl::if_c
+      <has_stored_allocator_type, const stored_allocator_type &, allocator_type>::type get_stored_allocator_const_return_t;
+
+   typedef typename dtl::if_c
+      <has_stored_allocator_type, stored_allocator_type &, allocator_type>::type get_stored_allocator_noconst_return_t;
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree()
+      : m_data()
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const Compare& comp)
+      : m_data(comp)
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const allocator_type& a)
+      : m_data(a)
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree(const Compare& comp, const allocator_type& a)
+      : m_data(comp, a)
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x)
+      :  m_data(x.m_data)
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      :  m_data(boost::move(x.m_data))
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x, const allocator_type &a)
+      :  m_data(x.m_data, a)
+   { }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
+      :  m_data(boost::move(x.m_data), a)
+   { }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_range_t, InputIterator first, InputIterator last)
+      : m_data()
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : m_data(comp)
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_data(comp, a)
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last)
+      : m_data()
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : m_data(comp)
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_data(comp, a)
+   {
+      this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last);
+      BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp()));
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( bool unique_insertion, InputIterator first, InputIterator last)
+      : m_data()
+   {
+      this->priv_range_insertion_construct(unique_insertion, first, last);
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+            , const Compare& comp)
+      : m_data(comp)
+   {
+      this->priv_range_insertion_construct(unique_insertion, first, last);
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+            , const allocator_type& a)
+      : m_data(a)
+   {
+      this->priv_range_insertion_construct(unique_insertion, first, last);
+   }
+
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+            , const Compare& comp, const allocator_type& a)
+      : m_data(comp, a)
+   {
+      this->priv_range_insertion_construct(unique_insertion, first, last);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE ~flat_tree()
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree&  operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
+   {  m_data = x.m_data;   return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE flat_tree&  operator=(BOOST_RV_REF(flat_tree) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  m_data = boost::move(x.m_data); return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE const value_compare &priv_value_comp() const
+   { return static_cast<const value_compare &>(this->m_data); }
+
+   BOOST_CONTAINER_FORCEINLINE value_compare &priv_value_comp()
+   { return static_cast<value_compare &>(this->m_data); }
+
+   BOOST_CONTAINER_FORCEINLINE const key_compare &priv_key_comp() const
+   { return this->priv_value_comp().get_comp(); }
+
+   BOOST_CONTAINER_FORCEINLINE key_compare &priv_key_comp()
+   { return this->priv_value_comp().get_comp(); }
+
+   struct insert_commit_data
+   {
+      const_iterator position;
+   };
+
+   public:
+   // accessors:
+   BOOST_CONTAINER_FORCEINLINE Compare key_comp() const
+   { return this->m_data.get_comp(); }
+
+   BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
+   { return this->m_data; }
+
+   BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
+   { return this->m_data.m_seq.get_allocator(); }
+
+   BOOST_CONTAINER_FORCEINLINE get_stored_allocator_const_return_t get_stored_allocator() const
+   {
+      return flat_tree_get_stored_allocator(this->m_data.m_seq, dtl::bool_<has_stored_allocator_type>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE get_stored_allocator_noconst_return_t get_stored_allocator()
+   {
+      return flat_tree_get_stored_allocator(this->m_data.m_seq, dtl::bool_<has_stored_allocator_type>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator begin()
+   { return this->m_data.m_seq.begin(); }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
+   { return this->cbegin(); }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
+   { return this->m_data.m_seq.begin(); }
+
+   BOOST_CONTAINER_FORCEINLINE iterator end()
+   { return this->m_data.m_seq.end(); }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator end() const
+   { return this->cend(); }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
+   { return this->m_data.m_seq.end(); }
+
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
+   { return reverse_iterator(this->end()); }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
+   {  return this->crbegin();  }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
+   {  return const_reverse_iterator(this->cend());  }
+
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
+   { return reverse_iterator(this->begin()); }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
+   { return this->crend(); }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
+   { return const_reverse_iterator(this->cbegin()); }
+
+   BOOST_CONTAINER_FORCEINLINE bool empty() const
+   { return this->m_data.m_seq.empty(); }
+
+   BOOST_CONTAINER_FORCEINLINE size_type size() const
+   { return this->m_data.m_seq.size(); }
+
+   BOOST_CONTAINER_FORCEINLINE size_type max_size() const
+   { return this->m_data.m_seq.max_size(); }
+
+   BOOST_CONTAINER_FORCEINLINE void swap(flat_tree& other)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
+   {  this->m_data.swap(other.m_data);  }
+
+   public:
+   // insert/erase
+   std::pair<iterator,bool> insert_unique(const value_type& val)
+   {
+      std::pair<iterator,bool> ret;
+      insert_commit_data data;
+      ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
+      ret.first = ret.second ? this->priv_insert_commit(data, val)
+                             : this->begin() + (data.position - this->cbegin());
+                             //: iterator(vector_iterator_get_ptr(data.position));
+      return ret;
+   }
+
+   std::pair<iterator,bool> insert_unique(BOOST_RV_REF(value_type) val)
+   {
+      std::pair<iterator,bool> ret;
+      insert_commit_data data;
+      ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
+      ret.first = ret.second ? this->priv_insert_commit(data, boost::move(val))
+                             : this->begin() + (data.position - this->cbegin());
+                             //: iterator(vector_iterator_get_ptr(data.position));
+      return ret;
+   }
+
+   iterator insert_equal(const value_type& val)
+   {
+      iterator i = this->upper_bound(KeyOfValue()(val));
+      i = this->m_data.m_seq.insert(i, val);
+      return i;
+   }
+
+   iterator insert_equal(BOOST_RV_REF(value_type) mval)
+   {
+      iterator i = this->upper_bound(KeyOfValue()(mval));
+      i = this->m_data.m_seq.insert(i, boost::move(mval));
+      return i;
+   }
+
+   iterator insert_unique(const_iterator hint, const value_type& val)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(hint));
+      insert_commit_data data;
+      return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
+            ? this->priv_insert_commit(data, val)
+            : this->begin() + (data.position - this->cbegin());
+            //: iterator(vector_iterator_get_ptr(data.position));
+   }
+
+   iterator insert_unique(const_iterator hint, BOOST_RV_REF(value_type) val)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(hint));
+      insert_commit_data data;
+      return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
+         ? this->priv_insert_commit(data, boost::move(val))
+         : this->begin() + (data.position - this->cbegin());
+         //: iterator(vector_iterator_get_ptr(data.position));
+   }
+
+   iterator insert_equal(const_iterator hint, const value_type& val)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(hint));
+      insert_commit_data data;
+      this->priv_insert_equal_prepare(hint, val, data);
+      return this->priv_insert_commit(data, val);
+   }
+
+   iterator insert_equal(const_iterator hint, BOOST_RV_REF(value_type) mval)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(hint));
+      insert_commit_data data;
+      this->priv_insert_equal_prepare(hint, mval, data);
+      return this->priv_insert_commit(data, boost::move(mval));
+   }
+
+   template <class InIt>
+   void insert_unique(InIt first, InIt last)
+   {
+      dtl::bool_<is_contiguous_container<container_type>::value> contiguous_tag;
+      container_type &seq = this->m_data.m_seq;
+      value_compare &val_cmp = this->priv_value_comp();
+
+      //Step 1: put new elements in the back
+      typename container_type::iterator const it = seq.insert(seq.cend(), first, last);
+
+      //Step 2: sort them
+      boost::movelib::pdqsort(it, seq.end(), val_cmp);
+
+      //Step 3: only left unique values from the back not already present in the original range
+      typename container_type::iterator const e = boost::movelib::inplace_set_unique_difference
+         (it, seq.end(), seq.begin(), it, val_cmp);
+      seq.erase(e, seq.cend());
+
+      //Step 4: merge both ranges
+      (flat_tree_container_inplace_merge)(seq, it, this->priv_value_comp(), contiguous_tag);
+   }
+
+   template <class InIt>
+   void insert_equal(InIt first, InIt last)
+   {
+      dtl::bool_<is_contiguous_container<container_type>::value> contiguous_tag;
+      container_type &seq = this->m_data.m_seq;
+      typename container_type::iterator const it = seq.insert(seq.cend(), first, last);
+      (flat_tree_container_inplace_sort_ending)(seq, it, this->priv_value_comp(), contiguous_tag);
+      (flat_tree_container_inplace_merge)      (seq, it, this->priv_value_comp(), contiguous_tag);
+   }
+
+   //Ordered
+
+   template <class InIt>
+   void insert_equal(ordered_range_t, InIt first, InIt last)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_merge_unique<container_type, InIt, InIt, value_compare>::value;
+      (flat_tree_merge_equal)(this->m_data.m_seq, first, last, this->priv_value_comp(), dtl::bool_<value>());
+   }
+
+   template <class InIt>
+   void insert_unique(ordered_unique_range_t, InIt first, InIt last)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_merge_unique<container_type, InIt, InIt, value_compare>::value;
+      (flat_tree_merge_unique)(this->m_data.m_seq, first, last, this->priv_value_comp(), dtl::bool_<value>());
+   }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <class... Args>
+   std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
+   {
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
+      stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
+      value_destructor<stored_allocator_type, value_type> d(a, val);
+      return this->insert_unique(::boost::move(val));
+   }
+
+   template <class... Args>
+   iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {
+      //hint checked in insert_unique
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
+      stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
+      value_destructor<stored_allocator_type, value_type> d(a, val);
+      return this->insert_unique(hint, ::boost::move(val));
+   }
+
+   template <class... Args>
+   iterator emplace_equal(BOOST_FWD_REF(Args)... args)
+   {
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
+      stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
+      value_destructor<stored_allocator_type, value_type> d(a, val);
+      return this->insert_equal(::boost::move(val));
+   }
+
+   template <class... Args>
+   iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {
+      //hint checked in insert_equal
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
+      stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
+      value_destructor<stored_allocator_type, value_type> d(a, val);
+      return this->insert_equal(hint, ::boost::move(val));
+   }
+
+   template <class KeyType, class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace
+      (const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
+   {
+      std::pair<iterator,bool> ret;
+      insert_commit_data data;
+      const key_type & k = key;
+      ret.second = hint == const_iterator()
+         ? this->priv_insert_unique_prepare(k, data)
+         : this->priv_insert_unique_prepare(hint, k, data);
+
+      if(!ret.second){
+         ret.first  = this->nth(data.position - this->cbegin());
+      }
+      else{
+         typedef typename emplace_functor_type<try_emplace_t, KeyType, Args...>::type func_t;
+         typedef emplace_iterator<value_type, func_t, difference_type> it_t;
+         func_t func(try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(args)...);
+         ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
+      }
+      return ret;
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
+   {\
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));\
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
+      stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      value_destructor<stored_allocator_type, value_type> d(a, val);\
+      return this->insert_unique(::boost::move(val));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));\
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
+      stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      value_destructor<stored_allocator_type, value_type> d(a, val);\
+      return this->insert_unique(hint, ::boost::move(val));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_equal(BOOST_MOVE_UREF##N)\
+   {\
+      typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));\
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
+      stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      value_destructor<stored_allocator_type, value_type> d(a, val);\
+      return this->insert_equal(::boost::move(val));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\
+      value_type &val = *static_cast<value_type *>(static_cast<void *>(v.data));\
+      get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
+      stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      value_destructor<stored_allocator_type, value_type> d(a, val);\
+      return this->insert_equal(hint, ::boost::move(val));\
+   }\
+   template <class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool>\
+      try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      std::pair<iterator,bool> ret;\
+      insert_commit_data data;\
+      const key_type & k = key;\
+      ret.second = hint == const_iterator()\
+         ? this->priv_insert_unique_prepare(k, data)\
+         : this->priv_insert_unique_prepare(hint, k, data);\
+      \
+      if(!ret.second){\
+         ret.first  = this->nth(data.position - this->cbegin());\
+      }\
+      else{\
+         typedef typename emplace_functor_type<try_emplace_t, KeyType BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::type func_t;\
+         typedef emplace_iterator<value_type, func_t, difference_type> it_t;\
+         func_t func(try_emplace_t(), ::boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+         ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());\
+      }\
+      return ret;\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO7(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template<class KeyType, class M>
+   std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
+   {
+      const key_type& k = key;
+      std::pair<iterator,bool> ret;
+      insert_commit_data data;
+      ret.second = hint == const_iterator()
+         ? this->priv_insert_unique_prepare(k, data)
+         : this->priv_insert_unique_prepare(hint, k, data);
+      if(!ret.second){
+         ret.first  = this->nth(data.position - this->cbegin());
+         ret.first->second = boost::forward<M>(obj);
+      }
+      else{
+         typedef typename emplace_functor_type<KeyType, M>::type func_t;
+         typedef emplace_iterator<value_type, func_t, difference_type> it_t;
+         func_t func(boost::forward<KeyType>(key), boost::forward<M>(obj));
+         ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
+      }
+      return ret;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator position)
+   {  return this->m_data.m_seq.erase(position);  }
+
+   size_type erase(const key_type& k)
+   {
+      std::pair<iterator,iterator > itp = this->equal_range(k);
+      size_type ret = static_cast<size_type>(itp.second-itp.first);
+      if (ret){
+         this->m_data.m_seq.erase(itp.first, itp.second);
+      }
+      return ret;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
+   {  return this->m_data.m_seq.erase(first, last);  }
+
+   BOOST_CONTAINER_FORCEINLINE void clear()
+   {  this->m_data.m_seq.clear();  }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
+   {  this->m_data.m_seq.shrink_to_fit();  }
+
+   BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_nth<container_type, size_type>::value;
+      return flat_tree_nth<iterator>(this->m_data.m_seq, n, dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_nth<container_type, size_type>::value;
+      return flat_tree_nth<const_iterator>(this->m_data.m_seq, n, dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_index_of<container_type, iterator>::value;
+      return flat_tree_index_of(this->m_data.m_seq, p, dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_index_of<container_type, const_iterator>::value;
+      return flat_tree_index_of(this->m_data.m_seq, p, dtl::bool_<value>());
+   }
+
+   // set operations:
+   iterator find(const key_type& k)
+   {
+      iterator i = this->lower_bound(k);
+      iterator end_it = this->end();
+      if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
+         i = end_it;
+      }
+      return i;
+   }
+
+   const_iterator find(const key_type& k) const
+   {
+      const_iterator i = this->lower_bound(k);
+
+      const_iterator end_it = this->cend();
+      if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
+         i = end_it;
+      }
+      return i;
+   }
+
+   template<class K>
+   typename dtl::enable_if_transparent<key_compare, K, iterator>::type
+      find(const K& k)
+   {
+      iterator i = this->lower_bound(k);
+      iterator end_it = this->end();
+      if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
+         i = end_it;
+      }
+      return i;
+   }
+
+   template<class K>
+   typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type
+      find(const K& k) const
+   {
+      const_iterator i = this->lower_bound(k);
+
+      const_iterator end_it = this->cend();
+      if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
+         i = end_it;
+      }
+      return i;
+   }
+
+   size_type count(const key_type& k) const
+   {
+      std::pair<const_iterator, const_iterator> p = this->equal_range(k);
+      size_type n = p.second - p.first;
+      return n;
+   }
+
+   template<class K>
+   typename dtl::enable_if_transparent<key_compare, K, size_type>::type
+      count(const K& k) const
+   {
+      std::pair<const_iterator, const_iterator> p = this->equal_range(k);
+      size_type n = p.second - p.first;
+      return n;
+   }
+
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge_unique(flat_tree<Value, KeyOfValue, C2, AllocatorOrContainer>& source)
+   {
+      this->insert( boost::make_move_iterator(source.begin())
+                  , boost::make_move_iterator(source.end()));
+   }
+
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge_equal(flat_tree<Value, KeyOfValue, C2, AllocatorOrContainer>& source)
+   {
+      this->insert( boost::make_move_iterator(source.begin())
+                  , boost::make_move_iterator(source.end()));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void merge_unique(flat_tree& source)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_merge_unique<container_type, iterator, iterator, value_compare>::value;
+      (flat_tree_merge_unique)
+         ( this->m_data.m_seq
+         , boost::make_move_iterator(source.m_data.m_seq.begin())
+         , boost::make_move_iterator(source.m_data.m_seq.end())
+         , this->priv_value_comp()
+         , dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void merge_equal(flat_tree& source)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_merge<container_type, iterator, iterator, value_compare>::value;
+      (flat_tree_merge_equal)
+         ( this->m_data.m_seq
+         , boost::make_move_iterator(source.m_data.m_seq.begin())
+         , boost::make_move_iterator(source.m_data.m_seq.end())
+         , this->priv_value_comp()
+         , dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
+   {  return this->priv_lower_bound(this->begin(), this->end(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
+   {  return this->priv_lower_bound(this->cbegin(), this->cend(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE 
+      typename dtl::enable_if_transparent<key_compare, K, iterator>::type
+         lower_bound(const K& k)
+   {  return this->priv_lower_bound(this->begin(), this->end(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE 
+      typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type
+         lower_bound(const K& k) const
+   {  return this->priv_lower_bound(this->cbegin(), this->cend(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
+   {  return this->priv_upper_bound(this->begin(), this->end(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
+   {  return this->priv_upper_bound(this->cbegin(), this->cend(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,iterator>::type
+   upper_bound(const K& k)
+   {  return this->priv_upper_bound(this->begin(), this->end(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,const_iterator>::type
+         upper_bound(const K& k) const
+   {  return this->priv_upper_bound(this->cbegin(), this->cend(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& k)
+   {  return this->priv_equal_range(this->begin(), this->end(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+   {  return this->priv_equal_range(this->cbegin(), this->cend(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,std::pair<iterator,iterator> >::type
+         equal_range(const K& k)
+   {  return this->priv_equal_range(this->begin(), this->end(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,std::pair<const_iterator,const_iterator> >::type
+         equal_range(const K& k) const
+   {  return this->priv_equal_range(this->cbegin(), this->cend(), k);  }
+
+
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, iterator> lower_bound_range(const key_type& k)
+   {  return this->priv_lower_bound_range(this->begin(), this->end(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
+   {  return this->priv_lower_bound_range(this->cbegin(), this->cend(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,std::pair<iterator,iterator> >::type
+         lower_bound_range(const K& k)
+   {  return this->priv_lower_bound_range(this->begin(), this->end(), k);  }
+
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K,std::pair<const_iterator,const_iterator> >::type
+         lower_bound_range(const K& k) const
+   {  return this->priv_lower_bound_range(this->cbegin(), this->cend(), k);  }
+
+   BOOST_CONTAINER_FORCEINLINE size_type capacity() const
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_capacity<container_type>::value;
+      return (flat_tree_capacity)(this->m_data.m_seq, dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
+   {
+      const bool value = boost::container::dtl::
+         has_member_function_callable_with_reserve<container_type, size_type>::value;
+      (flat_tree_reserve)(this->m_data.m_seq, cnt, dtl::bool_<value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE container_type extract_sequence()
+   {
+      return boost::move(m_data.m_seq);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE container_type &get_sequence_ref()
+   {
+      return m_data.m_seq;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence_equal(BOOST_RV_REF(container_type) seq)
+   {
+      (flat_tree_adopt_sequence_equal)( m_data.m_seq, boost::move(seq), this->priv_value_comp()
+         , dtl::bool_<is_contiguous_container<container_type>::value>());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence_unique(BOOST_RV_REF(container_type) seq)
+   {
+      (flat_tree_adopt_sequence_unique)(m_data.m_seq, boost::move(seq), this->priv_value_comp()
+         , dtl::bool_<is_contiguous_container<container_type>::value>());
+   }
+
+   void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(container_type) seq)
+   {
+      BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
+      m_data.m_seq = boost::move(seq);
+   }
+
+   void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(container_type) seq)
+   {
+      BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
+      m_data.m_seq = boost::move(seq);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y)
+   {
+      return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_tree& x, const flat_tree& y)
+   {
+      return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_tree& x, const flat_tree& y)
+      {  return !(x == y); }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_tree& x, const flat_tree& y)
+      {  return y < x;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_tree& x, const flat_tree& y)
+      {  return !(y < x);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_tree& x, const flat_tree& y)
+      {  return !(x < y);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend void swap(flat_tree& x, flat_tree& y)
+      {  x.swap(y);  }
+
+   private:
+
+   template <class InputIterator>
+   void priv_range_insertion_construct( bool unique_insertion, InputIterator first, InputIterator last)
+   {
+      //Use cend() as hint to achieve linear time for
+      //ordered ranges as required by the standard
+      //for the constructor
+      //Call end() every iteration as reallocation might have invalidated iterators
+      if(unique_insertion){
+         this->insert_unique(first, last);
+      }
+      else{
+         this->insert_equal (first, last);
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos <= this->end());
+   }
+
+   // insert/erase
+   void priv_insert_equal_prepare
+      (const_iterator pos, const value_type& val, insert_commit_data &data)
+   {
+      // N1780
+      //   To insert val at pos:
+      //   if pos == end || val <= *pos
+      //      if pos == begin || val >= *(pos-1)
+      //         insert val before pos
+      //      else
+      //         insert val before upper_bound(val)
+      //   else
+      //      insert val before lower_bound(val)
+      const value_compare &val_cmp = this->m_data;
+
+      if(pos == this->cend() || !val_cmp(*pos, val)){
+         if (pos == this->cbegin() || !val_cmp(val, pos[-1])){
+            data.position = pos;
+         }
+         else{
+            data.position =
+               this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
+         }
+      }
+      else{
+         data.position =
+            this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
+      }
+   }
+
+   bool priv_insert_unique_prepare
+      (const_iterator b, const_iterator e, const key_type& k, insert_commit_data &commit_data)
+   {
+      const key_compare &key_cmp  = this->priv_key_comp();
+      commit_data.position = this->priv_lower_bound(b, e, k);
+      return commit_data.position == e || key_cmp(k, KeyOfValue()(*commit_data.position));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE bool priv_insert_unique_prepare
+      (const key_type& k, insert_commit_data &commit_data)
+   {  return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), k, commit_data);   }
+
+   bool priv_insert_unique_prepare
+      (const_iterator pos, const key_type& k, insert_commit_data &commit_data)
+   {
+      //N1780. Props to Howard Hinnant!
+      //To insert k at pos:
+      //if pos == end || k <= *pos
+      //   if pos == begin || k >= *(pos-1)
+      //      insert k before pos
+      //   else
+      //      insert k before upper_bound(k)
+      //else if pos+1 == end || k <= *(pos+1)
+      //   insert k after pos
+      //else
+      //   insert k before lower_bound(k)
+      const key_compare &key_cmp = this->priv_key_comp();
+      const const_iterator cend_it = this->cend();
+      if(pos == cend_it || key_cmp(k, KeyOfValue()(*pos))){ //Check if k should go before end
+         const const_iterator cbeg = this->cbegin();
+         commit_data.position = pos;
+         if(pos == cbeg){  //If container is empty then insert it in the beginning
+            return true;
+         }
+         const_iterator prev(pos);
+         --prev;
+         if(key_cmp(KeyOfValue()(*prev), k)){   //If previous element was less, then it should go between prev and pos
+            return true;
+         }
+         else if(!key_cmp(k, KeyOfValue()(*prev))){   //If previous was equal then insertion should fail
+            commit_data.position = prev;
+            return false;
+         }
+         else{ //Previous was bigger so insertion hint was pointless, dispatch to hintless insertion
+               //but reduce the search between beg and prev as prev is bigger than k
+            return this->priv_insert_unique_prepare(cbeg, prev, k, commit_data);
+         }
+      }
+      else{
+         //The hint is before the insertion position, so insert it
+         //in the remaining range [pos, end)
+         return this->priv_insert_unique_prepare(pos, cend_it, k, commit_data);
+      }
+   }
+
+   template<class Convertible>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert_commit
+      (insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
+   {
+      return this->m_data.m_seq.insert
+         ( commit_data.position
+         , boost::forward<Convertible>(convertible));
+   }
+
+   template <class RanIt, class K>
+   RanIt priv_lower_bound(RanIt first, const RanIt last,
+                          const K & key) const
+   {
+      const Compare &key_cmp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      size_type len = static_cast<size_type>(last - first);
+      RanIt middle;
+
+      while (len) {
+         size_type step = len >> 1;
+         middle = first;
+         middle += step;
+
+         if (key_cmp(key_extract(*middle), key)) {
+            first = ++middle;
+            len -= step + 1;
+         }
+         else{
+            len = step;
+         }
+      }
+      return first;
+   }
+
+   template <class RanIt, class K>
+   RanIt priv_upper_bound
+      (RanIt first, const RanIt last,const K & key) const
+   {
+      const Compare &key_cmp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      size_type len = static_cast<size_type>(last - first);
+      RanIt middle;
+
+      while (len) {
+         size_type step = len >> 1;
+         middle = first;
+         middle += step;
+
+         if (key_cmp(key, key_extract(*middle))) {
+            len = step;
+         }
+         else{
+            first = ++middle;
+            len -= step + 1;
+         }
+      }
+      return first;
+   }
+
+   template <class RanIt, class K>
+   std::pair<RanIt, RanIt>
+      priv_equal_range(RanIt first, RanIt last, const K& key) const
+   {
+      const Compare &key_cmp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      size_type len = static_cast<size_type>(last - first);
+      RanIt middle;
+
+      while (len) {
+         size_type step = len >> 1;
+         middle = first;
+         middle += step;
+
+         if (key_cmp(key_extract(*middle), key)){
+            first = ++middle;
+            len -= step + 1;
+         }
+         else if (key_cmp(key, key_extract(*middle))){
+            len = step;
+         }
+         else {
+            //Middle is equal to key
+            last = first;
+            last += len;
+            RanIt const first_ret = this->priv_lower_bound(first, middle, key);
+            return std::pair<RanIt, RanIt>
+               ( first_ret, this->priv_upper_bound(++middle, last, key));
+         }
+      }
+      return std::pair<RanIt, RanIt>(first, first);
+   }
+
+   template<class RanIt, class K>
+   std::pair<RanIt, RanIt> priv_lower_bound_range(RanIt first, RanIt last, const K& k) const
+   {
+      const Compare &key_cmp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      RanIt lb(this->priv_lower_bound(first, last, k)), ub(lb);
+      if(lb != last && static_cast<difference_type>(!key_cmp(k, key_extract(*lb)))){
+         ++ub;
+      }
+      return std::pair<RanIt, RanIt>(lb, ub);
+   }
+};
+
+}  //namespace dtl {
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class KeyOfValue,
+class Compare, class AllocatorOrContainer>
+struct has_trivial_destructor_after_move<boost::container::dtl::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> >
+{
+   typedef typename boost::container::dtl::select_container_type<T, AllocatorOrContainer>::type container_type;
+   typedef typename container_type::allocator_type allocator_t;
+   typedef typename ::boost::container::allocator_traits<allocator_t>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<allocator_t>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_FLAT_TREE_HPP
diff --git a/include/boost/container/detail/function_detector.hpp b/include/boost/container/detail/function_detector.hpp
new file mode 100644
index 0000000..00caced
--- /dev/null
+++ b/include/boost/container/detail/function_detector.hpp
@@ -0,0 +1,96 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2009-2013.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+//  This code was modified from the code posted by Alexandre Courpron in his
+//  article "Interface Detection" in The Code Project:
+//  http://www.codeproject.com/KB/architecture/Detector.aspx
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2007 Alexandre Courpron
+//
+// Permission to use, copy, modify, redistribute and sell this software,
+// provided that this copyright notice appears on all copies of the software.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
+#define BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+
+namespace boost {
+namespace container {
+namespace function_detector {
+
+    typedef char NotFoundType;
+    struct StaticFunctionType { NotFoundType x [2]; };
+    struct NonStaticFunctionType { NotFoundType x [3]; };
+
+    enum
+         { NotFound          = 0,
+           StaticFunction    = sizeof( StaticFunctionType )    - sizeof( NotFoundType ),
+           NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
+         };
+
+}  //namespace boost {
+}  //namespace container {
+}  //namespace function_detector {
+
+#define BOOST_CONTAINER_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
+   namespace boost { \
+   namespace container { \
+   namespace function_detector { \
+   template < class T, \
+            class NonStaticType, \
+            class NonStaticConstType, \
+            class StaticType > \
+   class DetectMember_##InstantiationKey_##Identifier { \
+      template < NonStaticType > \
+      struct TestNonStaticNonConst ; \
+      \
+      template < NonStaticConstType > \
+      struct TestNonStaticConst ; \
+      \
+      template < StaticType > \
+      struct TestStatic ; \
+      \
+      template <class U > \
+      static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
+      \
+      template <class U > \
+      static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
+      \
+      template <class U> \
+      static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
+      \
+      template <class U> \
+      static NotFoundType Test( ... ); \
+   public : \
+      static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
+   };\
+}}} //namespace boost::container::function_detector {
+
+#define BOOST_CONTAINER_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
+    ::boost::container::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
+                                         ReturnType (Class::*)Params,\
+                                         ReturnType (Class::*)Params const,\
+                                         ReturnType (*)Params \
+                                       >::check
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //@ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
diff --git a/include/boost/container/detail/is_container.hpp b/include/boost/container/detail/is_container.hpp
new file mode 100644
index 0000000..feab702
--- /dev/null
+++ b/include/boost/container/detail/is_container.hpp
@@ -0,0 +1,55 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017. 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_DETAIL_IS_CONTAINER_HPP
+#define BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//empty
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME empty
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+//size
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME size
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template <class Container>
+struct is_container
+{
+   static const bool value =
+      boost::container::is_container_detail::
+         has_member_function_callable_with_size <const Container>::value &&
+      boost::container::is_container_detail::
+         has_member_function_callable_with_empty<const Container>::value;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
diff --git a/include/boost/container/detail/is_contiguous_container.hpp b/include/boost/container/detail/is_contiguous_container.hpp
new file mode 100644
index 0000000..528aeee
--- /dev/null
+++ b/include/boost/container/detail/is_contiguous_container.hpp
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017. 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_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
+#define BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//data
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME data
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_contiguous_container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template <class Container>
+struct is_contiguous_container
+{
+   static const bool value =
+      boost::container::is_contiguous_container_detail::
+         has_member_function_callable_with_data<Container>::value && 
+      boost::container::is_contiguous_container_detail::
+         has_member_function_callable_with_data<const Container>::value;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
diff --git a/include/boost/container/detail/is_sorted.hpp b/include/boost/container/detail/is_sorted.hpp
new file mode 100644
index 0000000..315bab5
--- /dev/null
+++ b/include/boost/container/detail/is_sorted.hpp
@@ -0,0 +1,57 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2016-2016. 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_DETAIL_IS_SORTED_HPP
+#define BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template <class ForwardIterator, class Pred>
+bool is_sorted (ForwardIterator first, ForwardIterator last, Pred pred)
+{
+   if(first != last){
+      ForwardIterator next = first;
+      while (++next != last){
+         if(pred(*next, *first))
+            return false;
+         ++first;
+      }
+   }
+   return true;
+}
+
+template <class ForwardIterator, class Pred>
+bool is_sorted_and_unique (ForwardIterator first, ForwardIterator last, Pred pred)
+{
+   if(first != last){
+      ForwardIterator next = first;
+      while (++next != last){
+         if(!pred(*first, *next))
+            return false;
+         ++first;
+      }
+   }
+   return true;
+}
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
diff --git a/include/boost/container/detail/iterator.hpp b/include/boost/container/detail/iterator.hpp
new file mode 100644
index 0000000..2ceaf26
--- /dev/null
+++ b/include/boost/container/detail/iterator.hpp
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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_DETAIL_ITERATOR_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace container {
+
+using ::boost::intrusive::iterator_traits;
+using ::boost::intrusive::iterator_distance;
+using ::boost::intrusive::iterator_advance;
+using ::boost::intrusive::iterator;
+using ::boost::intrusive::iterator_enable_if_tag;
+using ::boost::intrusive::iterator_disable_if_tag;
+using ::boost::intrusive::iterator_arrow_result;
+
+template <class Container>
+class back_emplacer
+{
+   private:
+   Container& container;
+
+   public:
+   typedef std::output_iterator_tag iterator_category;
+   typedef void                     value_type;
+   typedef void                     difference_type;
+   typedef void                     pointer;
+   typedef void                     reference;
+
+   back_emplacer(Container& x)
+      : container(x)
+   {}
+
+   template<class U>
+   back_emplacer& operator=(BOOST_FWD_REF(U) value)
+   {
+      container.emplace_back(boost::forward<U>(value));
+      return *this;
+   }
+   back_emplacer& operator*()    { return *this; }
+   back_emplacer& operator++()   { return *this; }
+   back_emplacer& operator++(int){ return *this; }
+};
+
+
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
diff --git a/include/boost/container/detail/iterator_to_raw_pointer.hpp b/include/boost/container/detail/iterator_to_raw_pointer.hpp
new file mode 100644
index 0000000..49f1d43
--- /dev/null
+++ b/include/boost/container/detail/iterator_to_raw_pointer.hpp
@@ -0,0 +1,33 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+using ::boost::movelib::iterator_to_raw_pointer;
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
diff --git a/include/boost/container/detail/iterators.hpp b/include/boost/container/detail/iterators.hpp
new file mode 100644
index 0000000..7ccdac9
--- /dev/null
+++ b/include/boost/container/detail/iterators.hpp
@@ -0,0 +1,875 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// 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_DETAIL_ITERATORS_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/value_init.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/intrusive/detail/reverse_iterator.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#else
+#include <boost/container/detail/variadic_templates_tools.hpp>
+#endif
+#include <boost/container/detail/iterator.hpp>
+
+namespace boost {
+namespace container {
+
+template <class T, class Difference = std::ptrdiff_t>
+class constant_iterator
+  : public ::boost::container::iterator
+      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+   typedef  constant_iterator<T, Difference> this_type;
+
+   public:
+   explicit constant_iterator(const T &ref, Difference range_size)
+      :  m_ptr(&ref), m_num(range_size){}
+
+   //Constructors
+   constant_iterator()
+      :  m_ptr(0), m_num(0){}
+
+   constant_iterator& operator++()
+   { increment();   return *this;   }
+
+   constant_iterator operator++(int)
+   {
+      constant_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   constant_iterator& operator--()
+   { decrement();   return *this;   }
+
+   constant_iterator operator--(int)
+   {
+      constant_iterator result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   constant_iterator& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   constant_iterator operator+(Difference off) const
+   {
+      constant_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend constant_iterator operator+(Difference off, const constant_iterator& right)
+   {  return right + off; }
+
+   constant_iterator& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   constant_iterator operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   const T& operator*() const
+   { return dereference(); }
+
+   const T& operator[] (Difference ) const
+   { return dereference(); }
+
+   const T* operator->() const
+   { return &(dereference()); }
+
+   private:
+   const T *   m_ptr;
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   { return *m_ptr; }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template <class T, class Difference>
+class value_init_construct_iterator
+  : public ::boost::container::iterator
+      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+   typedef  value_init_construct_iterator<T, Difference> this_type;
+
+   public:
+   explicit value_init_construct_iterator(Difference range_size)
+      :  m_num(range_size){}
+
+   //Constructors
+   value_init_construct_iterator()
+      :  m_num(0){}
+
+   value_init_construct_iterator& operator++()
+   { increment();   return *this;   }
+
+   value_init_construct_iterator operator++(int)
+   {
+      value_init_construct_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   value_init_construct_iterator& operator--()
+   { decrement();   return *this;   }
+
+   value_init_construct_iterator operator--(int)
+   {
+      value_init_construct_iterator result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   value_init_construct_iterator& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   value_init_construct_iterator operator+(Difference off) const
+   {
+      value_init_construct_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
+   {  return right + off; }
+
+   value_init_construct_iterator& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   value_init_construct_iterator operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   //This pseudo-iterator's dereference operations have no sense since value is not
+   //constructed until ::boost::container::construct_in_place is called.
+   //So comment them to catch bad uses
+   //const T& operator*() const;
+   //const T& operator[](difference_type) const;
+   //const T* operator->() const;
+
+   private:
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   {
+      static T dummy;
+      return dummy;
+   }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template <class T, class Difference>
+class default_init_construct_iterator
+  : public ::boost::container::iterator
+      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+   typedef  default_init_construct_iterator<T, Difference> this_type;
+
+   public:
+   explicit default_init_construct_iterator(Difference range_size)
+      :  m_num(range_size){}
+
+   //Constructors
+   default_init_construct_iterator()
+      :  m_num(0){}
+
+   default_init_construct_iterator& operator++()
+   { increment();   return *this;   }
+
+   default_init_construct_iterator operator++(int)
+   {
+      default_init_construct_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   default_init_construct_iterator& operator--()
+   { decrement();   return *this;   }
+
+   default_init_construct_iterator operator--(int)
+   {
+      default_init_construct_iterator result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   default_init_construct_iterator& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   default_init_construct_iterator operator+(Difference off) const
+   {
+      default_init_construct_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
+   {  return right + off; }
+
+   default_init_construct_iterator& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   default_init_construct_iterator operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   //This pseudo-iterator's dereference operations have no sense since value is not
+   //constructed until ::boost::container::construct_in_place is called.
+   //So comment them to catch bad uses
+   //const T& operator*() const;
+   //const T& operator[](difference_type) const;
+   //const T* operator->() const;
+
+   private:
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   {
+      static T dummy;
+      return dummy;
+   }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+
+template <class T, class Difference = std::ptrdiff_t>
+class repeat_iterator
+  : public ::boost::container::iterator
+      <std::random_access_iterator_tag, T, Difference, T*, T&>
+{
+   typedef repeat_iterator<T, Difference> this_type;
+   public:
+   explicit repeat_iterator(T &ref, Difference range_size)
+      :  m_ptr(&ref), m_num(range_size){}
+
+   //Constructors
+   repeat_iterator()
+      :  m_ptr(0), m_num(0){}
+
+   this_type& operator++()
+   { increment();   return *this;   }
+
+   this_type operator++(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   this_type& operator--()
+   { increment();   return *this;   }
+
+   this_type operator--(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   friend bool operator== (const this_type& i, const this_type& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const this_type& i, const this_type& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const this_type& i, const this_type& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const this_type& i, const this_type& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const this_type& i, const this_type& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const this_type& i, const this_type& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const this_type& i, const this_type& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   this_type& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   this_type operator+(Difference off) const
+   {
+      this_type other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend this_type operator+(Difference off, const this_type& right)
+   {  return right + off; }
+
+   this_type& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   this_type operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   T& operator*() const
+   { return dereference(); }
+
+   T& operator[] (Difference ) const
+   { return dereference(); }
+
+   T *operator->() const
+   { return &(dereference()); }
+
+   private:
+   T *         m_ptr;
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   T & dereference() const
+   { return *m_ptr; }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
+class emplace_iterator
+  : public ::boost::container::iterator
+      <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+   typedef emplace_iterator this_type;
+
+   public:
+   typedef Difference difference_type;
+   BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e)
+      :  m_num(1), m_pe(&e){}
+
+   BOOST_CONTAINER_FORCEINLINE emplace_iterator()
+      :  m_num(0), m_pe(0){}
+
+   BOOST_CONTAINER_FORCEINLINE this_type& operator++()
+   { increment();   return *this;   }
+
+   this_type operator++(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE this_type& operator--()
+   { decrement();   return *this;   }
+
+   this_type operator--(int)
+   {
+      this_type result (*this);
+      decrement();
+      return result;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
+   { return i.equal(i2); }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
+   { return !(i == i2); }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
+   { return i.less(i2); }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
+   { return i2 < i; }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
+   { return !(i > i2); }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
+   { return !(i < i2); }
+
+   BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off)
+   {  this->advance(off); return *this;   }
+
+   this_type operator+(difference_type off) const
+   {
+      this_type other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
+   {  return right + off; }
+
+   BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
+   {  this->advance(-off); return *this;   }
+
+   BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
+   {  return *this + (-off);  }
+
+   private:
+   //This pseudo-iterator's dereference operations have no sense since value is not
+   //constructed until ::boost::container::construct_in_place is called.
+   //So comment them to catch bad uses
+   const T& operator*() const;
+   const T& operator[](difference_type) const;
+   const T* operator->() const;
+
+   public:
+   template<class Allocator>
+   void construct_in_place(Allocator &a, T* ptr)
+   {  (*m_pe)(a, ptr);  }
+
+   template<class DestIt>
+   void assign_in_place(DestIt dest)
+   {  (*m_pe)(dest);  }
+
+   private:
+   difference_type m_num;
+   EmplaceFunctor *            m_pe;
+
+   BOOST_CONTAINER_FORCEINLINE void increment()
+   { --m_num; }
+
+   BOOST_CONTAINER_FORCEINLINE void decrement()
+   { ++m_num; }
+
+   BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   BOOST_CONTAINER_FORCEINLINE const T & dereference() const
+   {
+      static T dummy;
+      return dummy;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
+   {  m_num -= n; }
+
+   BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
+   {  return difference_type(m_num - other.m_num);   }
+};
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template<class ...Args>
+struct emplace_functor
+{
+   typedef typename dtl::build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+   emplace_functor(BOOST_FWD_REF(Args)... args)
+      : args_(args...)
+   {}
+
+   template<class Allocator, class T>
+   BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
+   {  emplace_functor::inplace_impl(a, ptr, index_tuple_t());  }
+
+   template<class DestIt>
+   BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
+   {  emplace_functor::inplace_impl(dest, index_tuple_t());  }
+
+   private:
+   template<class Allocator, class T, std::size_t ...IdxPack>
+   BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple<IdxPack...>&)
+   {
+      allocator_traits<Allocator>::construct
+         (a, ptr, ::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
+   }
+
+   template<class DestIt, std::size_t ...IdxPack>
+   BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple<IdxPack...>&)
+   {
+      typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
+      value_type && tmp= value_type(::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
+      *dest = ::boost::move(tmp);
+   }
+
+   dtl::tuple<Args&...> args_;
+};
+
+template<class ...Args>
+struct emplace_functor_type
+{
+   typedef emplace_functor<Args...> type;
+};
+
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+//Partial specializations cannot match argument list for primary template, so add an extra argument
+template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
+struct emplace_functor_type;
+
+#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
+BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+struct emplace_functor##N\
+{\
+   explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
+      BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
+   \
+   template<class Allocator, class T>\
+   void operator()(Allocator &a, T *ptr)\
+   {  allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);  }\
+   \
+   template<class DestIt>\
+   void operator()(DestIt dest)\
+   {\
+      typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
+      BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init<value_type> tmp) ;\
+      *dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\
+   }\
+   \
+   BOOST_MOVE_MREF##N\
+};\
+\
+template <BOOST_MOVE_CLASS##N>\
+struct emplace_functor_type<BOOST_MOVE_TARG##N>\
+{\
+   typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
+};\
+//
+
+BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
+
+#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
+
+#endif
+
+namespace dtl {
+
+template<class T>
+struct has_iterator_category
+{
+   struct two { char _[2]; };
+
+   template <typename X>
+   static char test(int, typename X::iterator_category*);
+
+   template <typename X>
+   static two test(int, ...);
+
+   static const bool value = (1 == sizeof(test<T>(0, 0)));
+};
+
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_input_iterator
+{
+   static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
+};
+
+template<class T>
+struct is_input_iterator<T, false>
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct is_not_input_iterator
+{
+   static const bool value = !is_input_iterator<T>::value;
+};
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_forward_iterator
+{
+   static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
+};
+
+template<class T>
+struct is_forward_iterator<T, false>
+{
+   static const bool value = false;
+};
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_bidirectional_iterator
+{
+   static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
+};
+
+template<class T>
+struct is_bidirectional_iterator<T, false>
+{
+   static const bool value = false;
+};
+
+template<class IINodeType>
+struct iiterator_node_value_type {
+  typedef typename IINodeType::value_type type;
+};
+
+template<class IIterator>
+struct iiterator_types
+{
+   typedef typename IIterator::value_type                            it_value_type;
+   typedef typename iiterator_node_value_type<it_value_type>::type   value_type;
+   typedef typename boost::container::iterator_traits<IIterator>::pointer         it_pointer;
+   typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
+   typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
+      template rebind_pointer<value_type>::type                      pointer;
+   typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
+      template rebind_pointer<const value_type>::type                const_pointer;
+   typedef typename ::boost::intrusive::
+      pointer_traits<pointer>::reference                             reference;
+   typedef typename ::boost::intrusive::
+      pointer_traits<const_pointer>::reference                       const_reference;
+   typedef typename IIterator::iterator_category                     iterator_category;
+};
+
+template<class IIterator, bool IsConst>
+struct iterator_types
+{
+   typedef typename ::boost::container::iterator
+      < typename iiterator_types<IIterator>::iterator_category
+      , typename iiterator_types<IIterator>::value_type
+      , typename iiterator_types<IIterator>::difference_type
+      , typename iiterator_types<IIterator>::const_pointer
+      , typename iiterator_types<IIterator>::const_reference> type;
+};
+
+template<class IIterator>
+struct iterator_types<IIterator, false>
+{
+   typedef typename ::boost::container::iterator
+      < typename iiterator_types<IIterator>::iterator_category
+      , typename iiterator_types<IIterator>::value_type
+      , typename iiterator_types<IIterator>::difference_type
+      , typename iiterator_types<IIterator>::pointer
+      , typename iiterator_types<IIterator>::reference> type;
+};
+
+template<class IIterator, bool IsConst>
+class iterator_from_iiterator
+{
+   typedef typename iterator_types<IIterator, IsConst>::type types_t;
+
+   public:
+   typedef typename types_t::pointer             pointer;
+   typedef typename types_t::reference           reference;
+   typedef typename types_t::difference_type     difference_type;
+   typedef typename types_t::iterator_category   iterator_category;
+   typedef typename types_t::value_type          value_type;
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
+      : m_iit()
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_iit(iit)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
+      :  m_iit(other.get())
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
+   {  ++this->m_iit;   return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      iterator_from_iiterator result (*this);
+      ++this->m_iit;
+      return result;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
+      BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
+      --this->m_iit;   return *this;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      iterator_from_iiterator result (*this);
+      --this->m_iit;
+      return result;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_iit == r.m_iit;   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return !(l == r); }
+
+   BOOST_CONTAINER_FORCEINLINE reference operator*()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->m_iit->get_data();  }
+
+   BOOST_CONTAINER_FORCEINLINE pointer   operator->() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*());  }
+
+   BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->m_iit;   }
+
+   private:
+   IIterator m_iit;
+};
+
+}  //namespace dtl {
+
+using ::boost::intrusive::reverse_iterator;
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
diff --git a/include/boost/container/detail/math_functions.hpp b/include/boost/container/detail/math_functions.hpp
new file mode 100644
index 0000000..8d350a1
--- /dev/null
+++ b/include/boost/container/detail/math_functions.hpp
@@ -0,0 +1,177 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000.
+// (C) Copyright Ion Gaztanaga 2007-2013.
+//
+// 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.
+//
+// This file is a slightly modified file from Boost.Pool
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <climits>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+// Greatest common divisor and least common multiple
+
+//
+// gcd is an algorithm that calculates the greatest common divisor of two
+//  integers, using Euclid's algorithm.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer gcd(Integer A, Integer B)
+{
+   do
+   {
+      const Integer tmp(B);
+      B = A % B;
+      A = tmp;
+   } while (B != 0);
+
+   return A;
+}
+
+//
+// lcm is an algorithm that calculates the least common multiple of two
+//  integers.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer lcm(const Integer & A, const Integer & B)
+{
+   Integer ret = A;
+   ret /= gcd(A, B);
+   ret *= B;
+   return ret;
+}
+
+template <typename Integer>
+inline Integer log2_ceil(const Integer & A)
+{
+   Integer i = 0;
+   Integer power_of_2 = 1;
+
+   while(power_of_2 < A){
+      power_of_2 <<= 1;
+      ++i;
+   }
+   return i;
+}
+
+template <typename Integer>
+inline Integer upper_power_of_2(const Integer & A)
+{
+   Integer power_of_2 = 1;
+
+   while(power_of_2 < A){
+      power_of_2 <<= 1;
+   }
+   return power_of_2;
+}
+
+template <typename Integer, bool Loop = true>
+struct upper_power_of_2_loop_ct
+{
+
+   template <Integer I, Integer P>
+   struct apply
+   {
+      static const Integer value =
+         upper_power_of_2_loop_ct<Integer, (I > P*2)>::template apply<I, P*2>::value;
+   };
+};
+
+template <typename Integer>
+struct upper_power_of_2_loop_ct<Integer, false>
+{
+   template <Integer I, Integer P>
+   struct apply
+   {
+      static const Integer value = P;
+   };
+};
+
+template <typename Integer, Integer I>
+struct upper_power_of_2_ct
+{
+   static const Integer value = upper_power_of_2_loop_ct<Integer, (I > 1)>::template apply<I, 2>::value;
+};
+
+//This function uses binary search to discover the
+//highest set bit of the integer
+inline std::size_t floor_log2 (std::size_t x)
+{
+   const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
+   const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
+   BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
+
+   std::size_t n = x;
+   std::size_t log2 = 0;
+
+   for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
+      std::size_t tmp = n >> shift;
+      if (tmp)
+         log2 += shift, n = tmp;
+   }
+
+   return log2;
+}
+
+template<std::size_t I1, std::size_t I2>
+struct gcd_ct
+{
+   static const std::size_t Max = I1 > I2 ? I1 : I2;
+   static const std::size_t Min = I1 < I2 ? I1 : I2;
+   static const std::size_t value = gcd_ct<Min, Max % Min>::value;
+};
+
+template<std::size_t I1>
+struct gcd_ct<I1, 0>
+{
+   static const std::size_t value = I1;
+};
+
+template<std::size_t I1>
+struct gcd_ct<0, I1>
+{
+   static const std::size_t value = I1;
+};
+
+template<std::size_t I1, std::size_t I2>
+struct lcm_ct
+{
+   static const std::size_t value = I1 * I2 / gcd_ct<I1, I2>::value;
+};
+
+} // namespace dtl
+} // namespace container
+} // namespace boost
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif
diff --git a/include/boost/container/detail/min_max.hpp b/include/boost/container/detail/min_max.hpp
new file mode 100644
index 0000000..35cf066
--- /dev/null
+++ b/include/boost/container/detail/min_max.hpp
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_MIN_MAX_HPP
+#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class T>
+const T &max_value(const T &a, const T &b)
+{  return a > b ? a : b;   }
+
+template<class T>
+const T &min_value(const T &a, const T &b)
+{  return a < b ? a : b;   }
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
diff --git a/include/boost/container/detail/minimal_char_traits_header.hpp b/include/boost/container/detail/minimal_char_traits_header.hpp
new file mode 100644
index 0000000..a92a31a
--- /dev/null
+++ b/include/boost/container/detail/minimal_char_traits_header.hpp
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2014-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_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
+#define BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
+#
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+#
+#//Try to avoid including <string>, as it's quite big
+#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
+   #include <iosfwd>   //Dinkum libraries for MSVC define std::char_traits there
+#elif defined(BOOST_GNU_STDLIB)
+   #include <bits/char_traits.h>
+#else
+   #include <string>  //Fallback
+#endif
+
+#endif //BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp
new file mode 100644
index 0000000..385f7db
--- /dev/null
+++ b/include/boost/container/detail/mpl.hpp
@@ -0,0 +1,104 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+//
+// 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_CONTAINER_DETAIL_MPL_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+using boost::move_detail::integral_constant;
+using boost::move_detail::true_type;
+using boost::move_detail::false_type;
+using boost::move_detail::enable_if_c;
+using boost::move_detail::enable_if;
+using boost::move_detail::enable_if_convertible;
+using boost::move_detail::disable_if_c;
+using boost::move_detail::disable_if;
+using boost::move_detail::disable_if_convertible;
+using boost::move_detail::is_convertible;
+using boost::move_detail::if_c;
+using boost::move_detail::if_;
+using boost::move_detail::identity;
+using boost::move_detail::bool_;
+using boost::move_detail::true_;
+using boost::move_detail::false_;
+using boost::move_detail::yes_type;
+using boost::move_detail::no_type;
+using boost::move_detail::bool_;
+using boost::move_detail::true_;
+using boost::move_detail::false_;
+using boost::move_detail::unvoid_ref;
+using boost::move_detail::and_;
+using boost::move_detail::or_;
+using boost::move_detail::not_;
+using boost::move_detail::enable_if_and;
+using boost::move_detail::disable_if_and;
+using boost::move_detail::enable_if_or;
+using boost::move_detail::disable_if_or;
+
+template <class FirstType>
+struct select1st
+{
+   typedef FirstType type;
+
+   template<class T>
+   const type& operator()(const T& x) const
+   {  return x.first;   }
+
+   template<class T>
+   type& operator()(T& x)
+   {  return const_cast<type&>(x.first);   }
+};
+
+template <class T, class=void>
+struct is_transparent
+{
+   static const bool value = false;
+};
+
+template <class T>
+struct is_transparent<T, typename T::is_transparent>
+{
+   static const bool value = true;
+};
+
+template <typename C, typename K, typename R>
+struct enable_if_transparent
+   : boost::move_detail::enable_if_c<dtl::is_transparent<C>::value, R>
+{};
+
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
+
diff --git a/include/boost/container/detail/multiallocation_chain.hpp b/include/boost/container/detail/multiallocation_chain.hpp
new file mode 100644
index 0000000..c10f809
--- /dev/null
+++ b/include/boost/container/detail/multiallocation_chain.hpp
@@ -0,0 +1,298 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_MULTIALLOCATION_CHAIN_HPP
+#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/container_fwd.hpp>
+// container/detail
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/transform_iterator.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class VoidPointer>
+class basic_multiallocation_chain
+{
+   private:
+   typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
+                        ,bi::link_mode<bi::normal_link>
+                        > node;
+
+   typedef typename boost::intrusive::pointer_traits
+      <VoidPointer>::template rebind_pointer<char>::type    char_ptr;
+   typedef typename boost::intrusive::
+      pointer_traits<char_ptr>::difference_type             difference_type;
+
+   typedef bi::slist< node
+                    , bi::linear<true>
+                    , bi::cache_last<true>
+                    , bi::size_type<typename boost::container::dtl::make_unsigned<difference_type>::type>
+                    > slist_impl_t;
+   slist_impl_t slist_impl_;
+
+   typedef typename boost::intrusive::pointer_traits
+      <VoidPointer>::template rebind_pointer<node>::type    node_ptr;
+   typedef typename boost::intrusive::
+      pointer_traits<node_ptr>                              node_ptr_traits;
+
+   static node & to_node(const VoidPointer &p)
+   {  return *static_cast<node*>(static_cast<void*>(boost::movelib::to_raw_pointer(p)));  }
+
+   static VoidPointer from_node(node &n)
+   {  return node_ptr_traits::pointer_to(n);  }
+
+   static node_ptr to_node_ptr(const VoidPointer &p)
+   {  return node_ptr_traits::static_cast_from(p);   }
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
+
+   public:
+
+   typedef VoidPointer                       void_pointer;
+   typedef typename slist_impl_t::iterator   iterator;
+   typedef typename slist_impl_t::size_type  size_type;
+
+   basic_multiallocation_chain()
+      :  slist_impl_()
+   {}
+
+   basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
+      :  slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
+   {}
+
+   basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
+      :  slist_impl_(::boost::move(other.slist_impl_))
+   {}
+
+   basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
+   {
+      slist_impl_ = ::boost::move(other.slist_impl_);
+      return *this;
+   }
+
+   bool empty() const
+   {  return slist_impl_.empty(); }
+
+   size_type size() const
+   {  return slist_impl_.size();  }
+
+   iterator before_begin()
+   {  return slist_impl_.before_begin(); }
+
+   iterator begin()
+   {  return slist_impl_.begin(); }
+
+   iterator end()
+   {  return slist_impl_.end(); }
+
+   iterator last()
+   {  return slist_impl_.last(); }
+
+   void clear()
+   {  slist_impl_.clear(); }
+
+   iterator insert_after(iterator it, void_pointer m)
+   {  return slist_impl_.insert_after(it, to_node(m));   }
+
+   void push_front(const void_pointer &m)
+   {  return slist_impl_.push_front(to_node(m));  }
+
+   void push_back(const void_pointer &m)
+   {  return slist_impl_.push_back(to_node(m));   }
+
+   void_pointer pop_front()
+   {
+      node & n = slist_impl_.front();
+      void_pointer ret = from_node(n);
+      slist_impl_.pop_front();
+      return ret;
+   }
+
+   void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+   {  slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n);   }
+
+   void splice_after(iterator after_this, basic_multiallocation_chain &x)
+   {  slist_impl_.splice_after(after_this, x.slist_impl_);   }
+
+   void erase_after(iterator before_b, iterator e, size_type n)
+   {  slist_impl_.erase_after(before_b, e, n);   }
+
+   void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
+   {
+      typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
+      char_ptr elem = char_pointer_traits::static_cast_from(b);
+      if(num_units){
+         char_ptr prev_elem = elem;
+         elem += unit_bytes;
+         for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
+            ::new (boost::movelib::to_raw_pointer(prev_elem)) void_pointer(elem);
+            prev_elem = elem;
+         }
+         slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
+      }
+      return elem;
+   }
+
+   void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
+   {  slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n);   }
+
+   void swap(basic_multiallocation_chain &x)
+   {  slist_impl_.swap(x.slist_impl_);   }
+
+   static iterator iterator_to(const void_pointer &p)
+   {  return slist_impl_t::s_iterator_to(to_node(p));   }
+
+   std::pair<void_pointer, void_pointer> extract_data()
+   {
+      std::pair<void_pointer, void_pointer> ret
+         (slist_impl_.begin().operator->()
+         ,slist_impl_.last().operator->());
+      slist_impl_.clear();
+      return ret;
+   }
+};
+
+template<class T>
+struct cast_functor
+{
+   typedef typename dtl::add_reference<T>::type result_type;
+   template<class U>
+   result_type operator()(U &ptr) const
+   {  return *static_cast<T*>(static_cast<void*>(&ptr));  }
+};
+
+template<class MultiallocationChain, class T>
+class transform_multiallocation_chain
+   : public MultiallocationChain
+{
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
+   //transform_multiallocation_chain(const transform_multiallocation_chain &);
+   //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
+
+   typedef typename MultiallocationChain::void_pointer   void_pointer;
+   typedef typename boost::intrusive::pointer_traits
+      <void_pointer>                                     void_pointer_traits;
+   typedef typename void_pointer_traits::template
+      rebind_pointer<T>::type                            pointer;
+   typedef typename boost::intrusive::pointer_traits
+      <pointer>                                          pointer_traits;
+
+   static pointer cast(const void_pointer &p)
+   {  return pointer_traits::static_cast_from(p);  }
+
+   public:
+   typedef transform_iterator
+      < typename MultiallocationChain::iterator
+      , dtl::cast_functor <T> >             iterator;
+   typedef typename MultiallocationChain::size_type      size_type;
+
+   transform_multiallocation_chain()
+      : MultiallocationChain()
+   {}
+
+   transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
+      : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
+   {}
+
+   transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
+      : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
+   {}
+
+   transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
+   {
+      return static_cast<MultiallocationChain&>
+         (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
+   }
+/*
+   void push_front(const pointer &mem)
+   {  holder_.push_front(mem);  }
+
+   void push_back(const pointer &mem)
+   {  return holder_.push_back(mem);   }
+
+   void swap(transform_multiallocation_chain &other_chain)
+   {  holder_.swap(other_chain.holder_); }
+
+   void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+   {  holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n);  }
+
+   void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
+   {  holder_.incorporate_after(after_this.base(), b, before_e, n);  }
+*/
+   pointer pop_front()
+   {  return cast(this->MultiallocationChain::pop_front());  }
+/*
+   bool empty() const
+   {  return holder_.empty(); }
+
+   iterator before_begin()
+   {  return iterator(holder_.before_begin());   }
+*/
+   iterator begin()
+   {  return iterator(this->MultiallocationChain::begin());   }
+/*
+   iterator end()
+   {  return iterator(holder_.end());   }
+
+   iterator last()
+   {  return iterator(holder_.last());   }
+
+   size_type size() const
+   {  return holder_.size();  }
+
+   void clear()
+   {  holder_.clear(); }
+*/
+   iterator insert_after(iterator it, pointer m)
+   {  return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
+
+   static iterator iterator_to(const pointer &p)
+   {  return iterator(MultiallocationChain::iterator_to(p));  }
+
+   std::pair<pointer, pointer> extract_data()
+   {
+      std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
+      return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
+   }
+/*
+   MultiallocationChain &extract_multiallocation_chain()
+   {  return holder_;  }*/
+};
+
+}}}
+
+// namespace dtl {
+// namespace container {
+// namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
diff --git a/include/boost/container/detail/mutex.hpp b/include/boost/container/detail/mutex.hpp
new file mode 100644
index 0000000..56e72a8
--- /dev/null
+++ b/include/boost/container/detail/mutex.hpp
@@ -0,0 +1,283 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000 
+// (C) Copyright Ion Gaztanaga  2015-2017.
+//
+// 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_MUTEX_HPP
+#define BOOST_CONTAINER_MUTEX_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//#define BOOST_CONTAINER_NO_MT
+//#define BOOST_CONTAINER_NO_SPINLOCKS
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// Extremely Light-Weight wrapper classes for OS thread synchronization
+
+#define BOOST_MUTEX_HELPER_NONE         0
+#define BOOST_MUTEX_HELPER_WIN32        1
+#define BOOST_MUTEX_HELPER_PTHREAD      2
+#define BOOST_MUTEX_HELPER_SPINLOCKS    3
+
+#if !defined(BOOST_HAS_THREADS) && !defined(BOOST_NO_MT)
+# define BOOST_NO_MT
+#endif
+
+#if defined(BOOST_NO_MT) || defined(BOOST_CONTAINER_NO_MT)
+  // No multithreading -> make locks into no-ops
+  #define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_NONE
+#else
+   //Taken from dlmalloc
+   #if !defined(BOOST_CONTAINER_NO_SPINLOCKS) &&                           \
+         ((defined(__GNUC__) &&                                            \
+         ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) ||      \
+         defined(__i386__) || defined(__x86_64__))) ||                     \
+      (defined(_MSC_VER) && _MSC_VER>=1310))
+      #define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_SPINLOCKS
+   #endif
+
+   #if defined(BOOST_WINDOWS)
+      #include <windows.h>
+      #ifndef BOOST_MUTEX_HELPER
+         #define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_WIN32
+      #endif
+   #elif defined(BOOST_HAS_UNISTD_H)
+      #include <unistd.h>
+      #if !defined(BOOST_MUTEX_HELPER) && (defined(_POSIX_THREADS) || defined(BOOST_HAS_PTHREADS))
+         #define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_PTHREAD
+      #endif
+   #endif
+#endif
+
+#ifndef BOOST_MUTEX_HELPER
+  #error Unable to determine platform mutex type; #define BOOST_NO_MT to assume single-threaded
+#endif
+
+#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
+   //...
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
+   #if defined(_MSC_VER)
+      #ifndef _M_AMD64
+         /* These are already defined on AMD64 builds */
+         #ifdef __cplusplus
+            extern "C" {
+         #endif /* __cplusplus */
+            long __cdecl _InterlockedCompareExchange(long volatile *Dest, long Exchange, long Comp);
+            long __cdecl _InterlockedExchange(long volatile *Target, long Value);
+         #ifdef __cplusplus
+            }
+         #endif /* __cplusplus */
+      #endif /* _M_AMD64 */
+      #pragma intrinsic (_InterlockedCompareExchange)
+      #pragma intrinsic (_InterlockedExchange)
+      #define interlockedcompareexchange _InterlockedCompareExchange
+      #define interlockedexchange        _InterlockedExchange
+   #elif defined(WIN32) && defined(__GNUC__)
+      #define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
+      #define interlockedexchange                 __sync_lock_test_and_set
+   #endif /* Win32 */
+
+   /* First, define CAS_LOCK and CLEAR_LOCK on ints */
+   /* Note CAS_LOCK defined to return 0 on success */
+
+   #if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
+      #define BOOST_CONTAINER_CAS_LOCK(sl)     __sync_lock_test_and_set(sl, 1)
+      #define BOOST_CONTAINER_CLEAR_LOCK(sl)   __sync_lock_release(sl)
+
+   #elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
+      /* Custom spin locks for older gcc on x86 */
+      static inline int boost_container_x86_cas_lock(int *sl) {
+         int ret;
+         int val = 1;
+         int cmp = 0;
+         __asm__ __volatile__  ("lock; cmpxchgl %1, %2"
+                                 : "=a" (ret)
+                                 : "r" (val), "m" (*(sl)), "0"(cmp)
+                                 : "memory", "cc");
+         return ret;
+      }
+
+      static inline void boost_container_x86_clear_lock(int* sl) {
+         assert(*sl != 0);
+         int prev = 0;
+         int ret;
+         __asm__ __volatile__ ("lock; xchgl %0, %1"
+                                 : "=r" (ret)
+                                 : "m" (*(sl)), "0"(prev)
+                                 : "memory");
+      }
+
+      #define BOOST_CONTAINER_CAS_LOCK(sl)     boost_container_x86_cas_lock(sl)
+      #define BOOST_CONTAINER_CLEAR_LOCK(sl)   boost_container_x86_clear_lock(sl)
+
+   #else /* Win32 MSC */
+      #define BOOST_CONTAINER_CAS_LOCK(sl)     interlockedexchange((long volatile*)sl, (long)1)
+      #define BOOST_CONTAINER_CLEAR_LOCK(sl)   interlockedexchange((long volatile*)sl, (long)0)
+   #endif
+
+   /* How to yield for a spin lock */
+   #define SPINS_PER_YIELD       63
+   #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+      #define SLEEP_EX_DURATION     50 /* delay for yield/sleep */
+      #define SPIN_LOCK_YIELD  SleepEx(SLEEP_EX_DURATION, FALSE)
+   #elif defined (__SVR4) && defined (__sun) /* solaris */
+      #include <thread.h>
+      #define SPIN_LOCK_YIELD   thr_yield();
+   #elif !defined(LACKS_SCHED_H)
+      #include <sched.h>
+      #define SPIN_LOCK_YIELD   sched_yield();
+   #else
+      #define SPIN_LOCK_YIELD
+   #endif /* ... yield ... */
+
+   #define BOOST_CONTAINER_SPINS_PER_YIELD       63
+   inline int boost_interprocess_spin_acquire_lock(int *sl) {
+      int spins = 0;
+      while (*(volatile int *)sl != 0 ||
+         BOOST_CONTAINER_CAS_LOCK(sl)) {
+         if ((++spins & BOOST_CONTAINER_SPINS_PER_YIELD) == 0) {
+            SPIN_LOCK_YIELD;
+         }
+      }
+      return 0;
+   }
+   #define BOOST_CONTAINER_MLOCK_T               int
+   #define BOOST_CONTAINER_TRY_LOCK(sl)          !BOOST_CONTAINER_CAS_LOCK(sl)
+   #define BOOST_CONTAINER_RELEASE_LOCK(sl)      BOOST_CONTAINER_CLEAR_LOCK(sl)
+   #define BOOST_CONTAINER_ACQUIRE_LOCK(sl)      (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0)
+   #define BOOST_MOVE_INITIAL_LOCK(sl)      (*sl = 0)
+   #define BOOST_CONTAINER_DESTROY_LOCK(sl)      (0)
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
+   //
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
+   #include <pthread.h>
+#endif
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
+   class null_mutex
+   {
+   private:
+      null_mutex(const null_mutex &);
+      void operator=(const null_mutex &);
+
+   public:
+      null_mutex() { }
+
+      static void lock() { }
+      static void unlock() { }
+   };
+
+  typedef null_mutex default_mutex;
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_SPINLOCKS
+
+   class spin_mutex
+   {
+   private:
+      BOOST_CONTAINER_MLOCK_T sl;
+      spin_mutex(const spin_mutex &);
+      void operator=(const spin_mutex &);
+
+   public:
+      spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); }
+
+      void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
+      void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); }
+   };
+  typedef spin_mutex default_mutex;
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
+   class mutex
+   {
+   private:
+      CRITICAL_SECTION mtx;
+
+      mutex(const mutex &);
+      void operator=(const mutex &);
+
+   public:
+      mutex()
+      { InitializeCriticalSection(&mtx); }
+
+      ~mutex()
+      { DeleteCriticalSection(&mtx); }
+
+      void lock()
+      { EnterCriticalSection(&mtx); }
+
+      void unlock()
+      { LeaveCriticalSection(&mtx); }
+   };
+
+  typedef mutex default_mutex;
+#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
+   class mutex
+   {
+   private:
+      pthread_mutex_t mtx;
+
+      mutex(const mutex &);
+      void operator=(const mutex &);
+
+   public:
+      mutex()
+      { pthread_mutex_init(&mtx, 0); }
+
+      ~mutex()
+      { pthread_mutex_destroy(&mtx); }
+
+      void lock()
+      { pthread_mutex_lock(&mtx); }
+
+      void unlock()
+      { pthread_mutex_unlock(&mtx); }
+   };
+
+  typedef mutex default_mutex;
+#endif
+
+template<class Mutex>
+class scoped_lock
+{
+   public:
+   scoped_lock(Mutex &m)
+      :  m_(m)
+   { m_.lock(); }
+   ~scoped_lock()
+   { m_.unlock(); }
+
+   private:
+   Mutex &m_;
+};
+
+} // namespace dtl
+} // namespace container
+} // namespace boost
+
+#undef BOOST_MUTEX_HELPER_WIN32
+#undef BOOST_MUTEX_HELPER_PTHREAD
+#undef BOOST_MUTEX_HELPER_NONE
+#undef BOOST_MUTEX_HELPER
+#undef BOOST_MUTEX_HELPER_SPINLOCKS
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif
diff --git a/include/boost/container/detail/next_capacity.hpp b/include/boost/container/detail/next_capacity.hpp
new file mode 100644
index 0000000..7e6554d
--- /dev/null
+++ b/include/boost/container/detail/next_capacity.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_DETAIL_NEXT_CAPACITY_HPP
+#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+// container
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/min_max.hpp>
+
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<unsigned Minimum, unsigned Numerator, unsigned Denominator>
+struct grow_factor_ratio
+{
+   BOOST_STATIC_ASSERT(Numerator > Denominator);
+   BOOST_STATIC_ASSERT(Numerator   < 100);
+   BOOST_STATIC_ASSERT(Denominator < 100);
+   BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator));
+
+   template<class SizeType>
+   SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const
+   {
+      const SizeType overflow_limit  = ((SizeType)-1) / Numerator;
+
+      SizeType new_cap = 0;
+
+      if(cur_cap <= overflow_limit){
+         new_cap = cur_cap * Numerator / Denominator;
+      }
+      else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){
+         new_cap = (SizeType)-1;
+      }
+      else{
+         new_cap *= Numerator;
+      }
+      return max_value(SizeType(Minimum), max_value(cur_cap+add_min_cap, min_value(max_cap, new_cap)));
+   }
+};
+
+}  //namespace dtl {
+
+struct growth_factor_50
+   : dtl::grow_factor_ratio<0, 3, 2>
+{};
+
+struct growth_factor_60
+   : dtl::grow_factor_ratio<0, 8, 5>
+{};
+
+struct growth_factor_100
+   : dtl::grow_factor_ratio<0, 2, 1>
+{};
+
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp
new file mode 100644
index 0000000..ad7b713
--- /dev/null
+++ b/include/boost/container/detail/node_alloc_holder.hpp
@@ -0,0 +1,419 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_NODE_ALLOC_HPP_
+#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/placement_new.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+// intrusive
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/options.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+// other
+#include <boost/core/no_exceptions_support.hpp>
+
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
+
+template<class Allocator, class ICont>
+struct node_alloc_holder
+{
+   //If the intrusive container is an associative container, obtain the predicate, which will
+   //be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+      ( boost::container::dtl::
+      , ICont, value_compare, dtl::nat)              intrusive_value_compare;
+   //In that case obtain the value predicate from the node predicate via predicate_type
+   //if intrusive_value_compare is node_compare<>, nat otherwise
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+      ( boost::container::dtl::
+      , intrusive_value_compare
+      , predicate_type, dtl::nat)                    value_compare;
+
+   typedef allocator_traits<Allocator>                            allocator_traits_type;
+   typedef typename allocator_traits_type::value_type             value_type;
+   typedef ICont                                                  intrusive_container;
+   typedef typename ICont::value_type                             Node;
+   typedef typename allocator_traits_type::template
+      portable_rebind_alloc<Node>::type                           NodeAlloc;
+   typedef allocator_traits<NodeAlloc>                            node_allocator_traits_type;
+   typedef dtl::allocator_version_traits<NodeAlloc>  node_allocator_version_traits_type;
+   typedef Allocator                                              ValAlloc;
+   typedef typename node_allocator_traits_type::pointer           NodePtr;
+   typedef dtl::scoped_deallocator<NodeAlloc>        Deallocator;
+   typedef typename node_allocator_traits_type::size_type         size_type;
+   typedef typename node_allocator_traits_type::difference_type   difference_type;
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::
+         version<NodeAlloc>::value>                               alloc_version;
+   typedef typename ICont::iterator                               icont_iterator;
+   typedef typename ICont::const_iterator                         icont_citerator;
+   typedef allocator_destroyer<NodeAlloc>                         Destroyer;
+   typedef allocator_traits<NodeAlloc>                            NodeAllocTraits;
+   typedef allocator_version_traits<NodeAlloc>                    AllocVersionTraits;
+
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
+
+   public:
+
+   //Constructors for sequence containers
+   node_alloc_holder()
+      : members_()
+   {}
+
+   explicit node_alloc_holder(const ValAlloc &a)
+      : members_(a)
+   {}
+
+   //Constructors for associative containers
+   node_alloc_holder(const value_compare &c, const ValAlloc &a)
+      : members_(a, c)
+   {}
+
+   explicit node_alloc_holder(const node_alloc_holder &x)
+      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
+   {}
+
+   node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
+      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
+   {}
+
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
+      : members_(boost::move(x.node_alloc()))
+   {  this->icont().swap(x.icont());  }
+
+   explicit node_alloc_holder(const value_compare &c)
+      : members_(c)
+   {}
+
+   //helpers for move assignments
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c)
+      : members_(boost::move(x.node_alloc()), c)
+   {  this->icont().swap(x.icont());  }
+
+   void copy_assign_alloc(const node_alloc_holder &x)
+   {
+      dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
+      dtl::assign_alloc( static_cast<NodeAlloc &>(this->members_)
+                                    , static_cast<const NodeAlloc &>(x.members_), flag);
+   }
+
+   void move_assign_alloc( node_alloc_holder &x)
+   {
+      dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
+      dtl::move_alloc( static_cast<NodeAlloc &>(this->members_)
+                                  , static_cast<NodeAlloc &>(x.members_), flag);
+   }
+
+   ~node_alloc_holder()
+   {  this->clear(alloc_version()); }
+
+   size_type max_size() const
+   {  return allocator_traits_type::max_size(this->node_alloc());  }
+
+   NodePtr allocate_one()
+   {  return AllocVersionTraits::allocate_one(this->node_alloc());   }
+
+   void deallocate_one(const NodePtr &p)
+   {  AllocVersionTraits::deallocate_one(this->node_alloc(), p);  }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template<class ...Args>
+   NodePtr create_node(Args &&...args)
+   {
+      NodePtr p = this->allocate_one();
+      Deallocator node_deallocator(p, this->node_alloc());
+      allocator_traits<NodeAlloc>::construct
+         ( this->node_alloc()
+         , dtl::addressof(p->m_data), boost::forward<Args>(args)...);
+      node_deallocator.release();
+      //This does not throw
+      typedef typename Node::hook_type hook_type;
+      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+      return (p);
+   }
+
+   #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   NodePtr create_node(BOOST_MOVE_UREF##N)\
+   {\
+      NodePtr p = this->allocate_one();\
+      Deallocator node_deallocator(p, this->node_alloc());\
+      allocator_traits<NodeAlloc>::construct\
+         ( this->node_alloc()\
+         , dtl::addressof(p->m_data)\
+          BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      node_deallocator.release();\
+      typedef typename Node::hook_type hook_type;\
+      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
+      return (p);\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
+   #undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template<class It>
+   NodePtr create_node_from_it(const It &it)
+   {
+      NodePtr p = this->allocate_one();
+      Deallocator node_deallocator(p, this->node_alloc());
+      ::boost::container::construct_in_place(this->node_alloc(), dtl::addressof(p->m_data), it);
+      node_deallocator.release();
+      //This does not throw
+      typedef typename Node::hook_type hook_type;
+      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+      return (p);
+   }
+
+   template<class KeyConvertible>
+   NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
+   {
+      NodePtr p = this->allocate_one();
+      NodeAlloc &na = this->node_alloc();
+      Deallocator node_deallocator(p, this->node_alloc());
+      node_allocator_traits_type::construct
+         (na, dtl::addressof(p->m_data.first), boost::forward<KeyConvertible>(key));
+      BOOST_TRY{
+         node_allocator_traits_type::construct(na, dtl::addressof(p->m_data.second));
+      }
+      BOOST_CATCH(...){
+         node_allocator_traits_type::destroy(na, dtl::addressof(p->m_data.first));
+         BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      node_deallocator.release();
+      //This does not throw
+      typedef typename Node::hook_type hook_type;
+      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+      return (p);
+   }
+
+   void destroy_node(const NodePtr &nodep)
+   {
+      allocator_traits<NodeAlloc>::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(nodep));
+      this->deallocate_one(nodep);
+   }
+
+   void swap(node_alloc_holder &x)
+   {
+      this->icont().swap(x.icont());
+      dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+      dtl::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
+   }
+
+   template<class FwdIterator, class Inserter>
+   void allocate_many_and_construct
+      (FwdIterator beg, difference_type n, Inserter inserter)
+   {
+      if(n){
+         typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
+
+         //Try to allocate memory in a single block
+         typedef typename multiallocation_chain::iterator multialloc_iterator;
+         multiallocation_chain mem;
+         NodeAlloc &nalloc = this->node_alloc();
+         node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
+         multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
+         mem.clear();
+         Node *p = 0;
+         BOOST_TRY{
+            Deallocator node_deallocator(NodePtr(), nalloc);
+            dtl::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
+            while(n--){
+               p = boost::movelib::iterator_to_raw_pointer(itbeg);
+               node_deallocator.set(p);
+               ++itbeg;
+               //This can throw
+               boost::container::construct_in_place(nalloc, dtl::addressof(p->m_data), beg);
+               sdestructor.set(p);
+               ++beg;
+               //This does not throw
+               typedef typename Node::hook_type hook_type;
+               ::new(static_cast<hook_type*>(p), boost_container_new_t()) hook_type;
+               //This can throw in some containers (predicate might throw).
+               //(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
+               inserter(*p);
+               sdestructor.set(0);
+            }
+            sdestructor.release();
+            node_deallocator.release();
+         }
+         BOOST_CATCH(...){
+            mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
+            node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+   }
+
+   void clear(version_1)
+   {  this->icont().clear_and_dispose(Destroyer(this->node_alloc()));   }
+
+   void clear(version_2)
+   {
+      typename NodeAlloc::multiallocation_chain chain;
+      allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
+      this->icont().clear_and_dispose(builder);
+      //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
+      if(!chain.empty())
+         this->node_alloc().deallocate_individual(chain);
+   }
+
+   icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
+   {  return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
+
+   icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
+   {
+      typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+      NodeAlloc & nalloc = this->node_alloc();
+      multiallocation_chain chain;
+      allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
+      icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
+      nalloc.deallocate_individual(chain);
+      return ret_it;
+   }
+
+   template<class Key, class Comparator>
+   size_type erase_key(const Key& k, const Comparator &comp, version_1)
+   {  return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
+
+   template<class Key, class Comparator>
+   size_type erase_key(const Key& k, const Comparator &comp, version_2)
+   {
+      allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+      return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
+   }
+
+   protected:
+   struct cloner
+   {
+      explicit cloner(node_alloc_holder &holder)
+         :  m_holder(holder)
+      {}
+
+      NodePtr operator()(const Node &other) const
+      {  return m_holder.create_node(other.m_data);  }
+
+      node_alloc_holder &m_holder;
+   };
+
+   struct move_cloner
+   {
+      move_cloner(node_alloc_holder &holder)
+         :  m_holder(holder)
+      {}
+
+      NodePtr operator()(Node &other)
+      {  //Use m_data instead of get_data to allow moving const key in [multi]map
+         return m_holder.create_node(::boost::move(other.m_data));
+      }
+
+      node_alloc_holder &m_holder;
+   };
+
+   struct members_holder
+      :  public NodeAlloc
+   {
+      private:
+      members_holder(const members_holder&);
+      members_holder & operator=(const members_holder&);
+
+      public:
+      members_holder()
+         : NodeAlloc(), m_icont()
+      {}
+
+      template<class ConvertibleToAlloc>
+      explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
+         :  NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
+         , m_icont()
+      {}
+
+      template<class ConvertibleToAlloc>
+      members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
+         :  NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
+         , m_icont(typename ICont::key_compare(c))
+      {}
+
+      explicit members_holder(const value_compare &c)
+         : NodeAlloc()
+         , m_icont(typename ICont::key_compare(c))
+      {}
+
+      //The intrusive container
+      ICont m_icont;
+   };
+
+   ICont &non_const_icont() const
+   {  return const_cast<ICont&>(this->members_.m_icont);   }
+
+   NodeAlloc &node_alloc()
+   {  return static_cast<NodeAlloc &>(this->members_);   }
+
+   const NodeAlloc &node_alloc() const
+   {  return static_cast<const NodeAlloc &>(this->members_);   }
+
+   members_holder members_;
+
+   public:
+   ICont &icont()
+   {  return this->members_.m_icont;   }
+
+   const ICont &icont() const
+   {  return this->members_.m_icont;   }
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
diff --git a/include/boost/container/detail/node_pool.hpp b/include/boost/container/detail/node_pool.hpp
new file mode 100644
index 0000000..e43956b
--- /dev/null
+++ b/include/boost/container/detail/node_pool.hpp
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_NODE_POOL_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/mutex.hpp>
+#include <boost/container/detail/pool_common_alloc.hpp>
+#include <boost/container/detail/node_pool_impl.hpp>
+#include <boost/container/detail/mutex.hpp>
+#include <boost/move/utility_core.hpp>
+#include <cstddef>
+#include <cassert>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+//!Pooled memory allocator using single segregated storage. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per block (NodesPerBlock) are known at compile time
+template< std::size_t NodeSize, std::size_t NodesPerBlock >
+class private_node_pool
+   //Inherit from the implementation to avoid template bloat
+   :  public boost::container::dtl::
+         private_node_pool_impl<fake_segment_manager>
+{
+   typedef boost::container::dtl::
+      private_node_pool_impl<fake_segment_manager>   base_t;
+   //Non-copyable
+   private_node_pool(const private_node_pool &);
+   private_node_pool &operator=(const private_node_pool &);
+
+   public:
+   typedef typename base_t::multiallocation_chain multiallocation_chain;
+   static const std::size_t nodes_per_block = NodesPerBlock;
+
+   //!Constructor from a segment manager. Never throws
+   private_node_pool()
+      :  base_t(0, NodeSize, NodesPerBlock)
+   {}
+
+};
+
+template< std::size_t NodeSize
+        , std::size_t NodesPerBlock
+        >
+class shared_node_pool
+   : public private_node_pool<NodeSize, NodesPerBlock>
+{
+   private:
+   typedef private_node_pool<NodeSize, NodesPerBlock> private_node_allocator_t;
+
+   public:
+   typedef typename private_node_allocator_t::free_nodes_t  free_nodes_t;
+   typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
+
+   //!Constructor from a segment manager. Never throws
+   shared_node_pool()
+   : private_node_allocator_t(){}
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~shared_node_pool()
+   {}
+
+   //!Allocates array of count elements. Can throw std::bad_alloc
+   void *allocate_node()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      return private_node_allocator_t::allocate_node();
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *ptr)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_node(ptr);
+   }
+
+   //!Allocates a singly linked list of n nodes ending in null pointer.
+   //!can throw std::bad_alloc
+   void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      return private_node_allocator_t::allocate_nodes(n, chain);
+   }
+
+   void deallocate_nodes(multiallocation_chain &chain)
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_nodes(chain);
+   }
+
+   //!Deallocates all the free blocks of memory. Never throws
+   void deallocate_free_blocks()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::deallocate_free_blocks();
+   }
+
+   //!Deallocates all blocks. Never throws
+   void purge_blocks()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      private_node_allocator_t::purge_blocks();
+   }
+
+   std::size_t num_free_nodes()
+   {
+      //-----------------------
+      scoped_lock<default_mutex> guard(mutex_);
+      //-----------------------
+      return private_node_allocator_t::num_free_nodes();
+   }
+
+   private:
+   default_mutex mutex_;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
diff --git a/include/boost/container/detail/node_pool_impl.hpp b/include/boost/container/detail/node_pool_impl.hpp
new file mode 100644
index 0000000..97f555b
--- /dev/null
+++ b/include/boost/container/detail/node_pool_impl.hpp
@@ -0,0 +1,375 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/detail/math_functions.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class SegmentManagerBase>
+class private_node_pool_impl
+{
+   //Non-copyable
+   private_node_pool_impl();
+   private_node_pool_impl(const private_node_pool_impl &);
+   private_node_pool_impl &operator=(const private_node_pool_impl &);
+
+   //A node object will hold node_t when it's not allocated
+   public:
+   typedef typename SegmentManagerBase::void_pointer              void_pointer;
+   typedef typename node_slist<void_pointer>::slist_hook_t        slist_hook_t;
+   typedef typename node_slist<void_pointer>::node_t              node_t;
+   typedef typename node_slist<void_pointer>::node_slist_t        free_nodes_t;
+   typedef typename SegmentManagerBase::multiallocation_chain     multiallocation_chain;
+   typedef typename SegmentManagerBase::size_type                 size_type;
+
+   private:
+   typedef typename bi::make_slist
+      < node_t, bi::base_hook<slist_hook_t>
+      , bi::linear<true>
+      , bi::constant_time_size<false> >::type      blockslist_t;
+
+   static size_type get_rounded_size(size_type orig_size, size_type round_to)
+   {  return ((orig_size-1)/round_to+1)*round_to;  }
+
+   public:
+
+   //!Segment manager typedef
+   typedef SegmentManagerBase segment_manager_base_type;
+
+   //!Constructor from a segment manager. Never throws
+   private_node_pool_impl(segment_manager_base_type *segment_mngr_base, size_type node_size, size_type nodes_per_block)
+   :  m_nodes_per_block(nodes_per_block)
+   ,  m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
+      //General purpose allocator
+   ,  mp_segment_mngr_base(segment_mngr_base)
+   ,  m_blocklist()
+   ,  m_freelist()
+      //Debug node count
+   ,  m_allocated(0)
+   {}
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~private_node_pool_impl()
+   {  this->purge_blocks();  }
+
+   size_type get_real_num_node() const
+   {  return m_nodes_per_block; }
+
+   //!Returns the segment manager. Never throws
+   segment_manager_base_type* get_segment_manager_base()const
+   {  return boost::movelib::to_raw_pointer(mp_segment_mngr_base);  }
+
+   void *allocate_node()
+   {  return this->priv_alloc_node();  }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *ptr)
+   {  this->priv_dealloc_node(ptr); }
+
+   //!Allocates a singly linked list of n nodes ending in null pointer.
+   void allocate_nodes(const size_type n, multiallocation_chain &chain)
+   {
+      //Preallocate all needed blocks to fulfill the request
+      size_type cur_nodes = m_freelist.size();
+      if(cur_nodes < n){
+         this->priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+      }
+
+      //We just iterate the needed nodes to get the last we'll erase
+      typedef typename free_nodes_t::iterator free_iterator;
+      free_iterator before_last_new_it = m_freelist.before_begin();
+      for(size_type j = 0; j != n; ++j){
+         ++before_last_new_it;
+      }
+
+      //Cache the first node of the allocated range before erasing
+      free_iterator first_node(m_freelist.begin());
+      free_iterator last_node (before_last_new_it);
+
+      //Erase the range. Since we already have the distance, this is O(1)
+      m_freelist.erase_after( m_freelist.before_begin()
+                            , ++free_iterator(before_last_new_it)
+                            , n);
+
+      //Now take the last erased node and just splice it in the end
+      //of the intrusive list that will be traversed by the multialloc iterator.
+      chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
+      m_allocated += n;
+   }
+
+   void deallocate_nodes(multiallocation_chain &chain)
+   {
+      typedef typename multiallocation_chain::iterator iterator;
+      iterator it(chain.begin()), itend(chain.end());
+      while(it != itend){
+         void *pElem = &*it;
+         ++it;
+         this->priv_dealloc_node(pElem);
+      }
+   }
+
+   //!Deallocates all the free blocks of memory. Never throws
+   void deallocate_free_blocks()
+   {
+      typedef typename free_nodes_t::iterator nodelist_iterator;
+      typename blockslist_t::iterator bit(m_blocklist.before_begin()),
+                                      it(m_blocklist.begin()),
+                                      itend(m_blocklist.end());
+      free_nodes_t backup_list;
+      nodelist_iterator backup_list_last = backup_list.before_begin();
+
+      //Execute the algorithm and get an iterator to the last value
+      size_type blocksize = (get_rounded_size)
+         (m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
+
+      while(it != itend){
+         //Collect all the nodes from the block pointed by it
+         //and push them in the list
+         free_nodes_t free_nodes;
+         nodelist_iterator last_it = free_nodes.before_begin();
+         const void *addr = get_block_from_hook(&*it, blocksize);
+
+         m_freelist.remove_and_dispose_if
+            (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
+
+         //If the number of nodes is equal to m_nodes_per_block
+         //this means that the block can be deallocated
+         if(free_nodes.size() == m_nodes_per_block){
+            //Unlink the nodes
+            free_nodes.clear();
+            it = m_blocklist.erase_after(bit);
+            mp_segment_mngr_base->deallocate((void*)addr);
+         }
+         //Otherwise, insert them in the backup list, since the
+         //next "remove_if" does not need to check them again.
+         else{
+            //Assign the iterator to the last value if necessary
+            if(backup_list.empty() && !m_freelist.empty()){
+               backup_list_last = last_it;
+            }
+            //Transfer nodes. This is constant time.
+            backup_list.splice_after
+               ( backup_list.before_begin()
+               , free_nodes
+               , free_nodes.before_begin()
+               , last_it
+               , free_nodes.size());
+            bit = it;
+            ++it;
+         }
+      }
+      //We should have removed all the nodes from the free list
+      BOOST_ASSERT(m_freelist.empty());
+
+      //Now pass all the node to the free list again
+      m_freelist.splice_after
+         ( m_freelist.before_begin()
+         , backup_list
+         , backup_list.before_begin()
+         , backup_list_last
+         , backup_list.size());
+   }
+
+   size_type num_free_nodes()
+   {  return m_freelist.size();  }
+
+   //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
+   //!already be deallocated. Otherwise, undefined behaviour. Never throws
+   void purge_blocks()
+   {
+      //check for memory leaks
+      BOOST_ASSERT(m_allocated==0);
+      size_type blocksize = (get_rounded_size)
+         (m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
+
+      //We iterate though the NodeBlock list to free the memory
+      while(!m_blocklist.empty()){
+         void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
+         m_blocklist.pop_front();
+         mp_segment_mngr_base->deallocate((void*)addr);
+      }
+      //Just clear free node list
+      m_freelist.clear();
+   }
+
+   void swap(private_node_pool_impl &other)
+   {
+      BOOST_ASSERT(m_nodes_per_block == other.m_nodes_per_block);
+      BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
+      std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+      m_blocklist.swap(other.m_blocklist);
+      m_freelist.swap(other.m_freelist);
+      std::swap(m_allocated, other.m_allocated);
+   }
+
+   private:
+
+   struct push_in_list
+   {
+      push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
+         :  slist_(l), last_it_(it)
+      {}
+
+      void operator()(typename free_nodes_t::pointer p) const
+      {
+         slist_.push_front(*p);
+         if(slist_.size() == 1){ //Cache last element
+            ++last_it_ = slist_.begin();
+         }
+      }
+
+      private:
+      free_nodes_t &slist_;
+      typename free_nodes_t::iterator &last_it_;
+   };
+
+   struct is_between
+   {
+      typedef typename free_nodes_t::value_type argument_type;
+      typedef bool                              result_type;
+
+      is_between(const void *addr, std::size_t size)
+         :  beg_(static_cast<const char *>(addr)), end_(beg_+size)
+      {}
+
+      bool operator()(typename free_nodes_t::const_reference v) const
+      {
+         return (beg_ <= reinterpret_cast<const char *>(&v) &&
+                 end_ >  reinterpret_cast<const char *>(&v));
+      }
+      private:
+      const char *      beg_;
+      const char *      end_;
+   };
+
+   //!Allocates one node, using single segregated storage algorithm.
+   //!Never throws
+   node_t *priv_alloc_node()
+   {
+      //If there are no free nodes we allocate a new block
+      if (m_freelist.empty())
+         this->priv_alloc_block(1);
+      //We take the first free node
+      node_t *n = (node_t*)&m_freelist.front();
+      m_freelist.pop_front();
+      ++m_allocated;
+      return n;
+   }
+
+   //!Deallocates one node, using single segregated storage algorithm.
+   //!Never throws
+   void priv_dealloc_node(void *pElem)
+   {
+      //We put the node at the beginning of the free node list
+      node_t * to_deallocate = static_cast<node_t*>(pElem);
+      m_freelist.push_front(*to_deallocate);
+      BOOST_ASSERT(m_allocated>0);
+      --m_allocated;
+   }
+
+   //!Allocates several blocks of nodes. Can throw
+   void priv_alloc_block(size_type num_blocks)
+   {
+      BOOST_ASSERT(num_blocks > 0);
+      size_type blocksize =
+         (get_rounded_size)(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
+
+      BOOST_TRY{
+         for(size_type i = 0; i != num_blocks; ++i){
+            //We allocate a new NodeBlock and put it as first
+            //element in the free Node list
+            char *pNode = reinterpret_cast<char*>
+               (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
+            char *pBlock = pNode;
+            m_blocklist.push_front(get_block_hook(pBlock, blocksize));
+
+            //We initialize all Nodes in Node Block to insert
+            //them in the free Node list
+            for(size_type j = 0; j < m_nodes_per_block; ++j, pNode += m_real_node_size){
+               m_freelist.push_front(*new (pNode) node_t);
+            }
+         }
+      }
+      BOOST_CATCH(...){
+         //to-do: if possible, an efficient way to deallocate allocated blocks
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   //!Deprecated, use deallocate_free_blocks
+   void deallocate_free_chunks()
+   {  this->deallocate_free_blocks(); }
+
+   //!Deprecated, use purge_blocks
+   void purge_chunks()
+   {  this->purge_blocks(); }
+
+   private:
+   //!Returns a reference to the block hook placed in the end of the block
+   static node_t & get_block_hook (void *block, size_type blocksize)
+   {
+      return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
+   }
+
+   //!Returns the starting address of the block reference to the block hook placed in the end of the block
+   void *get_block_from_hook (node_t *hook, size_type blocksize)
+   {
+      return (reinterpret_cast<char*>(hook) - blocksize);
+   }
+
+   private:
+   typedef typename boost::intrusive::pointer_traits
+      <void_pointer>::template rebind_pointer<segment_manager_base_type>::type   segment_mngr_base_ptr_t;
+
+   const size_type m_nodes_per_block;
+   const size_type m_real_node_size;
+   segment_mngr_base_ptr_t mp_segment_mngr_base;   //Segment manager
+   blockslist_t      m_blocklist;      //Intrusive container of blocks
+   free_nodes_t      m_freelist;       //Intrusive container of free nods
+   size_type       m_allocated;      //Used nodes for debugging
+};
+
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp
new file mode 100644
index 0000000..9cca9f6
--- /dev/null
+++ b/include/boost/container/detail/pair.hpp
@@ -0,0 +1,614 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+//
+// 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_CONTAINER_DETAIL_PAIR_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/std_fwd.hpp>
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#  include <boost/container/detail/variadic_templates_tools.hpp>
+#endif
+#include <boost/move/adl_move_swap.hpp> //swap
+
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/fwd_macros.hpp>
+
+namespace boost {
+namespace tuples {
+
+struct null_type;
+
+template <
+  class T0, class T1, class T2,
+  class T3, class T4, class T5,
+  class T6, class T7, class T8,
+  class T9>
+class tuple;
+
+}  //namespace tuples {
+}  //namespace boost {
+
+namespace boost {
+namespace container {
+namespace pair_impl {
+
+template <class TupleClass>
+struct is_boost_tuple
+{
+   static const bool value = false;
+};
+
+template <
+  class T0, class T1, class T2,
+  class T3, class T4, class T5,
+  class T6, class T7, class T8,
+  class T9>
+struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+{
+   static const bool value = true;
+};
+
+template<class Tuple>
+struct disable_if_boost_tuple
+   : boost::container::dtl::disable_if< is_boost_tuple<Tuple> >
+{};
+
+template<class T>
+struct is_tuple_null
+{
+   static const bool value = false;
+};
+
+template<>
+struct is_tuple_null<boost::tuples::null_type>
+{
+   static const bool value = true;
+};
+
+}}}
+
+#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
+//MSVC 2010 tuple marker
+namespace std { namespace tr1 { struct _Nil; }}
+#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
+//MSVC 2012 tuple marker
+namespace std { struct _Nil; }
+#endif
+
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   template <int Dummy = 0>
+   struct std_piecewise_construct_holder
+   {
+      static ::std::piecewise_construct_t *dummy;
+   };
+
+   template <int Dummy>
+   ::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
+      reinterpret_cast< ::std::piecewise_construct_t *>(0x01234);  //Avoid sanitizer errors on references to null pointers
+
+typedef const std::piecewise_construct_t & piecewise_construct_t;
+
+struct try_emplace_t{};
+
+#else
+
+//! The piecewise_construct_t struct is an empty structure type used as a unique type to
+//! disambiguate used to disambiguate between different functions that take two tuple arguments.
+typedef unspecified piecewise_construct_t;
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A instance of type
+//! piecewise_construct_t
+static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
+
+///@cond
+
+namespace dtl {
+
+struct piecewise_construct_use
+{
+   //Avoid warnings of unused "piecewise_construct"
+   piecewise_construct_use()
+   {  (void)&::boost::container::piecewise_construct;   }
+};
+
+template <class T1, class T2>
+struct pair;
+
+template <class T>
+struct is_pair
+{
+   static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_pair< pair<T1, T2> >
+{
+   static const bool value = true;
+};
+
+template <class T1, class T2>
+struct is_pair< std::pair<T1, T2> >
+{
+   static const bool value = true;
+};
+
+template <class T>
+struct is_not_pair
+{
+   static const bool value = !is_pair<T>::value;
+};
+
+template <class T>
+struct is_std_pair
+{
+   static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_std_pair< std::pair<T1, T2> >
+{
+   static const bool value = true;
+};
+
+struct pair_nat;
+
+template<typename T, typename U, typename V>
+void get(T); //to enable ADL
+
+///@endcond
+
+template <class T1, class T2>
+struct pair
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(pair)
+
+   public:
+   typedef T1 first_type;
+   typedef T2 second_type;
+
+   T1 first;
+   T2 second;
+
+   //Default constructor
+   pair()
+      : first(), second()
+   {}
+
+   //pair copy assignment
+   pair(const pair& x)
+      : first(x.first), second(x.second)
+   {}
+
+   //pair move constructor
+   pair(BOOST_RV_REF(pair) p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   template <class D, class S>
+   pair(const pair<D, S> &p)
+      : first(p.first), second(p.second)
+   {}
+
+   template <class D, class S>
+   pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   //pair from two values
+   pair(const T1 &t1, const T2 &t2)
+      : first(t1)
+      , second(t2)
+   {}
+
+   template<class U, class V>
+   pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
+      : first(::boost::forward<U>(u))
+      , second(::boost::forward<V>(v))
+   {}
+
+   //And now compatibility with std::pair
+   pair(const std::pair<T1, T2>& x)
+      : first(x.first), second(x.second)
+   {}
+
+   template <class D, class S>
+   pair(const std::pair<D, S>& p)
+      : first(p.first), second(p.second)
+   {}
+
+   pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   template <class D, class S>
+   pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+   template< class KeyType, class ...Args>
+   pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
+      : first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
+   {}
+   #else
+
+   //piecewise construction from boost::tuple
+   #define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
+   template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
+   pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
+      : first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
+   {}\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
+   #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
+
+   #endif   //BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+   //piecewise construction from boost::tuple
+   #define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
+   template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
+            BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+   pair( piecewise_construct_t\
+       , BoostTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
+       , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
+       , typename dtl::enable_if_c\
+         < pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\
+           !(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \
+         >::type* = 0\
+       )\
+      : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
+   { (void)p; (void)q; }\
+   //
+   BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
+   #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
+
+   //piecewise construction from variadic tuple (with delegating constructors)
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+   #  if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
+      private:
+      template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
+      pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
+         : first (::boost::forward<Args1>(get<Indexes1>(t1))...)
+         , second(::boost::forward<Args2>(get<Indexes2>(t2))...)
+      {  (void) t1; (void)t2; }
+
+      public:
+      template< template<class ...> class Tuple, class... Args1, class... Args2
+              , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
+      pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
+         : pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
+      {}
+   #  else
+      //piecewise construction from variadic tuple (suboptimal, without delegating constructors)
+      private:
+      template<typename T, template<class ...> class Tuple, typename... Args>
+      static T build_from_args(Tuple<Args...>&& t)
+      {  return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type());   }
+
+      template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
+      static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
+      {  (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...);  }
+
+      public:
+      template< template<class ...> class Tuple, class... Args1, class... Args2
+              , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
+      pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
+         : first  (build_from_args<first_type> (::boost::move(t1)))
+         , second (build_from_args<second_type>(::boost::move(t2)))
+      {}
+   #  endif   //BOOST_NO_CXX11_VARIADIC_TEMPLATES
+   #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
+      //MSVC 2010 tuple implementation
+      #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
+      template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
+               BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+      pair( piecewise_construct_t\
+          , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
+          , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
+         : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
+      { (void)p; (void)q; }\
+      //
+      BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
+      #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
+   #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
+      #if _VARIADIC_MAX >= 9
+      #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
+      #else
+      #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
+      #endif
+
+      //MSVC 2012 tuple implementation
+      #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
+      template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
+               BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
+      pair( piecewise_construct_t\
+          , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
+          , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
+         : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
+      { (void)p; (void)q; }\
+      //
+      BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
+      #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
+      #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
+   #endif
+
+   //pair copy assignment
+   pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   //pair move assignment
+   pair& operator=(BOOST_RV_REF(pair) p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   template <class D, class S>
+   typename ::boost::container::dtl::disable_if_or
+      < pair &
+      , ::boost::container::dtl::is_same<T1, D>
+      , ::boost::container::dtl::is_same<T2, S>
+      >::type
+      operator=(const pair<D, S>&p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   template <class D, class S>
+   typename ::boost::container::dtl::disable_if_or
+      < pair &
+      , ::boost::container::dtl::is_same<T1, D>
+      , ::boost::container::dtl::is_same<T2, S>
+      >::type
+      operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+//std::pair copy assignment
+   pair& operator=(const std::pair<T1, T2> &p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   template <class D, class S>
+   pair& operator=(const std::pair<D, S> &p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   //std::pair move assignment
+   pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   template <class D, class S>
+   pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   //swap
+   void swap(pair& p)
+   {
+      ::boost::adl_move_swap(this->first, p.first);
+      ::boost::adl_move_swap(this->second, p.second);
+   }
+};
+
+template <class T1, class T2>
+inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return static_cast<bool>(x.first == y.first && x.second == y.second);  }
+
+template <class T1, class T2>
+inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return static_cast<bool>(x.first < y.first ||
+                         (!(y.first < x.first) && x.second < y.second)); }
+
+template <class T1, class T2>
+inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return static_cast<bool>(!(x == y));  }
+
+template <class T1, class T2>
+inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return y < x;  }
+
+template <class T1, class T2>
+inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return static_cast<bool>(!(x < y)); }
+
+template <class T1, class T2>
+inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{  return static_cast<bool>(!(y < x)); }
+
+template <class T1, class T2>
+inline pair<T1, T2> make_pair(T1 x, T2 y)
+{  return pair<T1, T2>(x, y); }
+
+template <class T1, class T2>
+inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
+{  x.swap(y);  }
+
+}  //namespace dtl {
+}  //namespace container {
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T1, class T2>
+struct has_move_emulation_enabled< ::boost::container::dtl::pair<T1, T2> >
+{
+   static const bool value = true;
+};
+
+#endif
+
+namespace move_detail{
+
+template<class T>
+struct is_class_or_union;
+
+template <class T1, class T2>
+struct is_class_or_union< ::boost::container::dtl::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = true;
+};
+
+template <class T1, class T2>
+struct is_class_or_union< std::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = true;
+};
+
+template<class T>
+struct is_union;
+
+template <class T1, class T2>
+struct is_union< ::boost::container::dtl::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_union< std::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct is_class;
+
+template <class T1, class T2>
+struct is_class< ::boost::container::dtl::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = true;
+};
+
+template <class T1, class T2>
+struct is_class< std::pair<T1, T2> >
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+{
+   static const bool value = true;
+};
+
+
+//Triviality of pair
+template<class T>
+struct is_trivially_copy_constructible;
+
+template<class A, class B>
+struct is_trivially_copy_assignable
+   <boost::container::dtl::pair<A,B> >
+{
+   static const bool value = boost::move_detail::is_trivially_copy_assignable<A>::value &&
+                             boost::move_detail::is_trivially_copy_assignable<B>::value ;
+};
+
+template<class T>
+struct is_trivially_move_constructible;
+
+template<class A, class B>
+struct is_trivially_move_assignable
+   <boost::container::dtl::pair<A,B> >
+{
+   static const bool value = boost::move_detail::is_trivially_move_assignable<A>::value &&
+                             boost::move_detail::is_trivially_move_assignable<B>::value ;
+};
+
+template<class T>
+struct is_trivially_copy_assignable;
+
+template<class A, class B>
+struct is_trivially_copy_constructible<boost::container::dtl::pair<A,B> >
+{
+   static const bool value = boost::move_detail::is_trivially_copy_constructible<A>::value &&
+                             boost::move_detail::is_trivially_copy_constructible<B>::value ;
+};
+
+template<class T>
+struct is_trivially_move_assignable;
+
+template<class A, class B>
+struct is_trivially_move_constructible<boost::container::dtl::pair<A,B> >
+{
+   static const bool value = boost::move_detail::is_trivially_move_constructible<A>::value &&
+                             boost::move_detail::is_trivially_move_constructible<B>::value ;
+};
+
+template<class T>
+struct is_trivially_destructible;
+
+template<class A, class B>
+struct is_trivially_destructible<boost::container::dtl::pair<A,B> >
+{
+   static const bool value = boost::move_detail::is_trivially_destructible<A>::value &&
+                             boost::move_detail::is_trivially_destructible<B>::value ;
+};
+
+
+}  //namespace move_detail{
+
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
diff --git a/include/boost/container/detail/pair_key_mapped_of_value.hpp b/include/boost/container/detail/pair_key_mapped_of_value.hpp
new file mode 100644
index 0000000..6112b87
--- /dev/null
+++ b/include/boost/container/detail/pair_key_mapped_of_value.hpp
@@ -0,0 +1,55 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_PAIR_KEY_MAPPED_OF_VALUE_HPP
+#define BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+
+template<class Key, class Mapped>
+struct pair_key_mapped_of_value
+{
+   typedef Key    key_type;
+   typedef Mapped mapped_type;
+
+   template<class Pair>
+   const key_type & key_of_value(const Pair &p) const
+   {  return p.first;  }
+
+   template<class Pair>
+   const mapped_type & mapped_of_value(const Pair &p) const
+   {  return p.second;  }
+
+   template<class Pair>
+   key_type & key_of_value(Pair &p) const
+   {  return const_cast<key_type&>(p.first);  }
+
+   template<class Pair>
+   mapped_type & mapped_of_value(Pair &p) const
+   {  return p.second;  }
+
+};
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
diff --git a/include/boost/container/detail/placement_new.hpp b/include/boost/container/detail/placement_new.hpp
new file mode 100644
index 0000000..c50981f
--- /dev/null
+++ b/include/boost/container/detail/placement_new.hpp
@@ -0,0 +1,30 @@
+#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
+#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+struct boost_container_new_t{};
+
+//avoid including <new>
+inline void *operator new(std::size_t, void *p, boost_container_new_t)
+{  return p;  }
+
+inline void operator delete(void *, void *, boost_container_new_t)
+{}
+
+#endif   //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
diff --git a/include/boost/container/detail/pool_common.hpp b/include/boost/container/detail/pool_common.hpp
new file mode 100644
index 0000000..f42c1dd
--- /dev/null
+++ b/include/boost/container/detail/pool_common.hpp
@@ -0,0 +1,57 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_POOL_COMMON_HPP
+#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/intrusive/slist.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class VoidPointer>
+struct node_slist
+{
+   //This hook will be used to chain the individual nodes
+    typedef typename bi::make_slist_base_hook
+      <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type slist_hook_t;
+
+   //A node object will hold node_t when it's not allocated
+   typedef slist_hook_t node_t;
+
+   typedef typename bi::make_slist
+      <node_t, bi::linear<true>, bi::cache_last<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
+};
+
+template<class T>
+struct is_stateless_segment_manager
+{
+   static const bool value = false;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/include/boost/container/detail/pool_common_alloc.hpp b/include/boost/container/detail/pool_common_alloc.hpp
new file mode 100644
index 0000000..bfb82f5
--- /dev/null
+++ b/include/boost/container/detail/pool_common_alloc.hpp
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_POOL_COMMON_ALLOC_HPP
+#define BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/throw_exception.hpp>
+
+#include <boost/intrusive/slist.hpp>
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/container/detail/dlmalloc.hpp>
+#include <cstddef>
+
+namespace boost{
+namespace container{
+namespace dtl{
+
+struct node_slist_helper
+   : public boost::container::dtl::node_slist<void*>
+{};
+
+struct fake_segment_manager
+{
+   typedef void * void_pointer;
+   static const std::size_t PayloadPerAllocation = BOOST_CONTAINER_ALLOCATION_PAYLOAD;
+
+   typedef boost::container::dtl::
+      basic_multiallocation_chain<void*>              multiallocation_chain;
+   static void deallocate(void_pointer p)
+   { dlmalloc_free(p); }
+
+   static void deallocate_many(multiallocation_chain &chain)
+   {
+      std::size_t size = chain.size();
+      std::pair<void*, void*> ptrs = chain.extract_data();
+      dlmalloc_memchain dlchain;
+      BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&dlchain, ptrs.first, ptrs.second, size);
+      dlmalloc_multidealloc(&dlchain);
+   }
+
+   typedef std::ptrdiff_t  difference_type;
+   typedef std::size_t     size_type;
+
+   static void *allocate_aligned(std::size_t nbytes, std::size_t alignment)
+   {
+      void *ret = dlmalloc_memalign(nbytes, alignment);
+      if(!ret)
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+
+   static void *allocate(std::size_t nbytes)
+   {
+      void *ret = dlmalloc_malloc(nbytes);
+      if(!ret)
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+};
+
+}  //namespace boost{
+}  //namespace container{
+}  //namespace dtl{
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class T>
+struct is_stateless_segment_manager;
+
+template<>
+struct is_stateless_segment_manager
+   <boost::container::dtl::fake_segment_manager>
+{
+   static const bool value = true;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
diff --git a/include/boost/container/detail/pool_resource.hpp b/include/boost/container/detail/pool_resource.hpp
new file mode 100644
index 0000000..e5f59f5
--- /dev/null
+++ b/include/boost/container/detail/pool_resource.hpp
@@ -0,0 +1,191 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_POOL_RESOURCE_HPP
+#define BOOST_CONTAINER_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/pmr/memory_resource.hpp>
+#include <boost/container/detail/block_list.hpp>
+#include <boost/container/pmr/pool_options.hpp>
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace pmr {
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+class pool_data_t;
+
+static const std::size_t pool_options_minimum_max_blocks_per_chunk = 1u;
+static const std::size_t pool_options_default_max_blocks_per_chunk = 32u;
+static const std::size_t pool_options_minimum_largest_required_pool_block =
+   memory_resource::max_align > 2*sizeof(void*) ? memory_resource::max_align : 2*sizeof(void*);
+static const std::size_t pool_options_default_largest_required_pool_block =
+   pool_options_minimum_largest_required_pool_block > 4096u
+      ? pool_options_minimum_largest_required_pool_block : 4096u;
+
+#endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+class pool_resource
+{
+   typedef block_list_base<> block_list_base_t;
+
+   pool_options m_options;
+   memory_resource&   m_upstream;
+   block_list_base_t  m_oversized_list;
+   pool_data_t *m_pool_data;
+   std::size_t  m_pool_count;
+
+   static void priv_limit_option(std::size_t &val, std::size_t min, std::size_t max);
+   static std::size_t priv_pool_index(std::size_t block_size);
+   static std::size_t priv_pool_block(std::size_t index);
+
+   void priv_fix_options();
+   void priv_init_pools();
+   void priv_constructor_body();
+
+   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().
+   pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT;
+
+   //! <b>Effects</b>: Same as
+   //!   `pool_resource(pool_options(), get_default_resource())`.
+   pool_resource() BOOST_NOEXCEPT;
+
+   //! <b>Effects</b>: Same as
+   //!   `pool_resource(pool_options(), upstream)`.
+   explicit pool_resource(memory_resource* upstream) BOOST_NOEXCEPT;
+
+   //! <b>Effects</b>: Same as
+   //!   `pool_resource(opts, get_default_resource())`.
+   explicit pool_resource(const pool_options& opts) BOOST_NOEXCEPT;
+
+   #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   pool_resource(const pool_resource&) = delete;
+   pool_resource operator=(const pool_resource&) = delete;
+   #else
+   private:
+   pool_resource          (const pool_resource&);
+   pool_resource operator=(const pool_resource&);
+   public:
+   #endif
+
+   //! <b>Effects</b>: Calls
+   //!   `this->release()`.
+   virtual ~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;
+
+   public:  //public so that [un]synchronized_pool_resource can use them
+
+   //! <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 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`.
+   //!   from the pool specified by `pool_index`. 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_POOL_RESOURCE_HPP
diff --git a/include/boost/container/detail/singleton.hpp b/include/boost/container/detail/singleton.hpp
new file mode 100644
index 0000000..7601c3c
--- /dev/null
+++ b/include/boost/container/detail/singleton.hpp
@@ -0,0 +1,121 @@
+// Copyright (C) 2000 Stephen Cleary
+// Copyright (C) 2008 Ion Gaztanaga
+//
+// 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 for updates, documentation, and revision history.
+//
+// This file is a modified file from Boost.Pool
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013. 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_DETAIL_SINGLETON_DETAIL_HPP
+#define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+//
+// The following helper classes are placeholders for a generic "singleton"
+//  class.  The classes below support usage of singletons, including use in
+//  program startup/shutdown code, AS LONG AS there is only one thread
+//  running before main() begins, and only one thread running after main()
+//  exits.
+//
+// This class is also limited in that it can only provide singleton usage for
+//  classes with default constructors.
+//
+
+// The design of this class is somewhat twisted, but can be followed by the
+//  calling inheritance.  Let us assume that there is some user code that
+//  calls "singleton_default<T>::instance()".  The following (convoluted)
+//  sequence ensures that the same function will be called before main():
+//    instance() contains a call to create_object.do_nothing()
+//    Thus, object_creator is implicitly instantiated, and create_object
+//      must exist.
+//    Since create_object is a static member, its constructor must be
+//      called before main().
+//    The constructor contains a call to instance(), thus ensuring that
+//      instance() will be called before main().
+//    The first time instance() is called (i.e., before main()) is the
+//      latest point in program execution where the object of type T
+//      can be created.
+//    Thus, any call to instance() will auto-magically result in a call to
+//      instance() before main(), unless already present.
+//  Furthermore, since the instance() function contains the object, instead
+//  of the singleton_default class containing a static instance of the
+//  object, that object is guaranteed to be constructed (at the latest) in
+//  the first call to instance().  This permits calls to instance() from
+//  static code, even if that code is called before the file-scope objects
+//  in this file have been initialized.
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+// T must be: no-throw default constructible and no-throw destructible
+template <typename T>
+struct singleton_default
+{
+  private:
+    struct object_creator
+    {
+      // This constructor does nothing more than ensure that instance()
+      //  is called before main() begins, thus creating the static
+      //  T object before multithreading race issues can come up.
+      object_creator() { singleton_default<T>::instance(); }
+      inline void do_nothing() const { }
+    };
+    static object_creator create_object;
+
+    singleton_default();
+
+  public:
+    typedef T object_type;
+
+    // If, at any point (in user code), singleton_default<T>::instance()
+    //  is called, then the following function is instantiated.
+    static object_type & instance()
+    {
+      // This is the object that we return a reference to.
+      // It is guaranteed to be created before main() begins because of
+      //  the next line.
+      static object_type obj;
+
+      // The following line does nothing else than force the instantiation
+      //  of singleton_default<T>::create_object, whose constructor is
+      //  called before main() begins.
+      create_object.do_nothing();
+
+      return obj;
+    }
+};
+template <typename T>
+typename singleton_default<T>::object_creator
+singleton_default<T>::create_object;
+
+} // namespace dtl
+} // namespace container
+} // namespace boost
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
diff --git a/include/boost/container/detail/std_fwd.hpp b/include/boost/container/detail/std_fwd.hpp
new file mode 100644
index 0000000..0967812
--- /dev/null
+++ b/include/boost/container/detail/std_fwd.hpp
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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_DETAIL_STD_FWD_HPP
+#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//                        Standard predeclarations
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/std_ns_begin.hpp>
+BOOST_MOVE_STD_NS_BEG
+
+template<class T>
+class allocator;
+
+template<class T>
+struct less;
+
+template<class T1, class T2>
+struct pair;
+
+template<class T>
+struct char_traits;
+
+struct input_iterator_tag;
+struct forward_iterator_tag;
+struct bidirectional_iterator_tag;
+struct random_access_iterator_tag;
+
+template<class Container>
+class insert_iterator;
+
+struct allocator_arg_t;
+
+struct piecewise_construct_t;
+
+BOOST_MOVE_STD_NS_END
+#include <boost/move/detail/std_ns_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
diff --git a/include/boost/container/detail/thread_mutex.hpp b/include/boost/container/detail/thread_mutex.hpp
new file mode 100644
index 0000000..628f28b
--- /dev/null
+++ b/include/boost/container/detail/thread_mutex.hpp
@@ -0,0 +1,179 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2018-2018. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//
+// This code is partially based on the lightweight mutex implemented
+// by Boost.SmartPtr:
+//
+//  Copyright (c) 2002, 2003 Peter Dimov
+//  Copyright (c) Microsoft Corporation 2014
+//
+// 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
+#define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#if defined(BOOST_HAS_PTHREADS)
+
+#include <pthread.h>
+#include <boost/assert.hpp>
+
+namespace boost{
+namespace container {
+namespace dtl {
+
+class thread_mutex
+{
+   public:
+   thread_mutex()
+   {
+      BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0);
+   }
+
+   ~thread_mutex()
+   {
+     BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0);
+   }
+
+   void lock()
+   {
+      BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0);
+   }
+
+   void unlock()
+   {
+      BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0);
+   }
+
+   private:
+   thread_mutex(thread_mutex const &);
+   thread_mutex & operator=(thread_mutex const &);
+   
+   pthread_mutex_t m_mut;
+};
+
+} // namespace dtl {
+} // namespace container {
+} // namespace boost {
+
+#else //!BOOST_HAS_PTHREADS (Windows implementation)
+
+#ifdef BOOST_USE_WINDOWS_H
+
+#include <windows.h>
+
+namespace boost{
+namespace container {
+namespace dtl {
+
+typedef ::CRITICAL_SECTION win_critical_section;
+
+} // namespace dtl {
+} // namespace container {
+} // namespace boost {
+
+#else //! BOOST_USE_WINDOWS_H
+
+struct _RTL_CRITICAL_SECTION_DEBUG;
+struct _RTL_CRITICAL_SECTION;
+   
+namespace boost{
+namespace container {
+namespace dtl {
+
+#ifdef BOOST_PLAT_WINDOWS_UWP
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
+#else
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
+#endif
+extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
+extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
+extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
+
+struct win_critical_section
+{
+   struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo;
+   long LockCount;
+   long RecursionCount;
+   void * OwningThread;
+   void * LockSemaphore;
+   #if defined(_WIN64)
+   unsigned __int64 SpinCount;
+   #else
+   unsigned long SpinCount;
+   #endif
+};
+
+} // namespace dtl {
+} // namespace container {
+} // namespace boost {
+
+#endif   //BOOST_USE_WINDOWS_H
+
+namespace boost{
+namespace container {
+namespace dtl {
+
+class thread_mutex
+{
+   public:
+   thread_mutex()
+   {
+      #ifdef BOOST_PLAT_WINDOWS_UWP
+      InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0);
+      #else
+      InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
+      #endif
+   }
+
+   void lock()
+   {
+      EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
+   }
+
+   void unlock()
+   {
+      LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
+   }
+
+   ~thread_mutex()
+   {
+      DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
+   }
+  
+   private:
+   thread_mutex(thread_mutex const &);
+   thread_mutex & operator=(thread_mutex const &);
+   
+   win_critical_section m_crit_sect;
+};
+
+} // namespace dtl {
+} // namespace container {
+} // namespace boost {
+
+#endif   //BOOST_HAS_PTHREADS
+
+#endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
diff --git a/include/boost/container/detail/transform_iterator.hpp b/include/boost/container/detail/transform_iterator.hpp
new file mode 100644
index 0000000..ce81813
--- /dev/null
+++ b/include/boost/container/detail/transform_iterator.hpp
@@ -0,0 +1,180 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// 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_DETAIL_TRANSFORM_ITERATORS_HPP
+#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/iterator.hpp>
+
+namespace boost {
+namespace container {
+
+template <class PseudoReference>
+struct operator_arrow_proxy
+{
+   operator_arrow_proxy(const PseudoReference &px)
+      :  m_value(px)
+   {}
+
+   typedef PseudoReference element_type;
+
+   PseudoReference* operator->() const { return &m_value; }
+
+   mutable PseudoReference m_value;
+};
+
+template <class T>
+struct operator_arrow_proxy<T&>
+{
+   operator_arrow_proxy(T &px)
+      :  m_value(px)
+   {}
+
+   typedef T element_type;
+
+   T* operator->() const { return const_cast<T*>(&m_value); }
+
+   T &m_value;
+};
+
+template <class Iterator, class UnaryFunction>
+class transform_iterator
+   : public UnaryFunction
+   , public boost::container::iterator
+      < typename Iterator::iterator_category
+      , typename dtl::remove_reference<typename UnaryFunction::result_type>::type
+      , typename Iterator::difference_type
+      , operator_arrow_proxy<typename UnaryFunction::result_type>
+      , typename UnaryFunction::result_type>
+{
+   public:
+   explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+      :  UnaryFunction(f), m_it(it)
+   {}
+
+   explicit transform_iterator()
+      :  UnaryFunction(), m_it()
+   {}
+
+   //Constructors
+   transform_iterator& operator++()
+   { increment();   return *this;   }
+
+   transform_iterator operator++(int)
+   {
+      transform_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i == i2); }
+
+/*
+   friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i < i2); }
+*/
+   friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   transform_iterator& operator+=(typename Iterator::difference_type off)
+   {  this->advance(off); return *this;   }
+
+   transform_iterator operator+(typename Iterator::difference_type off) const
+   {
+      transform_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+   {  return right + off; }
+
+   transform_iterator& operator-=(typename Iterator::difference_type off)
+   {  this->advance(-off); return *this;   }
+
+   transform_iterator operator-(typename Iterator::difference_type off) const
+   {  return *this + (-off);  }
+
+   typename UnaryFunction::result_type operator*() const
+   { return dereference(); }
+
+   operator_arrow_proxy<typename UnaryFunction::result_type>
+      operator->() const
+   { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference());  }
+
+   Iterator & base()
+   {  return m_it;   }
+
+   const Iterator & base() const
+   {  return m_it;   }
+
+   private:
+   Iterator m_it;
+
+   void increment()
+   { ++m_it; }
+
+   void decrement()
+   { --m_it; }
+
+   bool equal(const transform_iterator &other) const
+   {  return m_it == other.m_it;   }
+
+   bool less(const transform_iterator &other) const
+   {  return other.m_it < m_it;   }
+
+   typename UnaryFunction::result_type dereference() const
+   { return UnaryFunction::operator()(*m_it); }
+
+   void advance(typename Iterator::difference_type n)
+   {  boost::container::iterator_advance(m_it, n); }
+
+   typename Iterator::difference_type distance_to(const transform_iterator &other)const
+   {  return boost::container::iterator_distance(other.m_it, m_it); }
+};
+
+template <class Iterator, class UnaryFunc>
+transform_iterator<Iterator, UnaryFunc>
+make_transform_iterator(Iterator it, UnaryFunc fun)
+{
+   return transform_iterator<Iterator, UnaryFunc>(it, fun);
+}
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp
new file mode 100644
index 0000000..c32e992
--- /dev/null
+++ b/include/boost/container/detail/tree.hpp
@@ -0,0 +1,1458 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_TREE_HPP
+#define BOOST_CONTAINER_TREE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/options.hpp>
+#include <boost/container/node_handle.hpp>
+
+// container/detail
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/rbtree.hpp>
+#include <boost/intrusive/avltree.hpp>
+#include <boost/intrusive/splaytree.hpp>
+#include <boost/intrusive/sgtree.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>   //pair
+#include <boost/intrusive/detail/tree_value_compare.hpp>    //tree_value_compare
+// move
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+
+
+
+#include <boost/container/detail/std_fwd.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+using boost::intrusive::tree_value_compare;
+
+template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+struct intrusive_tree_hook;
+
+template<class VoidPointer, bool OptimizeSize>
+struct intrusive_tree_hook<VoidPointer, boost::container::red_black_tree, OptimizeSize>
+{
+   typedef typename dtl::bi::make_set_base_hook
+      < dtl::bi::void_pointer<VoidPointer>
+      , dtl::bi::link_mode<dtl::bi::normal_link>
+      , dtl::bi::optimize_size<OptimizeSize>
+      >::type  type;
+};
+
+template<class VoidPointer, bool OptimizeSize>
+struct intrusive_tree_hook<VoidPointer, boost::container::avl_tree, OptimizeSize>
+{
+   typedef typename dtl::bi::make_avl_set_base_hook
+      < dtl::bi::void_pointer<VoidPointer>
+      , dtl::bi::link_mode<dtl::bi::normal_link>
+      , dtl::bi::optimize_size<OptimizeSize>
+      >::type  type;
+};
+
+template<class VoidPointer, bool OptimizeSize>
+struct intrusive_tree_hook<VoidPointer, boost::container::scapegoat_tree, OptimizeSize>
+{
+   typedef typename dtl::bi::make_bs_set_base_hook
+      < dtl::bi::void_pointer<VoidPointer>
+      , dtl::bi::link_mode<dtl::bi::normal_link>
+      >::type  type;
+};
+
+template<class VoidPointer, bool OptimizeSize>
+struct intrusive_tree_hook<VoidPointer, boost::container::splay_tree, OptimizeSize>
+{
+   typedef typename dtl::bi::make_bs_set_base_hook
+      < dtl::bi::void_pointer<VoidPointer>
+      , dtl::bi::link_mode<dtl::bi::normal_link>
+      >::type  type;
+};
+
+//This trait is used to type-pun std::pair because in C++03
+//compilers std::pair is useless for C++11 features
+template<class T>
+struct tree_internal_data_type
+{
+   typedef T type;
+};
+
+template<class T1, class T2>
+struct tree_internal_data_type< std::pair<T1, T2> >
+{
+   typedef pair<typename boost::move_detail::remove_const<T1>::type, T2> type;
+};
+
+//The node to be store in the tree
+template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+struct tree_node
+   :  public intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>::type
+{
+   private:
+   //BOOST_COPYABLE_AND_MOVABLE(tree_node)
+   tree_node();
+
+   public:
+   typedef typename intrusive_tree_hook
+      <VoidPointer, tree_type_value, OptimizeSize>::type hook_type;
+   typedef T value_type;
+   typedef typename tree_internal_data_type<T>::type     internal_type;
+
+   typedef tree_node< T, VoidPointer
+                    , tree_type_value, OptimizeSize>     node_t;
+
+   BOOST_CONTAINER_FORCEINLINE T &get_data()
+   {
+      T* ptr = reinterpret_cast<T*>(&this->m_data);
+      return *ptr;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE const T &get_data() const
+   {
+      const T* ptr = reinterpret_cast<const T*>(&this->m_data);
+      return *ptr;
+   }
+
+   internal_type m_data;
+
+   template<class T1, class T2>
+   BOOST_CONTAINER_FORCEINLINE void do_assign(const std::pair<const T1, T2> &p)
+   {
+      const_cast<T1&>(m_data.first) = p.first;
+      m_data.second  = p.second;
+   }
+
+   template<class T1, class T2>
+   BOOST_CONTAINER_FORCEINLINE void do_assign(const pair<const T1, T2> &p)
+   {
+      const_cast<T1&>(m_data.first) = p.first;
+      m_data.second  = p.second;
+   }
+
+   template<class V>
+   BOOST_CONTAINER_FORCEINLINE void do_assign(const V &v)
+   {  m_data = v; }
+
+   template<class T1, class T2>
+   BOOST_CONTAINER_FORCEINLINE void do_move_assign(std::pair<const T1, T2> &p)
+   {
+      const_cast<T1&>(m_data.first) = ::boost::move(p.first);
+      m_data.second = ::boost::move(p.second);
+   }
+
+   template<class T1, class T2>
+   BOOST_CONTAINER_FORCEINLINE void do_move_assign(pair<const T1, T2> &p)
+   {
+      const_cast<T1&>(m_data.first) = ::boost::move(p.first);
+      m_data.second  = ::boost::move(p.second);
+   }
+
+   template<class V>
+   BOOST_CONTAINER_FORCEINLINE void do_move_assign(V &v)
+   {  m_data = ::boost::move(v); }
+};
+
+template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+struct iiterator_node_value_type< tree_node<T, VoidPointer, tree_type_value, OptimizeSize> > {
+  typedef T type;
+};
+
+template<class Node, class Icont>
+class insert_equal_end_hint_functor
+{
+   Icont &icont_;
+
+   public:
+   BOOST_CONTAINER_FORCEINLINE insert_equal_end_hint_functor(Icont &icont)
+      :  icont_(icont)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
+   {  this->icont_.insert_equal(this->icont_.cend(), n); }
+};
+
+template<class Node, class Icont>
+class push_back_functor
+{
+   Icont &icont_;
+
+   public:
+   BOOST_CONTAINER_FORCEINLINE push_back_functor(Icont &icont)
+      :  icont_(icont)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
+   {  this->icont_.push_back(n); }
+};
+
+}//namespace dtl {
+
+namespace dtl {
+
+template< class NodeType, class NodeCompareType
+        , class SizeType,  class HookType
+        , boost::container::tree_type_enum tree_type_value>
+struct intrusive_tree_dispatch;
+
+template<class NodeType, class NodeCompareType, class SizeType, class HookType>
+struct intrusive_tree_dispatch
+   <NodeType, NodeCompareType, SizeType, HookType, boost::container::red_black_tree>
+{
+   typedef typename dtl::bi::make_rbtree
+      <NodeType
+      ,dtl::bi::compare<NodeCompareType>
+      ,dtl::bi::base_hook<HookType>
+      ,dtl::bi::constant_time_size<true>
+      ,dtl::bi::size_type<SizeType>
+      >::type  type;
+};
+
+template<class NodeType, class NodeCompareType, class SizeType, class HookType>
+struct intrusive_tree_dispatch
+   <NodeType, NodeCompareType, SizeType, HookType, boost::container::avl_tree>
+{
+   typedef typename dtl::bi::make_avltree
+      <NodeType
+      ,dtl::bi::compare<NodeCompareType>
+      ,dtl::bi::base_hook<HookType>
+      ,dtl::bi::constant_time_size<true>
+      ,dtl::bi::size_type<SizeType>
+      >::type  type;
+};
+
+template<class NodeType, class NodeCompareType, class SizeType, class HookType>
+struct intrusive_tree_dispatch
+   <NodeType, NodeCompareType, SizeType, HookType, boost::container::scapegoat_tree>
+{
+   typedef typename dtl::bi::make_sgtree
+      <NodeType
+      ,dtl::bi::compare<NodeCompareType>
+      ,dtl::bi::base_hook<HookType>
+      ,dtl::bi::floating_point<true>
+      ,dtl::bi::size_type<SizeType>
+      >::type  type;
+};
+
+template<class NodeType, class NodeCompareType, class SizeType, class HookType>
+struct intrusive_tree_dispatch
+   <NodeType, NodeCompareType, SizeType, HookType, boost::container::splay_tree>
+{
+   typedef typename dtl::bi::make_splaytree
+      <NodeType
+      ,dtl::bi::compare<NodeCompareType>
+      ,dtl::bi::base_hook<HookType>
+      ,dtl::bi::constant_time_size<true>
+      ,dtl::bi::size_type<SizeType>
+      >::type  type;
+};
+
+template<class Allocator, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+struct intrusive_tree_type
+{
+   private:
+   typedef typename boost::container::
+      allocator_traits<Allocator>::value_type              value_type;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::void_pointer            void_pointer;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::size_type               size_type;
+   typedef typename dtl::tree_node
+         < value_type, void_pointer
+         , tree_type_value, OptimizeSize>                   node_t;
+   typedef value_to_node_compare
+      <node_t, ValueCompare>                                node_compare_type;
+   //Deducing the hook type from node_t (e.g. node_t::hook_type) would
+   //provoke an early instantiation of node_t that could ruin recursive
+   //tree definitions, so retype the complete type to avoid any problem.
+   typedef typename intrusive_tree_hook
+      <void_pointer, tree_type_value
+      , OptimizeSize>::type                        hook_type;
+   public:
+   typedef typename intrusive_tree_dispatch
+      < node_t, node_compare_type
+      , size_type, hook_type
+      , tree_type_value>::type                     type;
+};
+
+//Trait to detect manually rebalanceable tree types
+template<boost::container::tree_type_enum tree_type_value>
+struct is_manually_balanceable
+{  static const bool value = true;  };
+
+template<>  struct is_manually_balanceable<red_black_tree>
+{  static const bool value = false; };
+
+template<>  struct is_manually_balanceable<avl_tree>
+{  static const bool value = false; };
+
+//Proxy traits to implement different operations depending on the
+//is_manually_balanceable<>::value
+template< boost::container::tree_type_enum tree_type_value
+        , bool IsManuallyRebalanceable = is_manually_balanceable<tree_type_value>::value>
+struct intrusive_tree_proxy
+{
+   template<class Icont>
+   BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &)   {}
+};
+
+template<boost::container::tree_type_enum tree_type_value>
+struct intrusive_tree_proxy<tree_type_value, true>
+{
+   template<class Icont>
+   BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &c)
+   {  c.rebalance(); }
+};
+
+}  //namespace dtl {
+
+namespace dtl {
+
+//This functor will be used with Intrusive clone functions to obtain
+//already allocated nodes from a intrusive container instead of
+//allocating new ones. When the intrusive container runs out of nodes
+//the node holder is used instead.
+template<class AllocHolder, bool DoMove>
+class RecyclingCloner
+{
+   typedef typename AllocHolder::intrusive_container  intrusive_container;
+   typedef typename AllocHolder::Node                 node_t;
+   typedef typename AllocHolder::NodePtr              node_ptr_type;
+
+   public:
+   RecyclingCloner(AllocHolder &holder, intrusive_container &itree)
+      :  m_holder(holder), m_icont(itree)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<true>)
+   {  p->do_move_assign(const_cast<node_t &>(other).m_data);   }
+
+   BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<false>)
+   {  p->do_assign(other.m_data);   }
+
+   node_ptr_type operator()(const node_t &other) const
+   {
+      if(node_ptr_type p = m_icont.unlink_leftmost_without_rebalance()){
+         //First recycle a node (this can't throw)
+         BOOST_TRY{
+            //This can throw
+            this->do_assign(p, other, bool_<DoMove>());
+            return p;
+         }
+         BOOST_CATCH(...){
+            //If there is an exception destroy the whole source
+            m_holder.destroy_node(p);
+            while((p = m_icont.unlink_leftmost_without_rebalance())){
+               m_holder.destroy_node(p);
+            }
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      else{
+         return m_holder.create_node(other.m_data);
+      }
+   }
+
+   AllocHolder &m_holder;
+   intrusive_container &m_icont;
+};
+
+
+template<class KeyCompare, class KeyOfValue>
+struct key_node_compare
+   :  public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
+{
+   BOOST_CONTAINER_FORCEINLINE explicit key_node_compare(const KeyCompare &comp)
+      :  base_t(comp)
+   {}
+
+   typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
+   typedef KeyCompare                  key_compare;
+   typedef KeyOfValue                  key_of_value;
+   typedef typename KeyOfValue::type   key_type;
+
+
+   template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+   BOOST_CONTAINER_FORCEINLINE static const key_type &
+      key_from(const tree_node<T, VoidPointer, tree_type_value, OptimizeSize> &n)
+   {
+      return key_of_value()(n.get_data());
+   }
+
+   template <class T>
+   BOOST_CONTAINER_FORCEINLINE static const T &
+      key_from(const T &t)
+   {
+      return t;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE const key_compare &key_comp() const
+   {  return static_cast<const key_compare &>(*this);  }
+
+   BOOST_CONTAINER_FORCEINLINE key_compare &key_comp()
+   {  return static_cast<key_compare &>(*this);  }
+
+   BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const
+   {  return this->key_comp()(key1, key2);  }
+
+   template<class U>
+   BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const
+   {  return this->key_comp()(key1, this->key_from(nonkey2));  }
+
+   template<class U>
+   BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const
+   {  return this->key_comp()(this->key_from(nonkey1), key2);  }
+
+   template<class U, class V>
+   BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const
+   {  return this->key_comp()(this->key_from(nonkey1), this->key_from(nonkey2));  }
+};
+
+template<class Options>
+struct get_tree_opt
+{
+   typedef Options type;
+};
+
+template<>
+struct get_tree_opt<void>
+{
+   typedef tree_assoc_defaults type;
+};
+
+template <class T, class KeyOfValue, class Compare, class Allocator, class Options>
+class tree
+   : public dtl::node_alloc_holder
+      < Allocator
+      , typename dtl::intrusive_tree_type
+         < Allocator, tree_value_compare
+            <typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue>
+         , get_tree_opt<Options>::type::tree_type
+         , get_tree_opt<Options>::type::optimize_size
+         >::type
+      >
+{
+   typedef tree_value_compare
+      < typename allocator_traits<Allocator>::pointer
+      , Compare, KeyOfValue>                                ValComp;
+   typedef typename get_tree_opt<Options>::type             options_type;
+   typedef typename dtl::intrusive_tree_type
+         < Allocator, ValComp
+         , options_type::tree_type
+         , options_type::optimize_size
+         >::type                                            Icont;
+   typedef dtl::node_alloc_holder
+      <Allocator, Icont>                                    AllocHolder;
+   typedef typename AllocHolder::NodePtr                    NodePtr;
+   typedef tree < T, KeyOfValue
+                , Compare, Allocator, Options>              ThisType;
+   typedef typename AllocHolder::NodeAlloc                  NodeAlloc;
+   typedef boost::container::
+      allocator_traits<NodeAlloc>                           allocator_traits_type;
+   typedef typename AllocHolder::ValAlloc                   ValAlloc;
+   typedef typename AllocHolder::Node                       Node;
+   typedef typename Icont::iterator                         iiterator;
+   typedef typename Icont::const_iterator                   iconst_iterator;
+   typedef dtl::allocator_destroyer<NodeAlloc> Destroyer;
+   typedef typename AllocHolder::alloc_version              alloc_version;
+   typedef intrusive_tree_proxy<options_type::tree_type>    intrusive_tree_proxy_t;
+
+   BOOST_COPYABLE_AND_MOVABLE(tree)
+
+   public:
+
+   typedef typename KeyOfValue::type                  key_type;
+   typedef T                                          value_type;
+   typedef Allocator                                  allocator_type;
+   typedef Compare                                    key_compare;
+   typedef ValComp                                    value_compare;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::pointer            pointer;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::const_pointer      const_pointer;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::reference          reference;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::const_reference    const_reference;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::size_type          size_type;
+   typedef typename boost::container::
+      allocator_traits<Allocator>::difference_type    difference_type;
+   typedef dtl::iterator_from_iiterator
+      <iiterator, false>                              iterator;
+   typedef dtl::iterator_from_iiterator
+      <iiterator, true >                              const_iterator;
+   typedef boost::container::reverse_iterator
+      <iterator>                                      reverse_iterator;
+   typedef boost::container::reverse_iterator
+      <const_iterator>                                const_reverse_iterator;
+   typedef node_handle
+      < NodeAlloc, void>                              node_type;
+   typedef insert_return_type_base
+      <iterator, node_type>                           insert_return_type;
+
+   typedef NodeAlloc                                  stored_allocator_type;
+
+   private:
+
+   typedef key_node_compare<key_compare, KeyOfValue>  KeyNodeCompare;
+
+   public:
+
+   BOOST_CONTAINER_FORCEINLINE tree()
+      : AllocHolder()
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp)
+      : AllocHolder(ValComp(comp))
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp, const allocator_type& a)
+      : AllocHolder(ValComp(comp), a)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit tree(const allocator_type& a)
+      : AllocHolder(a)
+   {}
+
+   template <class InputIterator>
+   tree(bool unique_insertion, InputIterator first, InputIterator last)
+      : AllocHolder(value_compare(key_compare()))
+   {
+      this->tree_construct(unique_insertion, first, last);
+      //AllocHolder clears in case of exception
+   }
+
+   template <class InputIterator>
+   tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp)
+      : AllocHolder(value_compare(comp))
+   {
+      this->tree_construct(unique_insertion, first, last);
+      //AllocHolder clears in case of exception
+   }
+
+   template <class InputIterator>
+   tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a)
+      : AllocHolder(value_compare(comp), a)
+   {
+      this->tree_construct(unique_insertion, first, last);
+      //AllocHolder clears in case of exception
+   }
+
+   //construct with ordered range
+   template <class InputIterator>
+   tree( ordered_range_t, InputIterator first, InputIterator last)
+      : AllocHolder(value_compare(key_compare()))
+   {
+      this->tree_construct(ordered_range_t(), first, last);
+   }
+
+   template <class InputIterator>
+   tree( ordered_range_t, InputIterator first, InputIterator last, const key_compare& comp)
+      : AllocHolder(value_compare(comp))
+   {
+      this->tree_construct(ordered_range_t(), first, last);
+   }
+
+   template <class InputIterator>
+   tree( ordered_range_t, InputIterator first, InputIterator last
+         , const key_compare& comp, const allocator_type& a)
+      : AllocHolder(value_compare(comp), a)
+   {
+      this->tree_construct(ordered_range_t(), first, last);
+   }
+
+   private:
+
+   template <class InputIterator>
+   void tree_construct(bool unique_insertion, InputIterator first, InputIterator last)
+   {
+      //Use cend() as hint to achieve linear time for
+      //ordered ranges as required by the standard
+      //for the constructor
+      if(unique_insertion){
+         const const_iterator end_it(this->cend());
+         for ( ; first != last; ++first){
+            this->insert_unique_convertible(end_it, *first);
+         }
+      }
+      else{
+         this->tree_construct_non_unique(first, last);
+      }
+   }
+
+   template <class InputIterator>
+   void tree_construct_non_unique(InputIterator first, InputIterator last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::enable_if_or
+         < void
+         , dtl::is_same<alloc_version, version_1>
+         , dtl::is_input_iterator<InputIterator>
+         >::type * = 0
+      #endif
+         )
+   {
+      //Use cend() as hint to achieve linear time for
+      //ordered ranges as required by the standard
+      //for the constructor
+      const const_iterator end_it(this->cend());
+      for ( ; first != last; ++first){
+         this->insert_equal_convertible(end_it, *first);
+      }
+   }
+
+   template <class InputIterator>
+   void tree_construct_non_unique(InputIterator first, InputIterator last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_same<alloc_version, version_1>
+         , dtl::is_input_iterator<InputIterator>
+         >::type * = 0
+      #endif
+         )
+   {
+      //Optimized allocation and construction
+      this->allocate_many_and_construct
+         ( first, boost::container::iterator_distance(first, last)
+         , insert_equal_end_hint_functor<Node, Icont>(this->icont()));
+   }
+
+   template <class InputIterator>
+   void tree_construct( ordered_range_t, InputIterator first, InputIterator last
+         #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_same<alloc_version, version_1>
+         , dtl::is_input_iterator<InputIterator>
+         >::type * = 0
+         #endif
+         )
+   {
+      //Optimized allocation and construction
+      this->allocate_many_and_construct
+         ( first, boost::container::iterator_distance(first, last)
+         , dtl::push_back_functor<Node, Icont>(this->icont()));
+      //AllocHolder clears in case of exception
+   }
+
+   template <class InputIterator>
+   void tree_construct( ordered_range_t, InputIterator first, InputIterator last
+         #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::enable_if_or
+         < void
+         , dtl::is_same<alloc_version, version_1>
+         , dtl::is_input_iterator<InputIterator>
+         >::type * = 0
+         #endif
+         )
+   {
+      for ( ; first != last; ++first){
+         this->push_back_impl(*first);
+      }
+   }
+
+   public:
+
+   BOOST_CONTAINER_FORCEINLINE tree(const tree& x)
+      :  AllocHolder(x, x.value_comp())
+   {
+      this->icont().clone_from
+         (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE tree(BOOST_RV_REF(tree) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      :  AllocHolder(BOOST_MOVE_BASE(AllocHolder, x), x.value_comp())
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE tree(const tree& x, const allocator_type &a)
+      :  AllocHolder(x.value_comp(), a)
+   {
+      this->icont().clone_from
+         (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+      //AllocHolder clears in case of exception
+   }
+
+   tree(BOOST_RV_REF(tree) x, const allocator_type &a)
+      :  AllocHolder(x.value_comp(), a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->icont().clone_from
+            (boost::move(x.icont()), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
+      }
+      //AllocHolder clears in case of exception
+   }
+
+   BOOST_CONTAINER_FORCEINLINE ~tree()
+   {} //AllocHolder clears the tree
+
+   tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->get_stored_allocator();
+         const NodeAlloc &x_alloc  = x.get_stored_allocator();
+         dtl::bool_<allocator_traits<NodeAlloc>::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         //Transfer all the nodes to a temporary tree
+         //If anything goes wrong, all the nodes will be destroyed
+         //automatically
+         Icont other_tree(::boost::move(this->icont()));
+
+         //Now recreate the source tree reusing nodes stored by other_tree
+         this->icont().clone_from
+            (x.icont()
+            , RecyclingCloner<AllocHolder, false>(*this, other_tree)
+            , Destroyer(this->node_alloc()));
+
+         //If there are remaining nodes, destroy them
+         NodePtr p;
+         while((p = other_tree.unlink_leftmost_without_rebalance())){
+            AllocHolder::destroy_node(p);
+         }
+      }
+      return *this;
+   }
+
+   tree& operator=(BOOST_RV_REF(tree) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {
+      BOOST_ASSERT(this != &x);
+      NodeAlloc &this_alloc = this->node_alloc();
+      NodeAlloc &x_alloc    = x.node_alloc();
+      const bool propagate_alloc = allocator_traits<NodeAlloc>::
+            propagate_on_container_move_assignment::value;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy
+         this->clear();
+         //Move allocator if needed
+         this->AllocHolder::move_assign_alloc(x);
+         //Obtain resources
+         this->icont() = boost::move(x.icont());
+      }
+      //Else do a one by one move
+      else{
+         //Transfer all the nodes to a temporary tree
+         //If anything goes wrong, all the nodes will be destroyed
+         //automatically
+         Icont other_tree(::boost::move(this->icont()));
+
+         //Now recreate the source tree reusing nodes stored by other_tree
+         this->icont().clone_from
+            (::boost::move(x.icont())
+            , RecyclingCloner<AllocHolder, true>(*this, other_tree)
+            , Destroyer(this->node_alloc()));
+
+         //If there are remaining nodes, destroy them
+         NodePtr p;
+         while((p = other_tree.unlink_leftmost_without_rebalance())){
+            AllocHolder::destroy_node(p);
+         }
+      }
+      return *this;
+   }
+
+   public:
+   // accessors:
+   BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
+   {  return this->icont().value_comp().predicate(); }
+
+   BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
+   {  return this->icont().value_comp().predicate().key_comp(); }
+
+   BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
+   {  return allocator_type(this->node_alloc()); }
+
+   BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
+   {  return this->node_alloc(); }
+
+   BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
+   {  return this->node_alloc(); }
+
+   BOOST_CONTAINER_FORCEINLINE iterator begin()
+   { return iterator(this->icont().begin()); }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
+   {  return this->cbegin();  }
+
+   BOOST_CONTAINER_FORCEINLINE iterator end()
+   {  return iterator(this->icont().end());  }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator end() const
+   {  return this->cend();  }
+
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
+   {  return reverse_iterator(end());  }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
+   {  return this->crbegin();  }
+
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
+   {  return reverse_iterator(begin());   }
+
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
+   {  return this->crend();   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
+   { return const_iterator(this->non_const_icont().begin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
+   { return const_iterator(this->non_const_icont().end()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
+   { return const_reverse_iterator(cend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
+   { return const_reverse_iterator(cbegin()); }
+
+   BOOST_CONTAINER_FORCEINLINE bool empty() const
+   {  return !this->size();  }
+
+   BOOST_CONTAINER_FORCEINLINE size_type size() const
+   {  return this->icont().size();   }
+
+   BOOST_CONTAINER_FORCEINLINE size_type max_size() const
+   {  return AllocHolder::max_size();  }
+
+   BOOST_CONTAINER_FORCEINLINE void swap(ThisType& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
+   {  AllocHolder::swap(x);   }
+
+   public:
+
+   typedef typename Icont::insert_commit_data insert_commit_data;
+
+   // insert/erase
+   std::pair<iterator,bool> insert_unique_check
+      (const key_type& key, insert_commit_data &data)
+   {
+      std::pair<iiterator, bool> ret =
+         this->icont().insert_unique_check(key, KeyNodeCompare(key_comp()), data);
+      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+   }
+
+   std::pair<iterator,bool> insert_unique_check
+      (const_iterator hint, const key_type& key, insert_commit_data &data)
+   {
+      BOOST_ASSERT((priv_is_linked)(hint));
+      std::pair<iiterator, bool> ret =
+         this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(key_comp()), data);
+      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+   }
+
+   template<class MovableConvertible>
+   iterator insert_unique_commit
+      (BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data)
+   {
+      NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_unique_commit(*tmp, data));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   template<class MovableConvertible>
+   std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) v)
+   {
+      insert_commit_data data;
+      std::pair<iterator,bool> ret =
+         this->insert_unique_check(KeyOfValue()(v), data);
+      if(ret.second){
+         ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
+      }
+      return ret;
+   }
+
+   private:
+
+   template<class KeyConvertible, class M>
+   iiterator priv_insert_or_assign_commit
+      (BOOST_FWD_REF(KeyConvertible) key, BOOST_FWD_REF(M) obj, insert_commit_data &data)
+   {
+      NodePtr tmp = AllocHolder::create_node(boost::forward<KeyConvertible>(key), boost::forward<M>(obj));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iiterator ret(this->icont().insert_unique_commit(*tmp, data));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   bool priv_is_linked(const_iterator const position) const
+   {
+      iiterator const cur(position.get());
+      return   cur == this->icont().end() ||
+               cur == this->icont().root() ||
+               iiterator(cur).go_parent().go_left()  == cur ||
+               iiterator(cur).go_parent().go_right() == cur;
+   }
+
+   template<class MovableConvertible>
+   void push_back_impl(BOOST_FWD_REF(MovableConvertible) v)
+   {
+      NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
+      //push_back has no-throw guarantee so avoid any deallocator/destroyer
+      this->icont().push_back(*tmp);
+   }
+
+   std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
+   {
+      value_type &v = p->get_data();
+      insert_commit_data data;
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc());
+      std::pair<iterator,bool> ret =
+         this->insert_unique_check(KeyOfValue()(v), data);
+      if(!ret.second){
+         return ret;
+      }
+      //No throw insertion part, release rollback
+      destroy_deallocator.release();
+      return std::pair<iterator,bool>
+         ( iterator(this->icont().insert_unique_commit(*p, data))
+         , true );
+   }
+
+   iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
+   {
+      BOOST_ASSERT((priv_is_linked)(hint));
+      value_type &v = p->get_data();
+      insert_commit_data data;
+      std::pair<iterator,bool> ret =
+         this->insert_unique_check(hint, KeyOfValue()(v), data);
+      if(!ret.second){
+         Destroyer(this->node_alloc())(p);
+         return ret.first;
+      }
+      return iterator(this->icont().insert_unique_commit(*p, data));
+   }
+
+   public:
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
+   {  return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...));   }
+
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {  return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...));   }
+
+   template <class... Args>
+   iterator emplace_equal(BOOST_FWD_REF(Args)... args)
+   {
+      NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   template <class... Args>
+   iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {
+      BOOST_ASSERT((priv_is_linked)(hint));
+      NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_equal(hint.get(), *tmp));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   template <class KeyType, class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace
+      (const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
+   {
+      insert_commit_data data;
+      const key_type & k = key;  //Support emulated rvalue references
+      std::pair<iiterator, bool> ret =
+         hint == const_iterator() ? this->icont().insert_unique_check(            k, KeyNodeCompare(key_comp()), data)
+                                  : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);
+      if(ret.second){
+         ret.first = this->icont().insert_unique_commit
+            (*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key), boost::forward<Args>(args)...), data);
+      }
+      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
+   {  return this->emplace_unique_impl(AllocHolder::create_node(BOOST_MOVE_FWD##N));  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_equal(BOOST_MOVE_UREF##N)\
+   {\
+      NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
+      iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));\
+      destroy_deallocator.release();\
+      return ret;\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      BOOST_ASSERT((priv_is_linked)(hint));\
+      NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
+      iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
+      destroy_deallocator.release();\
+      return ret;\
+   }\
+   \
+   template <class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool>\
+      try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      insert_commit_data data;\
+      const key_type & k = key;\
+      std::pair<iiterator, bool> ret =\
+         hint == const_iterator() ? this->icont().insert_unique_check(            k, KeyNodeCompare(key_comp()), data)\
+                                  : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);\
+      if(ret.second){\
+         ret.first = this->icont().insert_unique_commit\
+            (*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\
+      }\
+      return std::pair<iterator, bool>(iterator(ret.first), ret.second);\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_TREE_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_TREE_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template<class MovableConvertible>
+   iterator insert_unique_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
+   {
+      BOOST_ASSERT((priv_is_linked)(hint));
+      insert_commit_data data;
+      std::pair<iterator,bool> ret =
+         this->insert_unique_check(hint, KeyOfValue()(v), data);
+      if(!ret.second)
+         return ret.first;
+      return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
+   }
+
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_unique, value_type, iterator, this->insert_unique_convertible, const_iterator, const_iterator)
+
+   template <class InputIterator>
+   void insert_unique(InputIterator first, InputIterator last)
+   {
+      for( ; first != last; ++first)
+         this->insert_unique(*first);
+   }
+
+   iterator insert_equal(const value_type& v)
+   {
+      NodePtr tmp(AllocHolder::create_node(v));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   template<class MovableConvertible>
+   iterator insert_equal(BOOST_FWD_REF(MovableConvertible) v)
+   {
+      NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   template<class MovableConvertible>
+   iterator insert_equal_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
+   {
+      BOOST_ASSERT((priv_is_linked)(hint));
+      NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
+      scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
+      iterator ret(this->icont().insert_equal(hint.get(), *tmp));
+      destroy_deallocator.release();
+      return ret;
+   }
+
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_equal, value_type, iterator, this->insert_equal_convertible, const_iterator, const_iterator)
+
+   template <class InputIterator>
+   void insert_equal(InputIterator first, InputIterator last)
+   {
+      for( ; first != last; ++first)
+         this->insert_equal(*first);
+   }
+
+   template<class KeyType, class M>
+   std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
+   {
+      insert_commit_data data;
+      const key_type & k = key;  //Support emulated rvalue references
+      std::pair<iiterator, bool> ret =
+         hint == const_iterator() ? this->icont().insert_unique_check(k, KeyNodeCompare(key_comp()), data)
+                                  : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);
+      if(ret.second){
+         ret.first = this->priv_insert_or_assign_commit(boost::forward<KeyType>(key), boost::forward<M>(obj), data);
+      }
+      else{
+         ret.first->get_data().second = boost::forward<M>(obj);
+      }
+      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+   }
+
+   iterator erase(const_iterator position)
+   {
+      BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
+      return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc())));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k)
+   {  return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); }
+
+   iterator erase(const_iterator first, const_iterator last)
+   {
+      BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
+      BOOST_ASSERT(first == last || (priv_is_linked)(last));
+      return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
+   }
+
+   node_type extract(const key_type& k)
+   {
+      iterator const it = this->find(k);
+      if(this->end() != it){
+         return this->extract(it);
+      }
+      return node_type();
+   }
+
+   node_type extract(const_iterator position)
+   {
+      BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
+      iiterator const iit(position.get());
+      this->icont().erase(iit);
+      return node_type(iit.operator->(), this->node_alloc());
+   }
+
+   insert_return_type insert_unique_node(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      return this->insert_unique_node(this->end(), boost::move(nh));
+   }
+
+   insert_return_type insert_unique_node(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      insert_return_type irt; //inserted == false, node.empty()
+      if(!nh.empty()){
+         insert_commit_data data;
+         std::pair<iterator,bool> ret =
+            this->insert_unique_check(hint, KeyOfValue()(nh.value()), data);
+         if(ret.second){
+            irt.inserted = true;
+            irt.position = iterator(this->icont().insert_unique_commit(*nh.get(), data));
+            nh.release();
+         }
+         else{
+            irt.position = ret.first;
+            irt.node = boost::move(nh);
+         }
+      }
+      else{
+         irt.position = this->end();
+      }
+      return BOOST_MOVE_RET(insert_return_type, irt);
+   }
+
+   iterator insert_equal_node(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      if(nh.empty()){
+         return this->end();
+      }
+      else{
+         NodePtr const p(nh.release());
+         return iterator(this->icont().insert_equal(*p));
+      }
+   }
+
+   iterator insert_equal_node(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      if(nh.empty()){
+         return this->end();
+      }
+      else{
+         NodePtr const p(nh.release());
+         return iterator(this->icont().insert_equal(hint.get(), *p));
+      }
+   }
+
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge_unique(tree<T, KeyOfValue, C2, Allocator, Options>& source)
+   {  return this->icont().merge_unique(source.icont()); }
+
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge_equal(tree<T, KeyOfValue, C2, Allocator, Options>& source)
+   {  return this->icont().merge_equal(source.icont());  }
+   BOOST_CONTAINER_FORCEINLINE void clear()
+   {  AllocHolder::clear(alloc_version());  }
+
+   // search operations. Const and non-const overloads even if no iterator is returned
+   // so splay implementations can to their rebalancing when searching in non-const versions
+   BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& k)
+   {  return iterator(this->icont().find(k, KeyNodeCompare(key_comp())));  }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp())));  }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, iterator>::type
+         find(const K& k)
+   {  return iterator(this->icont().find(k, KeyNodeCompare(key_comp())));  }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type
+         find(const K& k) const
+   {  return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp())));  }
+
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& k) const
+   {  return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, size_type>::type
+         count(const K& k) const
+   {  return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); }
+
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
+   {  return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp())));  }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp())));  }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, iterator>::type
+         lower_bound(const K& k)
+   {  return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp())));  }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type
+         lower_bound(const K& k) const
+   {  return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp())));  }
+
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
+   {  return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp())));   }
+
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp())));  }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, iterator>::type
+         upper_bound(const K& k)
+   {  return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp())));   }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type
+         upper_bound(const K& k) const
+   {  return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp())));  }
+
+   std::pair<iterator,iterator> equal_range(const key_type& k)
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->icont().equal_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+   }
+
+   std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<const_iterator,const_iterator>
+         (const_iterator(ret.first), const_iterator(ret.second));
+   }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, std::pair<iterator,iterator> >::type
+         equal_range(const K& k)
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->icont().equal_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+   }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, std::pair<const_iterator, const_iterator> >::type
+         equal_range(const K& k) const
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<const_iterator,const_iterator>
+         (const_iterator(ret.first), const_iterator(ret.second));
+   }
+
+   std::pair<iterator,iterator> lower_bound_range(const key_type& k)
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+   }
+
+   std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<const_iterator,const_iterator>
+         (const_iterator(ret.first), const_iterator(ret.second));
+   }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, std::pair<iterator,iterator> >::type
+         lower_bound_range(const K& k)
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+   }
+
+   template <class K>
+   BOOST_CONTAINER_FORCEINLINE
+      typename dtl::enable_if_transparent<key_compare, K, std::pair<const_iterator, const_iterator> >::type
+         lower_bound_range(const K& k) const
+   {
+      std::pair<iiterator, iiterator> ret =
+         this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp()));
+      return std::pair<const_iterator,const_iterator>
+         (const_iterator(ret.first), const_iterator(ret.second));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void rebalance()
+   {  intrusive_tree_proxy_t::rebalance(this->icont());   }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const tree& x, const tree& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<(const tree& x, const tree& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const tree& x, const tree& y)
+   {  return !(x == y);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>(const tree& x, const tree& y)
+   {  return y < x;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const tree& x, const tree& y)
+   {  return !(y < x);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const tree& x, const tree& y)
+   {  return !(x < y);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend void swap(tree& x, tree& y)
+   {  x.swap(y);  }
+};
+
+} //namespace dtl {
+} //namespace container {
+
+template <class T>
+struct has_trivial_destructor_after_move;
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class KeyOfValue, class Compare, class Allocator, class Options>
+struct has_trivial_destructor_after_move
+   < 
+      ::boost::container::dtl::tree
+         <T, KeyOfValue, Compare, Allocator, Options>
+   >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+} //namespace boost  {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_TREE_HPP
diff --git a/include/boost/container/detail/type_traits.hpp b/include/boost/container/detail/type_traits.hpp
new file mode 100644
index 0000000..686cc40
--- /dev/null
+++ b/include/boost/container/detail/type_traits.hpp
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-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.
+//
+// The alignment and Type traits implementation comes from
+// John Maddock's TypeTraits library.
+//
+// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/type_traits.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+using ::boost::move_detail::enable_if;
+using ::boost::move_detail::enable_if_and;
+using ::boost::move_detail::is_same;
+using ::boost::move_detail::is_different;
+using ::boost::move_detail::is_pointer;
+using ::boost::move_detail::add_reference;
+using ::boost::move_detail::add_const;
+using ::boost::move_detail::add_const_reference;
+using ::boost::move_detail::remove_const;
+using ::boost::move_detail::remove_reference;
+using ::boost::move_detail::make_unsigned;
+using ::boost::move_detail::is_floating_point;
+using ::boost::move_detail::is_integral;
+using ::boost::move_detail::is_enum;
+using ::boost::move_detail::is_pod;
+using ::boost::move_detail::is_empty;
+using ::boost::move_detail::is_trivially_destructible;
+using ::boost::move_detail::is_trivially_default_constructible;
+using ::boost::move_detail::is_trivially_copy_constructible;
+using ::boost::move_detail::is_trivially_move_constructible;
+using ::boost::move_detail::is_trivially_copy_assignable;
+using ::boost::move_detail::is_trivially_move_assignable;
+using ::boost::move_detail::is_nothrow_default_constructible;
+using ::boost::move_detail::is_nothrow_copy_constructible;
+using ::boost::move_detail::is_nothrow_move_constructible;
+using ::boost::move_detail::is_nothrow_copy_assignable;
+using ::boost::move_detail::is_nothrow_move_assignable;
+using ::boost::move_detail::is_nothrow_swappable;
+using ::boost::move_detail::alignment_of;
+using ::boost::move_detail::aligned_storage;
+using ::boost::move_detail::nat;
+using ::boost::move_detail::max_align_t;
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
diff --git a/include/boost/container/detail/value_functors.hpp b/include/boost/container/detail/value_functors.hpp
new file mode 100644
index 0000000..a2c494c
--- /dev/null
+++ b/include/boost/container/detail/value_functors.hpp
@@ -0,0 +1,36 @@
+#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
+#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017. 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_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//Functors for member algorithm defaults
+template<class ValueType>
+struct value_less
+{
+   bool operator()(const ValueType &a, const ValueType &b) const
+      {  return a < b;  }
+};
+
+template<class ValueType>
+struct value_equal
+{
+   bool operator()(const ValueType &a, const ValueType &b) const
+      {  return a == b;  }
+};
+
+#endif   //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
diff --git a/include/boost/container/detail/value_init.hpp b/include/boost/container/detail/value_init.hpp
new file mode 100644
index 0000000..35b0aa1
--- /dev/null
+++ b/include/boost/container/detail/value_init.hpp
@@ -0,0 +1,51 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013.
+//
+// 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_DETAIL_VALUE_INIT_HPP
+#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<class T>
+struct value_init
+{
+   value_init()
+      : m_t()
+   {}
+
+   operator T &() { return m_t; }
+
+   T &get() { return m_t; }
+
+   T m_t;
+};
+
+}  //namespace dtl {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
diff --git a/include/boost/container/detail/variadic_templates_tools.hpp b/include/boost/container/detail/variadic_templates_tools.hpp
new file mode 100644
index 0000000..4f16fb0
--- /dev/null
+++ b/include/boost/container/detail/variadic_templates_tools.hpp
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2013. 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_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/move/utility_core.hpp>
+
+#include <boost/container/detail/type_traits.hpp>
+#include <cstddef>   //std::size_t
+
+namespace boost {
+namespace container {
+namespace dtl {
+
+template<typename... Values>
+class tuple;
+
+template<> class tuple<>
+{};
+
+template<typename Head, typename... Tail>
+class tuple<Head, Tail...>
+   : private tuple<Tail...>
+{
+   typedef tuple<Tail...> inherited;
+
+   public:
+   tuple()
+      : inherited(), m_head()
+   {}
+
+   template<class U, class ...Args>
+   tuple(U &&u, Args && ...args)
+      : inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u))
+   {}
+
+   // Construct tuple from another tuple.
+   template<typename... VValues>
+   tuple(const tuple<VValues...>& other)
+      : inherited(other.tail()), m_head(other.head())
+   {}
+
+   template<typename... VValues>
+   tuple& operator=(const tuple<VValues...>& other)
+   {
+      m_head = other.head();
+      tail() = other.tail();
+      return this;
+   }
+
+   typename add_reference<Head>::type head()             {  return m_head; }
+   typename add_reference<const Head>::type head() const {  return m_head; }
+
+   inherited& tail()             { return *this; }
+   const inherited& tail() const { return *this; }
+
+   protected:
+   Head m_head;
+};
+
+
+template<typename... Values>
+tuple<Values&&...> forward_as_tuple_impl(Values&&... values)
+{ return tuple<Values&&...>(::boost::forward<Values>(values)...); }
+
+template<int I, typename Tuple>
+struct tuple_element;
+
+template<int I, typename Head, typename... Tail>
+struct tuple_element<I, tuple<Head, Tail...> >
+{
+   typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct tuple_element<0, tuple<Head, Tail...> >
+{
+   typedef Head type;
+};
+
+template<int I, typename Tuple>
+class get_impl;
+
+template<int I, typename Head, typename... Values>
+class get_impl<I, tuple<Head, Values...> >
+{
+   typedef typename tuple_element<I-1, tuple<Values...> >::type   Element;
+   typedef get_impl<I-1, tuple<Values...> >                       Next;
+
+   public:
+   typedef typename add_reference<Element>::type                  type;
+   typedef typename add_const_reference<Element>::type            const_type;
+   static type get(tuple<Head, Values...>& t)              { return Next::get(t.tail()); }
+   static const_type get(const tuple<Head, Values...>& t)  { return Next::get(t.tail()); }
+};
+
+template<typename Head, typename... Values>
+class get_impl<0, tuple<Head, Values...> >
+{
+   public:
+   typedef typename add_reference<Head>::type         type;
+   typedef typename add_const_reference<Head>::type   const_type;
+   static type       get(tuple<Head, Values...>& t)      { return t.head(); }
+   static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
+};
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
+{  return get_impl<I, tuple<Values...> >::get(t);  }
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
+{  return get_impl<I, tuple<Values...> >::get(t);  }
+
+////////////////////////////////////////////////////
+// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
+// be used to "unpack" into comma-separated values
+// in a function call.
+////////////////////////////////////////////////////
+
+template<std::size_t...> struct index_tuple{ typedef index_tuple type; };
+
+template<class S1, class S2> struct concat_index_tuple;
+
+template<std::size_t... I1, std::size_t... I2>
+struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>>
+  : index_tuple<I1..., (sizeof...(I1)+I2)...>{};
+
+template<std::size_t N> struct build_number_seq;
+
+template<std::size_t N> 
+struct build_number_seq
+   : concat_index_tuple<typename build_number_seq<N/2>::type
+                       ,typename build_number_seq<N - N/2 >::type
+   >::type
+{};
+
+template<> struct build_number_seq<0> : index_tuple<>{};
+template<> struct build_number_seq<1> : index_tuple<0>{};
+
+}}}   //namespace boost { namespace container { namespace dtl {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
diff --git a/include/boost/container/detail/version_type.hpp b/include/boost/container/detail/version_type.hpp
new file mode 100644
index 0000000..c2531cc
--- /dev/null
+++ b/include/boost/container/detail/version_type.hpp
@@ -0,0 +1,110 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+//       This code comes from N1953 document by Howard E. Hinnant
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
+#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+namespace boost{
+namespace container {
+namespace dtl {
+
+template <class T, unsigned V>
+struct version_type
+    : public dtl::integral_constant<unsigned, V>
+{
+    typedef T type;
+
+    version_type(const version_type<T, 0>&);
+};
+
+namespace impl{
+
+template <class T,
+          bool = dtl::is_convertible<version_type<T, 0>, typename T::version>::value>
+struct extract_version
+{
+   static const unsigned value = 1;
+};
+
+template <class T>
+struct extract_version<T, true>
+{
+   static const unsigned value = T::version::value;
+};
+
+template <class T>
+struct has_version
+{
+   private:
+   struct two {char _[2];};
+   template <class U> static two test(...);
+   template <class U> static char test(const typename U::version*);
+   public:
+   static const bool value = sizeof(test<T>(0)) == 1;
+   void dummy(){}
+};
+
+template <class T, bool = has_version<T>::value>
+struct version
+{
+   static const unsigned value = 1;
+};
+
+template <class T>
+struct version<T, true>
+{
+   static const unsigned value = extract_version<T>::value;
+};
+
+}  //namespace impl
+
+template <class T>
+struct version
+   : public dtl::integral_constant<unsigned, impl::version<T>::value>
+{};
+
+template<class T, unsigned N>
+struct is_version
+{
+   static const bool value =
+      is_same< typename version<T>::type, integral_constant<unsigned, N> >::value;
+};
+
+}  //namespace dtl {
+
+typedef dtl::integral_constant<unsigned, 0> version_0;
+typedef dtl::integral_constant<unsigned, 1> version_1;
+typedef dtl::integral_constant<unsigned, 2> version_2;
+
+}  //namespace container {
+}  //namespace boost{
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp
new file mode 100644
index 0000000..736326b
--- /dev/null
+++ b/include/boost/container/detail/workaround.hpp
@@ -0,0 +1,111 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_WORKAROUND_HPP
+#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#if    !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
+    && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
+   #define BOOST_CONTAINER_PERFECT_FORWARDING
+#endif
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
+    && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
+   #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
+#endif
+
+#if defined(BOOST_GCC_VERSION)
+#  if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
+#     define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
+#  endif
+#elif defined(BOOST_MSVC)
+#  if _MSC_FULL_VER < 180020827
+#     define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
+#  endif
+#elif defined(BOOST_CLANG)
+#  if !__has_feature(cxx_delegating_constructors)
+#     define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
+#  endif
+#endif
+
+#if defined(BOOST_MSVC) && (_MSC_VER < 1400)
+   #define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
+#endif
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
+#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
+#endif
+
+//Macros for documentation purposes. For code, expands to the argument
+#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
+#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
+
+//Macros for memset optimization. In most platforms
+//memsetting pointers and floatings is safe and faster.
+//
+//If your platform does not offer these guarantees
+//define these to value zero.
+#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO
+#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1
+#endif
+
+#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL
+#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL
+#endif
+
+#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2
+#define BOOST_CONTAINER_I ,
+#define BOOST_CONTAINER_DOCIGN(T) T
+#define BOOST_CONTAINER_DOCONLY(T)
+
+/*
+   we need to import/export our code only if the user has specifically
+   asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+   libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
+   if they want just this one to be dynamically liked:
+*/
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
+
+   /* export if this is our own source, otherwise import: */
+   #ifdef BOOST_CONTAINER_SOURCE
+   #  define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT
+   #else
+   #  define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT
+   
+   #endif  /* BOOST_CONTAINER_SOURCE */
+#else
+   #define BOOST_CONTAINER_DECL
+#endif  /* DYN_LINK */
+
+//#define BOOST_CONTAINER_DISABLE_FORCEINLINE
+
+#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE)
+   #define BOOST_CONTAINER_FORCEINLINE inline
+#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE)
+   #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
+#elif defined(BOOST_MSVC) && defined(_DEBUG)
+   //"__forceinline" and MSVC seems to have some bugs in debug mode
+   #define BOOST_CONTAINER_FORCEINLINE inline
+#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5)))
+   //Older GCCs have problems with forceinline
+   #define BOOST_CONTAINER_FORCEINLINE inline
+#else
+   #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
+#endif
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp
new file mode 100644
index 0000000..9679946
--- /dev/null
+++ b/include/boost/container/flat_map.hpp
@@ -0,0 +1,2890 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_FLAT_MAP_HPP
+#define BOOST_CONTAINER_FLAT_MAP_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/flat_tree.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/algorithm.hpp> //equal()
+#include <boost/container/detail/container_or_allocator_rebind.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+#include <boost/move/traits.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// intrusive
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+//others
+#include <boost/core/no_exceptions_support.hpp>
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class Key, class T, class Compare, class AllocatorOrContainer>
+class flat_multimap;
+
+namespace dtl{
+
+template<class D, class S>
+BOOST_CONTAINER_FORCEINLINE static D &force(S &s)
+{  return *reinterpret_cast<D*>(&s); }
+
+template<class D, class S>
+BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s)
+{
+   const D *const vp = reinterpret_cast<const D *>(&s);
+   D ret_val(*vp);
+   return ret_val;
+}
+
+}  //namespace dtl{
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A flat_map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys.
+//!
+//! A flat_map satisfies all of the requirements of a container, a reversible
+//! container and an associative container. A flat_map also provides
+//! most operations described for unique keys. For a
+//! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! flat_map is similar to std::map but it's implemented by as an ordered sequence container.
+//! The underlying sequence container is by default <i>vector</i> but it can also work
+//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
+//!
+//! Using vector-like sequence containers means that inserting a new element into a flat_map might invalidate
+//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
+//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
+//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
+//!
+//! This container provides random-access iterators.
+//!
+//! \tparam Key is the key_type of the map
+//! \tparam Value is the <code>mapped_type</code>
+//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//! \tparam AllocatorOrContainer is either:
+//!   - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
+//!     (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
+//!   - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
+//!     sequence container with random-access iterators..
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
+#else
+template <class Key, class T, class Compare, class AllocatorOrContainer>
+#endif
+class flat_map
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_map)
+   //This is the tree that we should store if pair was movable
+   typedef dtl::flat_tree<
+                           std::pair<Key, T>,
+                           dtl::select1st<Key>,
+                           Compare,
+                           AllocatorOrContainer> tree_t;
+
+   //This is the real tree stored here. It's based on a movable pair
+   typedef dtl::flat_tree<
+                           dtl::pair<Key, T>,
+                           dtl::select1st<Key>,
+                           Compare,
+                           typename dtl::container_or_allocator_rebind<AllocatorOrContainer, dtl::pair<Key, T> >::type
+                           > impl_tree_t;
+   impl_tree_t m_flat_tree;  // flat tree representing flat_map
+
+   typedef typename impl_tree_t::value_type              impl_value_type;
+   typedef typename impl_tree_t::const_iterator          impl_const_iterator;
+   typedef typename impl_tree_t::iterator                impl_iterator;
+   typedef typename impl_tree_t::allocator_type          impl_allocator_type;
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   typedef std::initializer_list<impl_value_type>        impl_initializer_list;
+   #endif
+
+   typedef dtl::flat_tree_value_compare
+      < Compare
+      , dtl::select1st<Key>
+      , std::pair<Key, T> >                              value_compare_t;
+   typedef typename tree_t::iterator                     iterator_t;
+   typedef typename tree_t::const_iterator               const_iterator_t;
+   typedef typename tree_t::reverse_iterator             reverse_iterator_t;
+   typedef typename tree_t::const_reverse_iterator       const_reverse_iterator_t;
+
+   public:
+   typedef typename impl_tree_t::stored_allocator_type   impl_stored_allocator_type;
+   typedef typename impl_tree_t::sequence_type           impl_sequence_type;
+
+   BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
+   {  return m_flat_tree;  }
+
+   BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
+   {  return m_flat_tree;  }
+
+   private:
+   typedef typename tree_t::get_stored_allocator_const_return_t         get_stored_allocator_const_return_t;
+   typedef typename tree_t::get_stored_allocator_noconst_return_t       get_stored_allocator_noconst_return_t;
+   typedef typename impl_tree_t::get_stored_allocator_const_return_t    impl_get_stored_allocator_const_return_t;
+   typedef typename impl_tree_t::get_stored_allocator_noconst_return_t  impl_get_stored_allocator_noconst_return_t;
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                      key_type;
+   typedef T                                                                        mapped_type;
+   typedef Compare                                                                  key_compare;
+   typedef std::pair<Key, T>                                                        value_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type)                   sequence_type;
+   typedef typename sequence_type::allocator_type                                   allocator_type;
+   typedef ::boost::container::allocator_traits<allocator_type>                     allocator_traits_type;
+   typedef typename sequence_type::pointer                                          pointer;
+   typedef typename sequence_type::const_pointer                                    const_pointer;
+   typedef typename sequence_type::reference                                        reference;
+   typedef typename sequence_type::const_reference                                  const_reference;
+   typedef typename sequence_type::size_type                                        size_type;
+   typedef typename sequence_type::difference_type                                  difference_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare)                   value_compare;
+
+   typedef typename sequence_type::iterator                                         iterator;
+   typedef typename sequence_type::const_iterator                                   const_iterator;
+   typedef typename sequence_type::reverse_iterator                                 reverse_iterator;
+   typedef typename sequence_type::const_reverse_iterator                           const_reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(impl_value_type)                                  movable_value_type;
+
+   //AllocatorOrContainer::value_type must be std::pair<Key, T>
+   BOOST_STATIC_ASSERT((dtl::is_same<std::pair<Key, T>, typename allocator_type::value_type>::value));
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty flat_map.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
+                                                            dtl::is_nothrow_default_constructible<Compare>::value)
+      : m_flat_tree()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a)
+      : m_flat_tree(dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified
+   //! comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit flat_map(const Compare& comp)
+      : m_flat_tree(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified
+   //! comparison object and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE flat_map(const Compare& comp, const allocator_type& a)
+      : m_flat_tree(comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map and
+   //! and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last)
+      : m_flat_tree(true, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const allocator_type& a)
+      : m_flat_tree(true, first, last, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp)
+      : m_flat_tree(true, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_flat_tree(true, first, last, comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map
+   //! and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_map(ordered_unique_range_t, InputIterator first, InputIterator last)
+      : m_flat_tree(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : m_flat_tree(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_flat_tree(ordered_range, first, last, comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty flat_map and
+   //! inserts elements from the range [il.begin() ,il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il)
+     : m_flat_tree( true
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified
+   //! allocator, and inserts elements from the range [il.begin() ,il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const allocator_type& a)
+     : m_flat_tree( true
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end()
+                  , dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! inserts elements from the range [il.begin() ,il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp)
+     : m_flat_tree(true
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end()
+                  , comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin() ,il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+     : m_flat_tree(true
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end()
+                  , comp
+                  , dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il)
+     : m_flat_tree(ordered_unique_range
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+     : m_flat_tree(ordered_unique_range
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end()
+                  , comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+     : m_flat_tree( ordered_unique_range
+                  , dtl::force<impl_initializer_list>(il).begin()
+                  , dtl::force<impl_initializer_list>(il).end()
+                  , comp
+                  , dtl::force<const impl_allocator_type>(a))
+   {}
+#endif
+
+   //! <b>Effects</b>: Copy constructs a flat_map.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x)
+      : m_flat_tree(x.m_flat_tree)
+   {}
+
+   //! <b>Effects</b>: Move constructs a flat_map.
+   //!   Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : m_flat_tree(boost::move(x.m_flat_tree))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a)
+      : m_flat_tree(x.m_flat_tree, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
+   //!   Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
+      : m_flat_tree(boost::move(x.m_flat_tree), dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+   {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! <b>Effects</b>: Move constructs a flat_map.
+   //!   Constructs *this using x's resources.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_RV_REF(flat_map) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  m_flat_tree = boost::move(x.m_flat_tree);   return *this;  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assign elements from il to *this
+   flat_map& operator=(std::initializer_list<value_type> il)
+   {
+      this->clear();
+      this->insert(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Returns a copy of the allocator that
+   //!   was passed to the object's constructor.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE get_stored_allocator_noconst_return_t get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      impl_get_stored_allocator_noconst_return_t r = m_flat_tree.get_stored_allocator();
+      return dtl::force<stored_allocator_type>(r);
+   }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE get_stored_allocator_const_return_t get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      impl_get_stored_allocator_const_return_t r = m_flat_tree.get_stored_allocator();
+      return dtl::force<const stored_allocator_type>(r);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<iterator>(m_flat_tree.begin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.begin()); }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<iterator>(m_flat_tree.end()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.end()); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<reverse_iterator>(m_flat_tree.rend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.cbegin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.cend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the container contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.empty(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.size(); }
+
+   //! <b>Effects</b>: Returns the largest possible size of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.max_size(); }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.capacity(); }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), or the
+   //!   underlying container has no `reserve` member, this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
+   //!   to values might be invalidated.
+   BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
+      { m_flat_tree.reserve(cnt);   }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: If there is no key equivalent to x in the flat_map, inserts
+   //!   value_type(x, T()) into the flat_map.
+   //!
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //!
+   //! Complexity: Logarithmic.
+   mapped_type &operator[](const key_type& k);
+
+   //! Effects: If there is no key equivalent to x in the flat_map, inserts
+   //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
+   //!
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //!
+   //! Complexity: Logarithmic.
+   mapped_type &operator[](key_type &&k) ;
+   #elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
+      //in compilers like GCC 3.4, we can't catch temporaries
+      BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k)         {  return this->priv_subscript(k);  }
+      BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](BOOST_RV_REF(key_type) k)  {  return this->priv_subscript(::boost::move(k));  }
+   #else
+      BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
+   #endif
+
+   //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, forward<M>(obj)).
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! Returns: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! Complexity: Logarithmic in the size of the container.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >
+         (this->m_flat_tree.insert_or_assign
+            ( impl_const_iterator(), k, ::boost::forward<M>(obj))
+         );
+   }
+
+   //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, move(obj)).
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! Returns: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! Complexity: Logarithmic in the size of the container.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >
+         (this->m_flat_tree.insert_or_assign
+            ( impl_const_iterator(), ::boost::move(k), ::boost::forward<M>(obj))
+         );
+   }
+
+   //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
+   //! to the container as close as possible to the position just before hint.
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! Returns: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! Complexity: Logarithmic in the size of the container in general, but amortized constant if
+   //! the new element is inserted just before hint.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >
+         (this->m_flat_tree.insert_or_assign
+            ( dtl::force_copy<impl_const_iterator>(hint)
+            , k, ::boost::forward<M>(obj))
+         );
+   }
+
+   //! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, move(obj)) and the new element
+   //! to the container as close as possible to the position just before hint.
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! Returns: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! Complexity: Logarithmic in the size of the container in general, but amortized constant if
+   //! the new element is inserted just before hint.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >
+         (this->m_flat_tree.insert_or_assign
+            ( dtl::force_copy<impl_const_iterator>(hint)
+            , ::boost::move(k), ::boost::forward<M>(obj))
+         );
+   }
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type)
+   BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dtl::force_copy<iterator>(m_flat_tree.nth(n));  }
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type) const
+   BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dtl::force_copy<iterator>(m_flat_tree.nth(n));  }
+
+   //! @copydoc ::boost::container::flat_set::index_of(iterator)
+   BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return m_flat_tree.index_of(dtl::force_copy<impl_iterator>(p));  }
+
+   //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+   BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return m_flat_tree.index_of(dtl::force_copy<impl_const_iterator>(p));  }
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //!
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //!
+   //! Complexity: logarithmic.
+   T& at(const key_type& k)
+   {
+      iterator i = this->find(k);
+      if(i == this->end()){
+         throw_out_of_range("flat_map::at key not found");
+      }
+      return i->second;
+   }
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //!
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //!
+   //! Complexity: logarithmic.
+   const T& at(const key_type& k) const
+   {
+      const_iterator i = this->find(k);
+      if(i == this->end()){
+         throw_out_of_range("flat_map::at key not found");
+      }
+      return i->second;
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object x of type T constructed with
+   //!   std::forward<Args>(args)... if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+   {  return dtl::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.emplace_hint_unique( dtl::force_copy<impl_const_iterator>(hint)
+                                         , boost::forward<Args>(args)...));
+   }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
+   //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >(
+         m_flat_tree.try_emplace(impl_const_iterator(), k, boost::forward<Args>(args)...));
+   }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy<iterator>(m_flat_tree.try_emplace
+         (dtl::force_copy<impl_const_iterator>(hint), k, boost::forward<Args>(args)...).first);
+   }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
+   //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy< std::pair<iterator, bool> >
+         (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k), boost::forward<Args>(args)...));
+   }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.try_emplace(dtl::force_copy
+            <impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+   {\
+      return dtl::force_copy< std::pair<iterator, bool> >\
+         (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
+         (dtl::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+   }\
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      return dtl::force_copy< std::pair<iterator, bool> >\
+         (m_flat_tree.try_emplace(impl_const_iterator(), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
+         (dtl::force_copy<impl_const_iterator>(hint), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      return dtl::force_copy< std::pair<iterator, bool> >\
+         (m_flat_tree.try_emplace(impl_const_iterator(), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
+      (dtl::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
+   {  return dtl::force_copy<std::pair<iterator,bool> >(
+         m_flat_tree.insert_unique(dtl::force<const impl_value_type>(x))); }
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+   {  return dtl::force_copy<std::pair<iterator,bool> >(
+      m_flat_tree.insert_unique(boost::move(dtl::force<impl_value_type>(x)))); }
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
+   {
+      return dtl::force_copy<std::pair<iterator,bool> >
+      (m_flat_tree.insert_unique(boost::move(x)));
+   }
+
+   //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.insert_unique( dtl::force_copy<impl_const_iterator>(p)
+                                  , dtl::force<const impl_value_type>(x)));
+   }
+
+   //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.insert_unique( dtl::force_copy<impl_const_iterator>(p)
+                                   , boost::move(dtl::force<impl_value_type>(x))));
+   }
+
+   //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.insert_unique(dtl::force_copy<impl_const_iterator>(p), boost::move(x)));
+   }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: N log(size()+N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+   {  m_flat_tree.insert_unique(first, last);  }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element. This
+   //!   function is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
+      {  m_flat_tree.insert_unique(ordered_unique_range, first, last); }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {
+      m_flat_tree.insert_unique( dtl::force<impl_initializer_list>(il).begin()
+                               , dtl::force<impl_initializer_list>(il).end());
+   }
+
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element. This
+   //!   function is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
+   {
+      m_flat_tree.insert_unique(ordered_unique_range
+                               , dtl::force<impl_initializer_list>(il).begin()
+                               , dtl::force<impl_initializer_list>(il).end());
+   }
+#endif
+
+   //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
+   //!
+   //! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
+   //!   the comparison object of *this. If there is an element in a with key equivalent to the
+   //!   key of an element from source, then that element is not extracted from source.
+   //! 
+   //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
+   //!   to those same elements but as members of *this. Iterators referring to the transferred
+   //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
+   //!   not into source.
+   //!
+   //! <b>Throws</b>: Nothing unless the comparison object throws.
+   //!
+   //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
+   {  m_flat_tree.merge_unique(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
+
+   //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
+   {  m_flat_tree.merge_unique(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source));  }
+
+   //! <b>Effects</b>: Erases the element pointed to by p.
+   //!
+   //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists,
+   //!   returns end().
+   //!
+   //! <b>Complexity</b>: Linear to the elements with keys bigger than p
+   //!
+   //! <b>Note</b>: Invalidates elements with keys
+   //!   not less than the erased element.
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.erase(dtl::force_copy<impl_const_iterator>(p)));
+   }
+
+   //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+   //!
+   //! <b>Returns</b>: Returns the number of erased elements.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
+      { return m_flat_tree.erase(x); }
+
+   //! <b>Effects</b>: Erases all the elements in the range [first, last).
+   //!
+   //! <b>Returns</b>: Returns last.
+   //!
+   //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.erase( dtl::force_copy<impl_const_iterator>(first)
+                          , dtl::force_copy<impl_const_iterator>(last)));
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE void swap(flat_map& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! <b>Effects</b>: erase(a.begin(),a.end()).
+   //!
+   //! <b>Postcondition</b>: size() == 0.
+   //!
+   //! <b>Complexity</b>: linear in size().
+   BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
+      { m_flat_tree.clear(); }
+
+   //////////////////////////////////////////////
+   //
+   //                observers
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns the comparison object out
+   //!   of which a was constructed.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
+      { return dtl::force_copy<key_compare>(m_flat_tree.key_comp()); }
+
+   //! <b>Effects</b>: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
+      { return value_compare(dtl::force_copy<key_compare>(m_flat_tree.key_comp())); }
+
+   //////////////////////////////////////////////
+   //
+   //              map operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
+      { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
+      { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator find(const K& x)
+      { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator find(const K& x) const
+      { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
+      {  return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end());  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
+      {  return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end());  }
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const K& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const K& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const K& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const K& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
+      {  return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+      {  return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x)
+      {  return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const K& x) const
+      {  return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
+
+   //! <b>Effects</b>: Extracts the internal sequence container.
+   //!
+   //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   //!
+   //! <b>Throws</b>: If secuence_type's move constructor throws 
+   BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
+   {
+      return boost::move(dtl::force<sequence_type>(m_flat_tree.get_sequence_ref()));
+   }
+
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment. Erases non-unique elements.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+   //!
+   //! <b>Throws</b>: If the comparison or the move constructor throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+   {  this->m_flat_tree.adopt_sequence_unique(boost::move(dtl::force<impl_sequence_type>(seq)));  }
+
+   //! <b>Requires</b>: seq shall be ordered according to this->compare()
+   //!   and shall contain unique elements.
+   //!
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+   //!
+   //! <b>Throws</b>: If the move assignment throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
+   {  this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(dtl::force<impl_sequence_type>(seq)));  }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_map& x, const flat_map& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_map& x, const flat_map& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_map& x, const flat_map& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_map& x, const flat_map& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_map& x, const flat_map& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_map& x, const flat_map& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE friend void swap(flat_map& x, flat_map& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   mapped_type &priv_subscript(const key_type& k)
+   {
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         dtl::value_init<mapped_type> m;
+         i = insert(i, impl_value_type(k, ::boost::move(m.m_t)));
+      }
+      return (*i).second;
+   }
+   mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk)
+   {
+      key_type &k = mk;
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         dtl::value_init<mapped_type> m;
+         i = insert(i, impl_value_type(boost::move(k), ::boost::move(m.m_t)));
+      }
+      return (*i).second;
+   }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+flat_map(InputIterator, InputIterator) ->
+   flat_map< typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_map(InputIterator, InputIterator, Allocator const&) ->
+   flat_map< typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_map(InputIterator, InputIterator, Compare const&) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+template <typename InputIterator>
+flat_map(ordered_unique_range_t, InputIterator, InputIterator) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class T, class Compare, class AllocatorOrContainer>
+struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer> >
+{
+   typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A flat_multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. 
+//!
+//! A flat_multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! flat_multimap is similar to std::multimap but it's implemented by as an ordered sequence container.
+//! The underlying sequence container is by default <i>vector</i> but it can also work
+//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
+//!
+//! Using vector-like sequence containers means that inserting a new element into a flat_multimap might invalidate
+//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
+//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
+//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
+//!
+//! This container provides random-access iterators.
+//!
+//! \tparam Key is the key_type of the map
+//! \tparam Value is the <code>mapped_type</code>
+//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//! \tparam AllocatorOrContainer is either:
+//!   - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
+//!     (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
+//!   - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
+//!     sequence container with random-access iterators.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
+#else
+template <class Key, class T, class Compare, class AllocatorOrContainer>
+#endif
+class flat_multimap
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
+   typedef dtl::flat_tree<
+                           std::pair<Key, T>,
+                           dtl::select1st<Key>,
+                           Compare,
+                           AllocatorOrContainer> tree_t;
+   //This is the real tree stored here. It's based on a movable pair
+   typedef dtl::flat_tree<
+                           dtl::pair<Key, T>,
+                           dtl::select1st<Key>,
+                           Compare,
+                           typename dtl::container_or_allocator_rebind<AllocatorOrContainer, dtl::pair<Key, T> >::type
+                           > impl_tree_t;
+   impl_tree_t m_flat_tree;  // flat tree representing flat_map
+
+   typedef typename impl_tree_t::value_type              impl_value_type;
+   typedef typename impl_tree_t::const_iterator          impl_const_iterator;
+   typedef typename impl_tree_t::iterator                impl_iterator;
+   typedef typename impl_tree_t::allocator_type          impl_allocator_type;
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   typedef std::initializer_list<impl_value_type>        impl_initializer_list;
+   #endif
+
+   typedef dtl::flat_tree_value_compare
+      < Compare
+      , dtl::select1st<Key>
+      , std::pair<Key, T> >                                 value_compare_t;
+   typedef typename tree_t::iterator                        iterator_t;
+   typedef typename tree_t::const_iterator                  const_iterator_t;
+   typedef typename tree_t::reverse_iterator                reverse_iterator_t;
+   typedef typename tree_t::const_reverse_iterator          const_reverse_iterator_t;
+
+   public:
+   typedef typename impl_tree_t::stored_allocator_type      impl_stored_allocator_type;
+   typedef typename impl_tree_t::sequence_type              impl_sequence_type;
+
+   BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
+   {  return m_flat_tree;  }
+
+   BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
+   {  return m_flat_tree;  }
+
+   private:
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                      key_type;
+   typedef T                                                                        mapped_type;
+   typedef Compare                                                                  key_compare;
+   typedef std::pair<Key, T>                                                        value_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type)                   sequence_type;
+   typedef typename sequence_type::allocator_type                                   allocator_type;
+   typedef ::boost::container::allocator_traits<allocator_type>                     allocator_traits_type;
+   typedef typename sequence_type::pointer                                          pointer;
+   typedef typename sequence_type::const_pointer                                    const_pointer;
+   typedef typename sequence_type::reference                                        reference;
+   typedef typename sequence_type::const_reference                                  const_reference;
+   typedef typename sequence_type::size_type                                        size_type;
+   typedef typename sequence_type::difference_type                                  difference_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare)                   value_compare;
+
+   typedef typename sequence_type::iterator                                         iterator;
+   typedef typename sequence_type::const_iterator                                   const_iterator;
+   typedef typename sequence_type::reverse_iterator                                 reverse_iterator;
+   typedef typename sequence_type::const_reverse_iterator                           const_reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(impl_value_type)                                  movable_value_type;
+
+   //AllocatorOrContainer::value_type must be std::pair<Key, T>
+   BOOST_STATIC_ASSERT((dtl::is_same<std::pair<Key, T>, typename AllocatorOrContainer::value_type>::value));
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty flat_map.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE flat_multimap()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
+                        dtl::is_nothrow_default_constructible<Compare>::value)
+      : m_flat_tree()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const allocator_type& a)
+      : m_flat_tree(dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
+   //!   object .
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const Compare& comp)
+      : m_flat_tree(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
+   //!   object and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(const Compare& comp, const allocator_type& a)
+      : m_flat_tree(comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap
+   //!   and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(InputIterator first, InputIterator last)
+      : m_flat_tree(false, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified
+   //!   allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
+      : m_flat_tree(false, first, last, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+   //!   and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(InputIterator first, InputIterator last, const Compare& comp)
+      : m_flat_tree(false, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+   //!   and allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_flat_tree(false, first, last, comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap
+   //! and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, InputIterator first, InputIterator last)
+      : m_flat_tree(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+   //! inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : m_flat_tree(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : m_flat_tree(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty flat_map and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(std::initializer_list<value_type> il)
+      : m_flat_tree( false
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
+      : m_flat_tree(false
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end()
+                   , dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(std::initializer_list<value_type> il, const Compare& comp)
+      : m_flat_tree(false
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : m_flat_tree( false
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end()
+                   , comp, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap and
+   //! inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, std::initializer_list<value_type> il)
+      : m_flat_tree( ordered_range
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+   //! inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : m_flat_tree( ordered_range
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : m_flat_tree( ordered_range
+                   , dtl::force<impl_initializer_list>(il).begin()
+                   , dtl::force<impl_initializer_list>(il).end()
+                   , comp, dtl::force<const impl_allocator_type>(a))
+   {}
+#endif
+
+   //! <b>Effects</b>: Copy constructs a flat_multimap.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(const flat_multimap& x)
+      : m_flat_tree(x.m_flat_tree)
+   {}
+
+   //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(BOOST_RV_REF(flat_multimap) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : m_flat_tree(boost::move(x.m_flat_tree))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(const flat_multimap& x, const allocator_type &a)
+      : m_flat_tree(x.m_flat_tree, dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
+      : m_flat_tree(boost::move(x.m_flat_tree), dtl::force<const impl_allocator_type>(a))
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
+      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! <b>Effects</b>: this->swap(x.get()).
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+      {  m_flat_tree = boost::move(x.m_flat_tree);   return *this;  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assign content of il to *this
+   //!
+   //! <b>Complexity</b>: Linear in il.size().
+   BOOST_CONTAINER_FORCEINLINE
+   flat_multimap& operator=(std::initializer_list<value_type> il)
+   {
+      this->clear();
+      this->insert(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Returns a copy of the allocator that
+   //!   was passed to the object's constructor.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force<const stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<iterator>(m_flat_tree.begin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.begin()); }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<iterator>(m_flat_tree.end()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.end()); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<reverse_iterator>(m_flat_tree.rend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.cbegin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_iterator>(m_flat_tree.cend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return dtl::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the container contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.empty(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.size(); }
+
+   //! <b>Effects</b>: Returns the largest possible size of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.max_size(); }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_flat_tree.capacity(); }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), or the
+   //!   underlying container has no `reserve` member, this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
+   //!   to values might be invalidated.
+   BOOST_CONTAINER_FORCEINLINE
+   void reserve(size_type cnt)
+      { m_flat_tree.reserve(cnt);   }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   BOOST_CONTAINER_FORCEINLINE
+   void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type)
+   BOOST_CONTAINER_FORCEINLINE
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dtl::force_copy<iterator>(m_flat_tree.nth(n));  }
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type) const
+   BOOST_CONTAINER_FORCEINLINE
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return dtl::force_copy<iterator>(m_flat_tree.nth(n));  }
+
+   //! @copydoc ::boost::container::flat_set::index_of(iterator)
+   BOOST_CONTAINER_FORCEINLINE
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return m_flat_tree.index_of(dtl::force_copy<impl_iterator>(p));  }
+
+   //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+   BOOST_CONTAINER_FORCEINLINE
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return m_flat_tree.index_of(dtl::force_copy<impl_const_iterator>(p));  }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE
+   iterator emplace(BOOST_FWD_REF(Args)... args)
+   {  return dtl::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE
+   iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
+   {
+      return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_equal
+         (dtl::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
+   {  return dtl::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N));  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      return dtl::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
+         (dtl::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.insert_equal(dtl::force<const impl_value_type>(x)));
+   }
+
+   //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+   //!   the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(value_type) x)
+   { return dtl::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
+
+   //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+   //!   the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(impl_value_type) x)
+      { return dtl::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
+
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.insert_equal( dtl::force_copy<impl_const_iterator>(p)
+                                  , dtl::force<const impl_value_type>(x)));
+   }
+
+   //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.insert_equal(dtl::force_copy<impl_const_iterator>(p)
+                                  , boost::move(x)));
+   }
+
+   //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(impl_value_type) x)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.insert_equal(dtl::force_copy<impl_const_iterator>(p), boost::move(x)));
+   }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+      {  m_flat_tree.insert_equal(first, last); }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element. This
+   //!   function is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
+      {  m_flat_tree.insert_equal(ordered_range, first, last); }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) .
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {
+      m_flat_tree.insert_equal( dtl::force<impl_initializer_list>(il).begin()
+                              , dtl::force<impl_initializer_list>(il).end());
+   }
+
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element. This
+   //!   function is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
+   {
+      m_flat_tree.insert_equal( ordered_range
+                              , dtl::force<impl_initializer_list>(il).begin()
+                              , dtl::force<impl_initializer_list>(il).end());
+   }
+#endif
+
+   //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
+   //!
+   //! <b>Effects</b>: Extracts each element in source and insert it into a using
+   //!   the comparison object of *this.
+   //! 
+   //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
+   //!   to those same elements but as members of *this. Iterators referring to the transferred
+   //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
+   //!   not into source.
+   //!
+   //! <b>Throws</b>: Nothing unless the comparison object throws.
+   //!
+   //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
+   {  m_flat_tree.merge_equal(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
+
+   //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
+   {  m_flat_tree.merge_equal(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
+
+   //! <b>Effects</b>: Erases the element pointed to by p.
+   //!
+   //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists,
+   //!   returns end().
+   //!
+   //! <b>Complexity</b>: Linear to the elements with keys bigger than p
+   //!
+   //! <b>Note</b>: Invalidates elements with keys
+   //!   not less than the erased element.
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
+   {
+      return dtl::force_copy<iterator>(
+         m_flat_tree.erase(dtl::force_copy<impl_const_iterator>(p)));
+   }
+
+   //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+   //!
+   //! <b>Returns</b>: Returns the number of erased elements.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
+      { return m_flat_tree.erase(x); }
+
+   //! <b>Effects</b>: Erases all the elements in the range [first, last).
+   //!
+   //! <b>Returns</b>: Returns last.
+   //!
+   //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
+   {
+      return dtl::force_copy<iterator>
+         (m_flat_tree.erase( dtl::force_copy<impl_const_iterator>(first)
+                           , dtl::force_copy<impl_const_iterator>(last)));
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE void swap(flat_multimap& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! <b>Effects</b>: erase(a.begin(),a.end()).
+   //!
+   //! <b>Postcondition</b>: size() == 0.
+   //!
+   //! <b>Complexity</b>: linear in size().
+   BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
+      { m_flat_tree.clear(); }
+
+   //////////////////////////////////////////////
+   //
+   //                observers
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns the comparison object out
+   //!   of which a was constructed.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
+      { return dtl::force_copy<key_compare>(m_flat_tree.key_comp()); }
+
+   //! <b>Effects</b>: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
+      { return value_compare(dtl::force_copy<key_compare>(m_flat_tree.key_comp())); }
+
+   //////////////////////////////////////////////
+   //
+   //              map operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
+      { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Returns</b>: An const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
+      { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator find(const K& x)
+      { return dtl::force_copy<iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator find(const K& x) const
+      { return dtl::force_copy<const_iterator>(m_flat_tree.find(x)); }
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
+      { return m_flat_tree.count(x); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
+      { return m_flat_tree.count(x); }
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const K& x)
+      {  return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const K& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
+      {return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key
+   //!   not less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const K& x)
+      {return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key
+   //!   not less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const K& x) const
+      {  return dtl::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
+      {  return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x));   }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+      {  return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x));   }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x)
+      {  return dtl::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x));   }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<class K>
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const K& x) const
+      {  return dtl::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x));   }
+
+   //! <b>Effects</b>: Extracts the internal sequence container.
+   //!
+   //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   //!
+   //! <b>Throws</b>: If secuence_type's move constructor throws 
+   BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
+   {
+      return boost::move(dtl::force<sequence_type>(m_flat_tree.get_sequence_ref()));
+   }
+
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+   //!
+   //! <b>Throws</b>: If the comparison or the move constructor throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+   {  this->m_flat_tree.adopt_sequence_equal(boost::move(dtl::force<impl_sequence_type>(seq)));  }
+
+   //! <b>Requires</b>: seq shall be ordered according to this->compare().
+   //!
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+   //!
+   //! <b>Throws</b>: If the move assignment throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
+   {  this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(dtl::force<impl_sequence_type>(seq)));  }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_multimap& x, const flat_multimap& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_multimap& x, const flat_multimap& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_multimap& x, const flat_multimap& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE friend void swap(flat_multimap& x, flat_multimap& y)
+   {  x.swap(y);  }
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+flat_multimap(InputIterator, InputIterator) ->
+   flat_multimap<typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+                        , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_multimap(InputIterator, InputIterator, Allocator const&) ->
+   flat_multimap<typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+                        , typename iterator_traits<InputIterator>::value_type::second_type
+                        , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+                        , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_multimap(InputIterator, InputIterator, Compare const&) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+template <typename InputIterator>
+flat_multimap(ordered_range_t, InputIterator, InputIterator) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+#endif
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class T, class Compare, class AllocatorOrContainer>
+struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, AllocatorOrContainer> >
+{
+   typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   // BOOST_CONTAINER_FLAT_MAP_HPP
diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp
new file mode 100644
index 0000000..cfea7c8
--- /dev/null
+++ b/include/boost/container/flat_set.hpp
@@ -0,0 +1,1847 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_FLAT_SET_HPP
+#define BOOST_CONTAINER_FLAT_SET_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// container/detail
+#include <boost/container/detail/flat_tree.hpp>
+#include <boost/container/detail/mpl.hpp>
+// move
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+template <class Key, class Compare, class AllocatorOrContainer>
+class flat_multiset;
+#endif
+
+//! flat_set is a Sorted Associative Container that stores objects of type Key.
+//! It is also a Unique Associative Container, meaning that no two elements are the same.
+//!
+//! flat_set is similar to std::set but it's implemented by as an ordered sequence container.
+//! The underlying sequence container is by default <i>vector</i> but it can also work
+//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
+//!
+//! Using vector-like sequence containers means that inserting a new element into a flat_set might invalidate
+//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
+//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
+//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
+//!
+//! This container provides random-access iterators.
+//!
+//! \tparam Key is the type to be inserted in the set, which is also the key_type
+//! \tparam Compare is the comparison functor used to order keys
+//! \tparam AllocatorOrContainer is either:
+//!   - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
+//!     (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
+//!   - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
+//!     sequence container with random-access iterators.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator<Key> >
+#else
+template <class Key, class Compare, class AllocatorOrContainer>
+#endif
+class flat_set
+   ///@cond
+   : public dtl::flat_tree<Key, dtl::identity<Key>, Compare, AllocatorOrContainer>
+   ///@endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_set)
+   typedef dtl::flat_tree<Key, dtl::identity<Key>, Compare, AllocatorOrContainer> tree_t;
+
+   public:
+   tree_t &tree()
+   {  return *this;  }
+
+   const tree_t &tree() const
+   {  return *this;  }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                      key_type;
+   typedef Compare                                                                  key_compare;
+   typedef Key                                                                      value_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type)                   sequence_type;
+   typedef typename sequence_type::allocator_type                                   allocator_type;
+   typedef ::boost::container::allocator_traits<allocator_type>                     allocator_traits_type;
+   typedef typename sequence_type::pointer                                          pointer;
+   typedef typename sequence_type::const_pointer                                    const_pointer;
+   typedef typename sequence_type::reference                                        reference;
+   typedef typename sequence_type::const_reference                                  const_reference;
+   typedef typename sequence_type::size_type                                        size_type;
+   typedef typename sequence_type::difference_type                                  difference_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare)                   value_compare;
+
+   typedef typename sequence_type::iterator                                         iterator;
+   typedef typename sequence_type::const_iterator                                   const_iterator;
+   typedef typename sequence_type::reverse_iterator                                 reverse_iterator;
+   typedef typename sequence_type::const_reverse_iterator                           const_reverse_iterator;
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty container.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
+                                dtl::is_nothrow_default_constructible<Compare>::value)
+      : tree_t()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified
+   //! comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   explicit flat_set(const Compare& comp)
+      : tree_t(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   explicit flat_set(const allocator_type& a)
+      : tree_t(a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified
+   //! comparison object and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(const Compare& comp, const allocator_type& a)
+      : tree_t(comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! comp and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(InputIterator first, InputIterator last)
+      : tree_t(true, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! comp and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(InputIterator first, InputIterator last, const allocator_type& a)
+      : tree_t(true, first, last, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! comp and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(InputIterator first, InputIterator last, const Compare& comp)
+      : tree_t(true, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! comp and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : tree_t(true, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(ordered_unique_range_t, InputIterator first, InputIterator last)
+      : tree_t(ordered_unique_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : tree_t(ordered_unique_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE
+   flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : tree_t(ordered_unique_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty container and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! comp and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il)
+      : tree_t(true, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! comp and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const allocator_type& a)
+      : tree_t(true, il.begin(), il.end(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! comp and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp)
+      : tree_t(true, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! comp and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : tree_t(true, il.begin(), il.end(), comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il)
+      : tree_t(ordered_unique_range, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : tree_t(ordered_unique_range, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : tree_t(ordered_unique_range, il.begin(), il.end(), comp, a)
+   {}
+#endif
+
+   //! <b>Effects</b>: Copy constructs the container.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x)
+      : tree_t(static_cast<const tree_t&>(x))
+   {}
+
+   //! <b>Effects</b>: Move constructs thecontainer. Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : tree_t(BOOST_MOVE_BASE(tree_t, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a container using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x, const allocator_type &a)
+      : tree_t(static_cast<const tree_t&>(x), a)
+   {}
+
+   //! <b>Effects</b>: Move constructs a container using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
+   BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a)
+      : tree_t(BOOST_MOVE_BASE(tree_t, x), a)
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+   {  return static_cast<flat_set&>(this->tree_t::operator=(static_cast<const tree_t&>(x)));  }
+
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_RV_REF(flat_set) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<flat_set&>(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Copy all elements from il to *this.
+   //!
+   //! <b>Complexity</b>: Linear in il.size().
+   flat_set& operator=(std::initializer_list<value_type> il)
+   {
+       this->clear();
+       this->insert(il.begin(), il.end());
+       return *this;
+   }
+#endif
+
+   #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+   //! <b>Effects</b>: Returns a copy of the allocator that
+   //!   was passed to the object's constructor.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns an iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns true if the container contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the largest possible size of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), or the
+   //!   underlying container has no `reserve` member, this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
+   //!   to values might be invalidated.
+   void reserve(size_type cnt);
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or Key's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   void shrink_to_fit();
+
+   #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object x of type Key constructed with
+   //!   std::forward<Args>(args)... if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->tree_t::emplace_unique(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)... in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->tree_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+   {  return this->tree_t::emplace_unique(BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->tree_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   std::pair<iterator, bool> insert(const value_type &x);
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   std::pair<iterator, bool> insert(value_type &&x);
+   #else
+   private:
+   typedef std::pair<iterator, bool> insert_return_pair;
+   public:
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, const value_type &x);
+
+   //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+      {  this->tree_t::insert_unique(first, last);  }
+
+   //! <b>Requires</b>: first, last are not iterators into *this and
+   //! must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
+      {  this->tree_t::insert_unique(ordered_unique_range, first, last);  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->tree_t::insert_unique(il.begin(), il.end()); }
+
+   //! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate
+   //! and must be unique values.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) .This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
+   {  this->tree_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
+#endif
+
+   //! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, AllocatorOrContainer>& source)
+   {  this->tree_t::merge_unique(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_set::merge(flat_set<Key, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_set<Key, C2, AllocatorOrContainer>&>(source));   }
+
+   //! @copydoc ::boost::container::flat_map::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, AllocatorOrContainer>& source)
+   {  this->tree_t::merge_unique(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_set::merge(flat_multiset<Key, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_multiset<Key, C2, AllocatorOrContainer>&>(source));   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Erases the element pointed to by p.
+   //!
+   //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists,
+   //!   returns end().
+   //!
+   //! <b>Complexity</b>: Linear to the elements with keys bigger than p
+   //!
+   //! <b>Note</b>: Invalidates elements with keys
+   //!   not less than the erased element.
+   iterator erase(const_iterator p);
+
+   //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+   //!
+   //! <b>Returns</b>: Returns the number of erased elements.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   size_type erase(const key_type& x);
+
+   //! <b>Effects</b>: Erases all the elements in the range [first, last).
+   //!
+   //! <b>Returns</b>: Returns last.
+   //!
+   //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   iterator erase(const_iterator first, const_iterator last);
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(flat_set& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
+
+   //! <b>Effects</b>: erase(a.begin(),a.end()).
+   //!
+   //! <b>Postcondition</b>: size() == 0.
+   //!
+   //! <b>Complexity</b>: linear in size().
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the comparison object out
+   //!   of which a was constructed.
+   //!
+   //! <b>Complexity</b>: Constant.
+   key_compare key_comp() const;
+
+   //! <b>Effects</b>: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   value_compare value_comp() const;
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator find(const key_type& x);
+
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   const_iterator find(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   iterator find(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   const_iterator find(const K& x) const;
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns an iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns a const_iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
+   {  return static_cast<size_type>(this->tree_t::find(x) != this->tree_t::cend());  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<typename K>
+   BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
+   {  return static_cast<size_type>(this->tree_t::find(x) != this->tree_t::cend());  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator lower_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator lower_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator lower_bound(const K& x) const;
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator upper_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator upper_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator upper_bound(const K& x) const;
+
+   #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+   {  return this->tree_t::lower_bound_range(x);  }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
+   {  return this->tree_t::lower_bound_range(x);  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<iterator,iterator> equal_range(const K& x)
+   {  return this->tree_t::lower_bound_range(x);  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<const_iterator,const_iterator> equal_range(const K& x) const
+   {  return this->tree_t::lower_bound_range(x);  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const flat_set& x, const flat_set& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(flat_set& x, flat_set& y);
+
+   //! <b>Effects</b>: Extracts the internal sequence container.
+   //!
+   //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   //!
+   //! <b>Throws</b>: If secuence_type's move constructor throws 
+   sequence_type extract_sequence();
+
+   #endif   //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment. Erases non-unique elements.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+   //!
+   //! <b>Throws</b>: If the comparison or the move constructor throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+   {  this->tree_t::adopt_sequence_unique(boost::move(seq));  }
+
+   //! <b>Requires</b>: seq shall be ordered according to this->compare()
+   //!   and shall contain unique elements.
+   //!
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+   //!
+   //! <b>Throws</b>: If the move assignment throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
+   {  this->tree_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq));  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   template<class KeyType>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
+   {  return this->tree_t::insert_unique(::boost::forward<KeyType>(x));  }
+
+   template<class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+   {  return this->tree_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+flat_set(InputIterator, InputIterator) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_set(InputIterator, InputIterator, Allocator const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, std::less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_set(InputIterator, InputIterator, Compare const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_set(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+template <typename InputIterator>
+flat_set(ordered_unique_range_t, InputIterator, InputIterator) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, std::less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class Compare, class AllocatorOrContainer>
+struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, AllocatorOrContainer> >
+{
+   typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! flat_multiset is a Sorted Associative Container that stores objects of type Key and
+//! can store multiple copies of the same key value.
+//!
+//! flat_multiset is similar to std::multiset but it's implemented by as an ordered sequence container.
+//! The underlying sequence container is by default <i>vector</i> but it can also work
+//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
+//!
+//! Using vector-like sequence containers means that inserting a new element into a flat_multiset might invalidate
+//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
+//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
+//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
+//!
+//! This container provides random-access iterators.
+//!
+//! \tparam Key is the type to be inserted in the multiset, which is also the key_type
+//! \tparam Compare is the comparison functor used to order keys
+//! \tparam AllocatorOrContainer is either:
+//!   - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
+//!     (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
+//!   - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
+//!     sequence container with random-access iterators.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator<Key> >
+#else
+template <class Key, class Compare, class AllocatorOrContainer>
+#endif
+class flat_multiset
+   ///@cond
+   : public dtl::flat_tree<Key, dtl::identity<Key>, Compare, AllocatorOrContainer>
+   ///@endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
+   typedef dtl::flat_tree<Key, dtl::identity<Key>, Compare, AllocatorOrContainer> tree_t;
+
+   public:
+   tree_t &tree()
+   {  return *this;  }
+
+   const tree_t &tree() const
+   {  return *this;  }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                      key_type;
+   typedef Compare                                                                  key_compare;
+   typedef Key                                                                      value_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type)                   sequence_type;
+   typedef typename sequence_type::allocator_type                                   allocator_type;
+   typedef ::boost::container::allocator_traits<allocator_type>                     allocator_traits_type;
+   typedef typename sequence_type::pointer                                          pointer;
+   typedef typename sequence_type::const_pointer                                    const_pointer;
+   typedef typename sequence_type::reference                                        reference;
+   typedef typename sequence_type::const_reference                                  const_reference;
+   typedef typename sequence_type::size_type                                        size_type;
+   typedef typename sequence_type::difference_type                                  difference_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare)                   value_compare;
+
+   typedef typename sequence_type::iterator                                         iterator;
+   typedef typename sequence_type::const_iterator                                   const_iterator;
+   typedef typename sequence_type::reverse_iterator                                 reverse_iterator;
+   typedef typename sequence_type::const_reverse_iterator                           const_reverse_iterator;
+
+   //! @copydoc ::boost::container::flat_set::flat_set()
+   BOOST_CONTAINER_FORCEINLINE flat_multiset() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
+                                                                 dtl::is_nothrow_default_constructible<Compare>::value)
+      : tree_t()
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(const Compare&)
+   BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const Compare& comp)
+      : tree_t(comp)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const allocator_type& a)
+      : tree_t(a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(const Compare&, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(const Compare& comp, const allocator_type& a)
+      : tree_t(comp, a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last)
+      : tree_t(false, first, last)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const allocator_type& a)
+      : tree_t(false, first, last, a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp)
+      : tree_t(false, first, last, comp)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp, const allocator_type&)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : tree_t(false, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multiset and
+   //! inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last)
+      : tree_t(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
+   //! inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : tree_t(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [first, last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : tree_t(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il)
+      : tree_t(false, il.begin(), il.end())
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const allocator_type& a)
+      : tree_t(false, il.begin(), il.end(), a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp)
+      : tree_t(false, il.begin(), il.end(), comp)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : tree_t(false, il.begin(), il.end(), comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty containerand
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il)
+      : tree_t(ordered_range, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : tree_t(ordered_range, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : tree_t(ordered_range, il.begin(), il.end(), comp, a)
+   {}
+#endif
+
+   //! @copydoc ::boost::container::flat_set::flat_set(const flat_set &)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x)
+      : tree_t(static_cast<const tree_t&>(x))
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(flat_set &&)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : tree_t(boost::move(static_cast<tree_t&>(x)))
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(const flat_set &, const allocator_type &)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x, const allocator_type &a)
+      : tree_t(static_cast<const tree_t&>(x), a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::flat_set(flat_set &&, const allocator_type &)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
+      : tree_t(BOOST_MOVE_BASE(tree_t, x), a)
+   {}
+
+   //! @copydoc ::boost::container::flat_set::operator=(const flat_set &)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
+   {  return static_cast<flat_multiset&>(this->tree_t::operator=(static_cast<const tree_t&>(x)));  }
+
+   //! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
+   BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<flat_multiset&>(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! @copydoc ::boost::container::flat_set::operator=(std::initializer_list<value_type>)
+   flat_multiset& operator=(std::initializer_list<value_type> il)
+   {
+       this->clear();
+       this->insert(il.begin(), il.end());
+       return *this;
+   }
+#endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::flat_set::get_allocator()
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::get_stored_allocator()
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::get_stored_allocator() const
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::begin()
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::begin() const
+   const_iterator begin() const;
+
+   //! @copydoc ::boost::container::flat_set::cbegin() const
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::end()
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::end() const
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::cend() const
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::rbegin()
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::rbegin() const
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::crbegin() const
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::rend()
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::rend() const
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::crend() const
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::empty() const
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::size() const
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::max_size() const
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::capacity() const
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::reserve(size_type)
+   void reserve(size_type cnt);
+
+   //! @copydoc ::boost::container::flat_set::shrink_to_fit()
+   void shrink_to_fit();
+
+   #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)... and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->tree_t::emplace_equal(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->tree_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
+   {  return this->tree_t::emplace_equal(BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->tree_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(const value_type &x);
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from x
+   //!   and returns the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, const value_type &x);
+
+   //! <b>Effects</b>: Inserts a new value move constructed  from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+      {  this->tree_t::insert_equal(first, last);  }
+
+   //! <b>Requires</b>: first, last are not iterators into *this and
+   //! must be ordered according to the predicate.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
+      {  this->tree_t::insert_equal(ordered_range, first, last);  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: N log(N).
+   //!
+   //! <b>Note</b>: If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->tree_t::insert_equal(il.begin(), il.end()); }
+
+   //! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
+   BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
+   {  this->tree_t::insert_equal(ordered_range, il.begin(), il.end()); }
+#endif
+
+   //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, AllocatorOrContainer>& source)
+   {  this->tree_t::merge_equal(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_multiset::merge(flat_multiset<Key, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_multiset<Key, C2, AllocatorOrContainer>&>(source));   }
+
+   //! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, AllocatorOrContainer>& source)
+   {  this->tree_t::merge_equal(source.tree());   }
+
+   //! @copydoc ::boost::container::flat_multiset::merge(flat_set<Key, C2, AllocatorOrContainer>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<flat_set<Key, C2, AllocatorOrContainer>&>(source));   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::flat_set::erase(const_iterator)
+   iterator erase(const_iterator p);
+
+   //! @copydoc ::boost::container::flat_set::erase(const key_type&)
+   size_type erase(const key_type& x);
+
+   //! @copydoc ::boost::container::flat_set::erase(const_iterator,const_iterator)
+   iterator erase(const_iterator first, const_iterator last);
+
+   //! @copydoc ::boost::container::flat_set::swap
+   void swap(flat_multiset& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
+
+   //! @copydoc ::boost::container::flat_set::clear
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::key_comp
+   key_compare key_comp() const;
+
+   //! @copydoc ::boost::container::flat_set::value_comp
+   value_compare value_comp() const;
+
+   //! @copydoc ::boost::container::flat_set::find(const key_type& )
+   iterator find(const key_type& x);
+
+   //! @copydoc ::boost::container::flat_set::find(const key_type& ) const
+   const_iterator find(const key_type& x) const;
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type)
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::nth(size_type) const
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::index_of(iterator)
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::flat_set::count(const key_type& ) const
+   size_type count(const key_type& x) const;
+
+   //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& )
+   iterator lower_bound(const key_type& x);
+
+   //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& ) const
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& )
+   iterator upper_bound(const key_type& x);
+
+   //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& ) const
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! @copydoc ::boost::container::flat_set::equal_range(const key_type& ) const
+   std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
+
+   //! @copydoc ::boost::container::flat_set::equal_range(const key_type& )
+   std::pair<iterator,iterator> equal_range(const key_type& x);
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const flat_multiset& x, const flat_multiset& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(flat_multiset& x, flat_multiset& y);
+
+   //! <b>Effects</b>: Extracts the internal sequence container.
+   //!
+   //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   //!
+   //! <b>Throws</b>: If secuence_type's move constructor throws 
+   sequence_type extract_sequence();
+
+   #endif   //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+   //!
+   //! <b>Throws</b>: If the comparison or the move constructor throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+   {  this->tree_t::adopt_sequence_equal(boost::move(seq));  }
+
+   //! <b>Requires</b>: seq shall be ordered according to this->compare()
+   //!
+   //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+   //!   one passed externally using the move assignment.
+   //!
+   //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+   //!
+   //! <b>Throws</b>: If the move assignment throws
+   BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
+   {  this->tree_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq));  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x)
+   {  return this->tree_t::insert_equal(::boost::forward<KeyType>(x));  }
+
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+   {  return this->tree_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+flat_multiset(InputIterator, InputIterator) ->
+   flat_multiset<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_multiset(InputIterator, InputIterator, Allocator const&) ->
+   flat_multiset< typename iterator_traits<InputIterator>::value_type
+                , std::less<typename iterator_traits<InputIterator>::value_type>
+                , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_multiset(InputIterator, InputIterator, Compare const&) ->
+   flat_multiset<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_multiset(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+template <typename InputIterator>
+flat_multiset(ordered_range_t, InputIterator, InputIterator) ->
+   flat_multiset<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+flat_multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) ->
+   flat_multiset< typename iterator_traits<InputIterator>::value_type
+                , std::less<typename iterator_traits<InputIterator>::value_type>
+                , Allocator>;
+
+template <typename InputIterator, typename Compare>
+flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) ->
+   flat_multiset< typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   flat_multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class Compare, class AllocatorOrContainer>
+struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, AllocatorOrContainer> >
+{
+   typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   // BOOST_CONTAINER_FLAT_SET_HPP
diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp
new file mode 100644
index 0000000..68892bc
--- /dev/null
+++ b/include/boost/container/list.hpp
@@ -0,0 +1,1499 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_LIST_HPP
+#define BOOST_CONTAINER_LIST_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/algorithm.hpp>
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/value_functors.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#  include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/list.hpp>
+// other
+#include <boost/assert.hpp>
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace dtl {
+
+template<class VoidPointer>
+struct list_hook
+{
+   typedef typename dtl::bi::make_list_base_hook
+      <dtl::bi::void_pointer<VoidPointer>, dtl::bi::link_mode<dtl::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct list_node
+   :  public list_hook<VoidPointer>::type
+{
+   private:
+   list_node();
+
+   public:
+   typedef T value_type;
+   typedef typename list_hook<VoidPointer>::type hook_type;
+
+   T m_data;
+
+   T &get_data()
+   {  return this->m_data;   }
+
+   const T &get_data() const
+   {  return this->m_data;   }
+};
+
+template <class T, class VoidPointer>
+struct iiterator_node_value_type< list_node<T,VoidPointer> > {
+  typedef T type;
+};
+
+template<class Allocator>
+struct intrusive_list_type
+{
+   typedef boost::container::allocator_traits<Allocator>   allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename boost::intrusive::pointer_traits
+      <typename allocator_traits_type::pointer>::template
+         rebind_pointer<void>::type
+            void_pointer;
+   typedef typename dtl::list_node
+         <value_type, void_pointer>             node_type;
+   typedef typename dtl::bi::make_list
+      < node_type
+      , dtl::bi::base_hook<typename list_hook<void_pointer>::type>
+      , dtl::bi::constant_time_size<true>
+      , dtl::bi::size_type
+         <typename allocator_traits_type::size_type>
+      >::type                                   container_type;
+   typedef container_type                       type ;
+};
+
+}  //namespace dtl {
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A list is a doubly linked list. That is, it is a Sequence that supports both
+//! forward and backward traversal, and (amortized) constant time insertion and
+//! removal of elements at the beginning or the end, or in the middle. Lists have
+//! the important property that insertion and splicing do not invalidate iterators
+//! to list elements, and that even removal invalidates only the iterators that point
+//! to the elements that are removed. The ordering of iterators may be changed
+//! (that is, list<T>::iterator might have a different predecessor or successor
+//! after a list operation than it did before), but the iterators themselves will
+//! not be invalidated or made to point to different elements unless that invalidation
+//! or mutation is explicit.
+//!
+//! \tparam T The type of object that is stored in the list
+//! \tparam Allocator The allocator used for all internal memory management
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Allocator = new_allocator<T> >
+#else
+template <class T, class Allocator>
+#endif
+class list
+   : protected dtl::node_alloc_holder
+      <Allocator, typename dtl::intrusive_list_type<Allocator>::type>
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef typename
+      dtl::intrusive_list_type<Allocator>::type Icont;
+   typedef dtl::node_alloc_holder<Allocator, Icont>  AllocHolder;
+   typedef typename AllocHolder::NodePtr                          NodePtr;
+   typedef typename AllocHolder::NodeAlloc                        NodeAlloc;
+   typedef typename AllocHolder::ValAlloc                         ValAlloc;
+   typedef typename AllocHolder::Node                             Node;
+   typedef dtl::allocator_destroyer<NodeAlloc>       Destroyer;
+   typedef typename AllocHolder::alloc_version                    alloc_version;
+   typedef boost::container::allocator_traits<Allocator>          allocator_traits_type;
+   typedef boost::container::equal_to_value<Allocator>            equal_to_value_type;
+
+   BOOST_COPYABLE_AND_MOVABLE(list)
+
+   typedef dtl::iterator_from_iiterator<typename Icont::iterator, false>  iterator_impl;
+   typedef dtl::iterator_from_iiterator<typename Icont::iterator, true>   const_iterator_impl;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef T                                                                           value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(NodeAlloc)                                           stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(iterator_impl)                                       iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl)                                 const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs a list.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   list() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : AllocHolder()
+   {}
+
+   //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW
+      : AllocHolder(a)
+   {}
+
+   //! <b>Effects</b>: Constructs a list
+   //!   and inserts n value-initialized value_types.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit list(size_type n)
+      : AllocHolder(Allocator())
+   {  this->resize(n);  }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   list(size_type n, const allocator_type &a)
+      : AllocHolder(a)
+   {  this->resize(n);  }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   list(size_type n, const T& value, const Allocator& a = Allocator())
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), n, value);  }
+
+   //! <b>Effects</b>: Copy constructs a list.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   list(const list& x)
+      : AllocHolder(x)
+   {  this->insert(this->cbegin(), x.begin(), x.end());   }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   list(BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
+      : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   list(const list& x, const allocator_type &a)
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), x.begin(), x.end());   }
+
+   //! <b>Effects</b>: Move constructor sing the specified allocator.
+   //!                 Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   list(BOOST_RV_REF(list) x, const allocator_type &a)
+      : AllocHolder(a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
+      }
+   }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the list.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+   template <class InpIt>
+   list(InpIt first, InpIt last, const Allocator &a = Allocator())
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), first, last);  }
+
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [il.begin(), il.end()) in the list.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced
+   //!   std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   list(std::initializer_list<value_type> il, const Allocator &a = Allocator())
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), il.begin(), il.end()); }
+#endif
+
+   //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements.
+   ~list() BOOST_NOEXCEPT_OR_NOTHROW
+   {} //AllocHolder clears the list
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->node_alloc();
+         const NodeAlloc &x_alloc  = x.node_alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
+   //!
+   //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   list& operator=(BOOST_RV_REF(list) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(this != &x);
+      NodeAlloc &this_alloc = this->node_alloc();
+      NodeAlloc &x_alloc    = x.node_alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy
+         this->clear();
+         //Move allocator if needed
+         this->AllocHolder::move_assign_alloc(x);
+         //Obtain resources
+         this->icont() = boost::move(x.icont());
+      }
+      //Else do a one by one move
+      else{
+         this->assign( boost::make_move_iterator(x.begin())
+                     , boost::make_move_iterator(x.end()));
+      }
+      return *this;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Makes *this contain the same elements as il.
+   //!
+   //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   list& operator=(std::initializer_list<value_type> il)
+   {
+      assign(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Assigns the n copies of val to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   void assign(size_type n, const T& val)
+   {
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->assign(cvalue_iterator(val, n), cvalue_iterator());
+   }
+
+   //! <b>Effects</b>: Assigns the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template <class InpIt>
+   void assign(InpIt first, InpIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible<InpIt, size_type>::type * = 0
+      #endif
+      )
+   {
+      iterator first1      = this->begin();
+      const iterator last1 = this->end();
+      for ( ; first1 != last1 && first != last; ++first1, ++first)
+         *first1 = *first;
+      if (first == last)
+         this->erase(first1, last1);
+      else{
+         this->insert(last1, first, last);
+      }
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   void assign(std::initializer_list<value_type> il)
+   { assign(il.begin(), il.end()); }
+#endif
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return allocator_type(this->node_alloc()); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->node_alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->node_alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return iterator(this->icont().begin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->cbegin();   }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(this->icont().end());  }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->cend();  }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return reverse_iterator(end());  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->crbegin();  }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return reverse_iterator(begin());   }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->crend();   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(this->non_const_icont().begin());   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(this->non_const_icont().end());  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_reverse_iterator(this->cend());  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_reverse_iterator(this->cbegin());   }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the list contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return !this->size();  }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {   return this->icont().size();   }
+
+   //! <b>Effects</b>: Returns the largest possible size of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return AllocHolder::max_size();  }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {
+      if(!priv_try_shrink(new_size)){
+         typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
+         this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
+      }
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x)
+   {
+      if(!priv_try_shrink(new_size)){
+         this->insert(this->cend(), new_size - this->size(), x);
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->begin();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->begin();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(--this->end());
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(--this->end());
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the end of the list.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant
+   template <class... Args>
+   reference emplace_back(BOOST_FWD_REF(Args)... args)
+   {  return *this->emplace(this->cend(), boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the beginning of the list.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant
+   template <class... Args>
+   reference emplace_front(BOOST_FWD_REF(Args)... args)
+   {  return *this->emplace(this->cbegin(), boost::forward<Args>(args)...);  }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... before p.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant
+   template <class... Args>
+   iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args)
+   {
+      BOOST_ASSERT((priv_is_linked)(position));
+      NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
+      return iterator(this->icont().insert(position.get(), *pnode));
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   reference emplace_back(BOOST_MOVE_UREF##N)\
+   {  return *this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   reference emplace_front(BOOST_MOVE_UREF##N)\
+   {  return *this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\
+      NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+      return iterator(this->icont().insert(position.get(), *pnode));\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_LIST_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the beginning of the list
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the end of the list.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the end of the list
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   iterator insert(const_iterator p, const T &x);
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a new element before p with x's resources.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   iterator insert(const_iterator p, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts n copies of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   iterator insert(const_iterator position, size_type n, const T& x)
+   {
+      //range check is done by insert
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->insert(position, cvalue_iterator(x, n), cvalue_iterator());
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [first, last).
+   template <class InpIt>
+   iterator insert(const_iterator p, InpIt first, InpIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::enable_if_c
+         < !dtl::is_convertible<InpIt, size_type>::value
+            && (dtl::is_input_iterator<InpIt>::value
+                || dtl::is_same<alloc_version, version_1>::value
+               )
+         >::type * = 0
+      #endif
+      )
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      const typename Icont::iterator ipos(p.get());
+      iterator ret_it(ipos);
+      if(first != last){
+         ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
+         ++first;
+      }
+      for (; first != last; ++first){
+         this->icont().insert(ipos, *this->create_node_from_it(first));
+      }
+      return ret_it;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   iterator insert(const_iterator position, FwdIt first, FwdIt last
+      , typename dtl::enable_if_c
+         < !dtl::is_convertible<FwdIt, size_type>::value
+            && !(dtl::is_input_iterator<FwdIt>::value
+                || dtl::is_same<alloc_version, version_1>::value
+               )
+         >::type * = 0
+      )
+   {
+      BOOST_ASSERT((priv_is_linked)(position));
+      //Optimized allocation and construction
+      insertion_functor func(this->icont(), position.get());
+      iterator before_p(position.get());
+      --before_p;
+      this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
+      return ++before_p;
+   }
+   #endif
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if if.begin() == il.end().
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
+   iterator insert(const_iterator p, std::initializer_list<value_type> il)
+   {
+      //position range check is done by insert()
+      return insert(p, il.begin(), il.end());
+   }
+#endif
+
+   //! <b>Effects</b>: Removes the first element from the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      this->erase(this->cbegin());
+   }
+
+   //! <b>Effects</b>: Removes the last element from the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      const_iterator tmp = this->cend();
+      this->erase(--tmp);
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Erases the element at p.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p));
+      return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc())));
+   }
+
+   //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+   //!
+   //! <b>Effects</b>: Erases the elements pointed by [first, last).
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the distance between first and last.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
+      BOOST_ASSERT(first == last || (priv_is_linked)(last));
+      return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(list& x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+                               || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
+                   allocator_traits_type::is_always_equal::value ||
+                   this->get_stored_allocator() == x.get_stored_allocator());
+      AllocHolder::swap(x);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the list.
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {  AllocHolder::clear(alloc_version());  }
+
+   //////////////////////////////////////////////
+   //
+   //              slist operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      BOOST_ASSERT(this != &x);
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice(p.get(), x.icont());
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //Checks done in splice
+      this->splice(p, static_cast<list&>(x));
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice(p.get(), x.icont(), i.get());
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this != &x);
+      //Additional checks done in splice()
+      this->splice(p, static_cast<list&>(x), i);
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements transferred.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first)));
+      BOOST_ASSERT(first == last || x.priv_is_linked(last));
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice(p.get(), x.icont(), first.get(), last.get());
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements transferred.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this != &x);
+      //Additional checks done in splice()
+      this->splice(p, static_cast<list&>(x), first, last);
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   n == distance(first, last). this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>:  Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   n == distance(first, last). this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice(p, static_cast<list&>(x), first, last, n);  }
+
+   //! <b>Effects</b>: Removes all the elements that compare equal to value.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void remove(const T& value)
+   {  this->remove_if(equal_to_value_type(value));  }
+
+   //! <b>Effects</b>: Removes all the elements for which a specified
+   //!   predicate is satisfied.
+   //!
+   //! <b>Throws</b>: If pred throws.
+   //!
+   //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template <class Pred>
+   void remove_if(Pred pred)
+   {
+      typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+      this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+   //!   elements that are equal from the list.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void unique()
+   {  this->unique(value_equal_t());  }
+
+   //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+   //!   elements that satisfy some binary predicate from the list.
+   //!
+   //! <b>Throws</b>: If pred throws.
+   //!
+   //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template <class BinaryPredicate>
+   void unique(BinaryPredicate binary_pred)
+   {
+      typedef value_to_node_compare<Node, BinaryPredicate> value_to_node_compare_type;
+      this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
+   }
+
+   //! <b>Requires</b>: The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less<value_type>. The merge is stable;
+   //!   that is, if an element from *this is equivalent to one from x, then the element
+   //!   from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(list &x)
+   {  this->merge(x, value_less_t());  }
+
+   //! <b>Requires</b>: The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less<value_type>. The merge is stable;
+   //!   that is, if an element from *this is equivalent to one from x, then the element
+   //!   from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(BOOST_RV_REF(list) x)
+   {  this->merge(static_cast<list&>(x)); }
+
+   //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is
+   //!   equivalent to one from x, then the element from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //!
+   //! <b>Note</b>: Iterators and references to *this are not invalidated.
+   template <class StrictWeakOrdering>
+   void merge(list &x, const StrictWeakOrdering &comp)
+   {
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+      this->icont().merge(x.icont(), value_to_node_compare_type(comp));
+   }
+
+   //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is
+   //!   equivalent to one from x, then the element from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //!
+   //! <b>Note</b>: Iterators and references to *this are not invalidated.
+   template <class StrictWeakOrdering>
+   void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
+   {  this->merge(static_cast<list&>(x), comp); }
+
+   //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Notes</b>: Iterators and references are not invalidated.
+   //!
+   //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   void sort()
+   {  this->sort(value_less_t());  }
+
+   //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Notes</b>: Iterators and references are not invalidated.
+   //!
+   //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   template <class StrictWeakOrdering>
+   void sort(StrictWeakOrdering comp)
+   {
+      // nothing if the list has length 0 or 1.
+      if (this->size() < 2)
+         return;
+      typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+      this->icont().sort(value_to_node_compare_type(comp));
+   }
+
+   //! <b>Effects</b>: Reverses the order of elements in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: This function is linear time.
+   //!
+   //! <b>Note</b>: Iterators and references are not invalidated
+   void reverse() BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->icont().reverse(); }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const list& x, const list& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const list& x, const list& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const list& x, const list& y)
+   {  return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const list& x, const list& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const list& x, const list& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const list& x, const list& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(list& x, list& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   static bool priv_is_linked(const_iterator const position)
+   {
+      const_iterator cur(position);
+      //This list is circular including end nodes
+      return (--(++cur)) == position && (++(--cur)) == position;
+   }
+
+   bool priv_try_shrink(size_type new_size)
+   {
+      const size_type len = this->size();
+      if(len > new_size){
+         const const_iterator iend = this->cend();
+         size_type to_erase = len - new_size;
+         const_iterator ifirst;
+         if(to_erase < len/2u){
+            ifirst = iend;
+            while(to_erase--){
+               --ifirst;
+            }
+         }
+         else{
+            ifirst = this->cbegin();
+            size_type to_skip = len - to_erase;
+            while(to_skip--){
+               ++ifirst;
+            }
+         }
+         this->erase(ifirst, iend);
+         return true;
+      }
+      else{
+         return false;
+      }
+   }
+
+   iterator priv_insert(const_iterator p, const T &x)
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      NodePtr tmp = AllocHolder::create_node(x);
+      return iterator(this->icont().insert(p.get(), *tmp));
+   }
+
+   iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
+   {
+      BOOST_ASSERT((priv_is_linked)(p));
+      NodePtr tmp = AllocHolder::create_node(boost::move(x));
+      return iterator(this->icont().insert(p.get(), *tmp));
+   }
+
+   void priv_push_back (const T &x)
+   {  this->insert(this->cend(), x);    }
+
+   void priv_push_back (BOOST_RV_REF(T) x)
+   {  this->insert(this->cend(), boost::move(x));    }
+
+   void priv_push_front (const T &x)
+   {  this->insert(this->cbegin(), x);  }
+
+   void priv_push_front (BOOST_RV_REF(T) x)
+   {  this->insert(this->cbegin(), boost::move(x));  }
+
+   class insertion_functor;
+   friend class insertion_functor;
+
+   class insertion_functor
+   {
+      Icont &icont_;
+      typedef typename Icont::const_iterator iconst_iterator;
+      const iconst_iterator pos_;
+
+      public:
+      insertion_functor(Icont &icont, typename Icont::const_iterator pos)
+         :  icont_(icont), pos_(pos)
+      {}
+
+      void operator()(Node &n)
+      {
+         this->icont_.insert(pos_, n);
+      }
+   };
+
+   typedef value_less<value_type>   value_less_t;
+   typedef value_equal<value_type>  value_equal_t;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+};
+
+#if __cplusplus >= 201703L
+template <typename InputIterator>
+list(InputIterator, InputIterator) ->
+   list<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+list(InputIterator, InputIterator, Allocator const&) ->
+   list<typename iterator_traits<InputIterator>::value_type, Allocator>;
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_LIST_HPP
diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp
new file mode 100644
index 0000000..a88b6a5
--- /dev/null
+++ b/include/boost/container/map.hpp
@@ -0,0 +1,2233 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_MAP_HPP
+#define BOOST_CONTAINER_MAP_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/tree.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/value_init.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/pair_key_mapped_of_value.hpp>
+
+// move
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// other
+#include <boost/static_assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys. The map class supports bidirectional iterators.
+//!
+//! A map satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. The <code>value_type</code> stored
+//! by this container is the value_type is std::pair<const Key, T>.
+//!
+//! \tparam Key is the key_type of the map
+//! \tparam T is the <code>mapped_type</code>
+//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
+//!   (e.g. <i>allocator< std::pair<const Key, T> > </i>).
+//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
+template < class Key, class T, class Compare = std::less<Key>
+         , class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults >
+#else
+template <class Key, class T, class Compare, class Allocator, class Options>
+#endif
+class map
+   ///@cond
+   : public dtl::tree
+      < std::pair<const Key, T>
+      , dtl::select1st<Key>
+      , Compare, Allocator, Options>
+   ///@endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(map)
+
+   typedef dtl::select1st<Key>                                select_1st_t;
+   typedef std::pair<const Key, T>                                         value_type_impl;
+   typedef dtl::tree
+      <value_type_impl, select_1st_t, Compare, Allocator, Options>         base_t;
+   typedef dtl::pair <Key, T>                                 movable_value_type_impl;
+   typedef typename base_t::value_compare                                  value_compare_impl;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef Key                                                                      key_type;
+   typedef ::boost::container::allocator_traits<Allocator>                          allocator_traits_type;
+   typedef T                                                                        mapped_type;
+   typedef typename boost::container::allocator_traits<Allocator>::value_type       value_type;
+   typedef typename boost::container::allocator_traits<Allocator>::pointer          pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::const_pointer    const_pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::reference        reference;
+   typedef typename boost::container::allocator_traits<Allocator>::const_reference  const_reference;
+   typedef typename boost::container::allocator_traits<Allocator>::size_type        size_type;
+   typedef typename boost::container::allocator_traits<Allocator>::difference_type  difference_type;
+   typedef Allocator                                                                allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)           stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(value_compare_impl)                               value_compare;
+   typedef Compare                                                                  key_compare;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                        iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                  const_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)          const_reverse_iterator;
+   typedef std::pair<key_type, mapped_type>                                         nonconst_value_type;
+   typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl)                          movable_value_type;
+   typedef BOOST_CONTAINER_IMPDEF(node_handle<
+      typename base_t::stored_allocator_type
+      BOOST_MOVE_I pair_key_mapped_of_value
+         <key_type BOOST_MOVE_I mapped_type> >)                                     node_type;
+   typedef BOOST_CONTAINER_IMPDEF
+      (insert_return_type_base<iterator BOOST_MOVE_I node_type>)                    insert_return_type;
+
+   //allocator_type::value_type type must be std::pair<CONST Key, T>
+   BOOST_STATIC_ASSERT((dtl::is_same<typename allocator_type::value_type, std::pair<const Key, T> >::value));
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty map.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE 
+   map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value &&
+                           dtl::is_nothrow_default_constructible<Compare>::value)
+      : base_t()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object
+   //! and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE map(const Compare& comp, const allocator_type& a)
+      : base_t(comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit map(const Compare& comp)
+      : base_t(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit map(const allocator_type& a)
+      : base_t(a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last)
+      : base_t(true, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const allocator_type& a)
+      : base_t(true, first, last, Compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(true, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : base_t(true, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last)
+      : base_t(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last
+      , const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty map and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted according
+   //! to the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il)
+      : base_t(true, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(true, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const allocator_type& a)
+      : base_t(true, il.begin(), il.end(), Compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(true, il.begin(), il.end(), comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map and inserts elements from the ordered unique range [il.begin(), il.end()).
+   //! This function is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list<value_type> il)
+      : base_t(ordered_range, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object,
+   //!  and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(ordered_range, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, std::initializer_list<value_type> il
+                                  , const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, il.begin(), il.end(), comp, a)
+   {} 
+
+#endif
+
+   //! <b>Effects</b>: Copy constructs a map.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE map(const map& x)
+      : base_t(static_cast<const base_t&>(x))
+   {}
+
+   //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : base_t(BOOST_MOVE_BASE(base_t, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a map using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE map(const map& x, const allocator_type &a)
+      : base_t(static_cast<const base_t&>(x), a)
+   {}
+
+   //! <b>Effects</b>: Move constructs a map using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x, const allocator_type &a)
+      : base_t(BOOST_MOVE_BASE(base_t, x), a)
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
+   {  return static_cast<map&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
+
+   //! <b>Effects</b>: this->swap(x.get()).
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_RV_REF(map) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<map&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assign content of il to *this.
+   //!
+   BOOST_CONTAINER_FORCEINLINE map& operator=(std::initializer_list<value_type> il)
+   {
+       this->clear();
+       insert(il.begin(), il.end());
+       return *this;
+   }
+#endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Returns a copy of the allocator that
+   //!   was passed to the object's constructor.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const;
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns an iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns true if the container contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the largest possible size of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: If there is no key equivalent to x in the map, inserts
+   //! value_type(x, T()) into the map.
+   //!
+   //! <b>Returns</b>: A reference to the mapped_type corresponding to x in *this.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   mapped_type& operator[](const key_type &k);
+
+   //! <b>Effects</b>: If there is no key equivalent to x in the map, inserts
+   //! value_type(boost::move(x), T()) into the map (the key is move-constructed)
+   //!
+   //! <b>Returns</b>: A reference to the mapped_type corresponding to x in *this.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   mapped_type& operator[](key_type &&k);
+   #elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
+      //in compilers like GCC 3.4, we can't catch temporaries
+      BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k)         {  return this->priv_subscript(k);  }
+      BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](BOOST_RV_REF(key_type) k)  {  return this->priv_subscript(::boost::move(k));  }
+   #else
+      BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
+   #endif
+
+   //! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, forward<M>(obj)).
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! <b>Returns</b>: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! <b>Complexity</b>: Logarithmic in the size of the container.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
+   {  return this->base_t::insert_or_assign(const_iterator(), k, ::boost::forward<M>(obj));  }
+
+   //! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, move(obj)).
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! <b>Returns</b>: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! <b>Complexity</b>: Logarithmic in the size of the container.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
+   {  return this->base_t::insert_or_assign(const_iterator(), ::boost::move(k), ::boost::forward<M>(obj));  }
+
+   //! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
+   //! to the container as close as possible to the position just before hint.
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! <b>Returns</b>: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! <b>Complexity</b>: Logarithmic in the size of the container in general, but amortized constant if
+   //! the new element is inserted just before hint.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
+   {  return this->base_t::insert_or_assign(hint, k, ::boost::forward<M>(obj));  }
+
+   //! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
+   //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
+   //! as if by insert, constructing it from value_type(k, move(obj)) and the new element
+   //! to the container as close as possible to the position just before hint.
+   //! 
+   //! No iterators or references are invalidated. If the insertion is successful, pointers and references
+   //! to the element obtained while it is held in the node handle are invalidated, and pointers and
+   //! references obtained to that element before it was extracted become valid.
+   //!
+   //! <b>Returns</b>: The bool component is true if the insertion took place and false if the assignment
+   //!   took place. The iterator component is pointing at the element that was inserted or updated.
+   //!
+   //! <b>Complexity</b>: Logarithmic in the size of the container in general, but amortized constant if
+   //! the new element is inserted just before hint.
+   template <class M>
+   BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
+   {  return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward<M>(obj));  }
+
+   //! <b>Returns</b>: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! <b>Complexity</b>: logarithmic.
+   T& at(const key_type& k)
+   {
+      iterator i = this->find(k);
+      if(i == this->end()){
+         throw_out_of_range("map::at key not found");
+      }
+      return i->second;
+   }
+
+   //! <b>Returns</b>: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! <b>Complexity</b>: logarithmic.
+   const T& at(const key_type& k) const
+   {
+      const_iterator i = this->find(k);
+      if(i == this->end()){
+         throw_out_of_range("map::at key not found");
+      }
+      return i->second;
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
+   { return this->base_t::insert_unique(x); }
+
+   //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
+   //! there is no element in the container  with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const nonconst_value_type& x)
+   { return this->try_emplace(x.first, x.second); }
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
+   { return this->try_emplace(boost::move(x.first), boost::move(x.second)); }
+
+   //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
+   { return this->try_emplace(boost::move(x.first), boost::move(x.second)); }
+
+   //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+   { return this->base_t::insert_unique(boost::move(x)); }
+
+   //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
+   { return this->base_t::insert_unique(p, x); }
+
+   //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
+   { return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
+
+   //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
+   { return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
+
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator insert(const_iterator p, const nonconst_value_type& x)
+   { return this->try_emplace(p, x.first, x.second); }
+
+   //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+   { return this->base_t::insert_unique(p, boost::move(x)); }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+   {  this->base_t::insert_unique(first, last);  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end())
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->base_t::insert_unique(il.begin(), il.end()); }
+#endif
+
+   //! <b>Requires</b>: nh is empty or this->get_allocator() == nh.get_allocator().
+   //!
+   //! <b>Effects</b>: If nh is empty, has no effect. Otherwise, inserts the element owned
+   //!   by nh if and only if there is no element in the container with a key equivalent to nh.key().
+   //!
+   //! <b>Returns</b>: If nh is empty, insert_return_type.inserted is false, insert_return_type.position
+   //!   is end(), and insert_return_type.node is empty. Otherwise if the insertion took place,
+   //!   insert_return_type.inserted is true, insert_return_type.position points to the inserted element,
+   //!   and insert_return_type.node is empty; if the insertion failed, insert_return_type.inserted is
+   //!   false, insert_return_type.node has the previous value of nh, and insert_return_type.position
+   //!   points to an element with a key equivalent to nh.key().
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      typename base_t::node_type  n(boost::move(nh));
+      typename base_t::insert_return_type base_ret(this->base_t::insert_unique_node(boost::move(n)));
+      return insert_return_type (base_ret.inserted, base_ret.position, boost::move(base_ret.node));
+   }
+
+   //! <b>Effects</b>: Same as `insert(node_type && nh)` but the element is inserted as close as possible
+   //!   to the position just prior to "hint".
+   //!
+   //! <b>Complexity</b>: logarithmic in general, but amortized constant if the element is inserted
+   //!   right before "hint".
+   insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      typename base_t::node_type  n(boost::move(nh));
+      typename base_t::insert_return_type base_ret(this->base_t::insert_unique_node(hint, boost::move(n)));
+      return insert_return_type (base_ret.inserted, base_ret.position, boost::move(base_ret.node));
+   }
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object x of type T constructed with
+   //!   std::forward<Args>(args)... in the container if and only if there is
+   //!   no element in the container with an equivalent key.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the container if and only if there is
+   //!   no element in the container with an equivalent key.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
+   //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::try_emplace(const_iterator(), k, boost::forward<Args>(args)...); }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(k), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::try_emplace(hint, k, boost::forward<Args>(args)...).first; }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only if the
+   //! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::try_emplace(const_iterator(), boost::move(k), boost::forward<Args>(args)...); }
+
+   //! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct, 
+   //! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
+   //! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
+   //! forward_as_tuple(forward<Args>(args)...).
+   //! 
+   //! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
+   //! 
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::try_emplace(hint, boost::move(k), boost::forward<Args>(args)...).first; }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_unique(BOOST_MOVE_FWD##N);   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(const key_type& k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::try_emplace(const_iterator(), k BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, const key_type &k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::try_emplace(hint, k BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::try_emplace(const_iterator(), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::try_emplace(hint, boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_MAP_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Erases the element pointed to by p.
+   //!
+   //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists,
+   //!   returns end().
+   //!
+   //! <b>Complexity</b>: Amortized constant time
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+   //!
+   //! <b>Returns</b>: Returns the number of erased elements.
+   //!
+   //! <b>Complexity</b>: log(size()) + count(k)
+   size_type erase(const key_type& x) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Erases all the elements in the range [first, last).
+   //!
+   //! <b>Returns</b>: Returns last.
+   //!
+   //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW;
+
+   #endif
+
+   //! <b>Effects</b>: Removes the first element in the container with key equivalent to k.
+   //!
+   //! <b>Returns</b>: A node_type owning the element if found, otherwise an empty node_type.
+   //!
+   //! <b>Complexity</b>: log(a.size()).
+   node_type extract(const key_type& k)
+   {
+      typename base_t::node_type base_nh(this->base_t::extract(k));
+      node_type nh(boost::move(base_nh));
+      return BOOST_MOVE_RET(node_type, nh);
+   }
+
+   //! <b>Effects</b>: Removes the element pointed to by "position".
+   //!
+   //! <b>Returns</b>: A node_type owning the element, otherwise an empty node_type.
+   //!
+   //! <b>Complexity</b>: Amortized constant.
+   node_type extract(const_iterator position)
+   {
+      typename base_t::node_type base_nh(this->base_t::extract(position));
+      node_type nh(boost::move(base_nh));
+      return BOOST_MOVE_RET(node_type, nh);
+   }
+
+   //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
+   //!
+   //! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
+   //!   the comparison object of *this. If there is an element in a with key equivalent to the
+   //!   key of an element from source, then that element is not extracted from source.
+   //! 
+   //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
+   //!   to those same elements but as members of *this. Iterators referring to the transferred
+   //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
+   //!   not into source.
+   //!
+   //! <b>Throws</b>: Nothing unless the comparison object throws.
+   //!
+   //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
+      this->merge_unique(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<map<Key, T, C2, Allocator, Options>&>(source)); }
+
+   //! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
+      this->base_t::merge_unique(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<multimap<Key, T, C2, Allocator, Options>&>(source)); }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(map& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value )
+
+   //! <b>Effects</b>: erase(a.begin(),a.end()).
+   //!
+   //! <b>Postcondition</b>: size() == 0.
+   //!
+   //! <b>Complexity</b>: linear in size().
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Effects</b>: Returns the comparison object out
+   //!   of which a was constructed.
+   //!
+   //! <b>Complexity</b>: Constant.
+   key_compare key_comp() const;
+
+   //! <b>Effects</b>: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   value_compare value_comp() const;
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator find(const key_type& x);
+
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   const_iterator find(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   iterator find(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   const_iterator find(const K& x) const;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
+   {  return static_cast<size_type>(this->find(x) != this->cend());  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<typename K>
+   BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
+   {  return static_cast<size_type>(this->find(x) != this->cend());  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator lower_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator lower_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator lower_bound(const K& x) const;
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator upper_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator upper_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator upper_bound(const K& x) const;
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   std::pair<iterator,iterator> equal_range(const key_type& x);
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<iterator,iterator> equal_range(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<const_iterator,const_iterator> equal_range(const K& x) const;
+
+   //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
+   //!
+   //! <b>Complexity</b>: Linear
+   void rebalance();
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const map& x, const map& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const map& x, const map& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const map& x, const map& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const map& x, const map& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const map& x, const map& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const map& x, const map& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(map& x, map& y);
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   template<class KeyConvertible>
+   BOOST_CONTAINER_FORCEINLINE mapped_type& priv_subscript(BOOST_FWD_REF(KeyConvertible) k)
+   {
+      return this->try_emplace(boost::forward<KeyConvertible>(k)).first->second;
+   }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+map(InputIterator, InputIterator) ->
+   map< typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+map(InputIterator, InputIterator, Allocator const&) ->
+   map< typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+map(InputIterator, InputIterator, Compare const&) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+map(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+template <typename InputIterator>
+map(ordered_unique_range_t, InputIterator, InputIterator) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   map< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+#endif
+
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. The multimap class
+//! supports bidirectional iterators.
+//!
+//! A multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. The <code>value_type</code> stored
+//! by this container is the value_type is std::pair<const Key, T>.
+//!
+//! \tparam Key is the key_type of the map
+//! \tparam Value is the <code>mapped_type</code>
+//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
+//!   (e.g. <i>allocator< std::pair<const Key, T> > </i>).
+//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
+template < class Key, class T, class Compare = std::less<Key>
+         , class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults>
+#else
+template <class Key, class T, class Compare, class Allocator, class Options>
+#endif
+class multimap
+   ///@cond
+   : public dtl::tree
+      < std::pair<const Key, T>
+      , dtl::select1st<Key>
+      , Compare, Allocator, Options>
+   ///@endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(multimap)
+
+   typedef dtl::select1st<Key>                                      select_1st_t;
+   typedef std::pair<const Key, T>                                               value_type_impl;
+   typedef dtl::tree
+      <value_type_impl, select_1st_t, Compare, Allocator, Options>               base_t;
+   typedef dtl::pair <Key, T>                                       movable_value_type_impl;
+   typedef typename base_t::value_compare                                        value_compare_impl;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   typedef ::boost::container::allocator_traits<Allocator>                       allocator_traits_type;
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef Key                                                                      key_type;
+   typedef T                                                                        mapped_type;
+   typedef typename boost::container::allocator_traits<Allocator>::value_type       value_type;
+   typedef typename boost::container::allocator_traits<Allocator>::pointer          pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::const_pointer    const_pointer;
+   typedef typename boost::container::allocator_traits<Allocator>::reference        reference;
+   typedef typename boost::container::allocator_traits<Allocator>::const_reference  const_reference;
+   typedef typename boost::container::allocator_traits<Allocator>::size_type        size_type;
+   typedef typename boost::container::allocator_traits<Allocator>::difference_type  difference_type;
+   typedef Allocator                                                                allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)           stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(value_compare_impl)                               value_compare;
+   typedef Compare                                                                  key_compare;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                        iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                  const_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)          const_reverse_iterator;
+   typedef std::pair<key_type, mapped_type>                                         nonconst_value_type;
+   typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl)                          movable_value_type;
+   typedef BOOST_CONTAINER_IMPDEF(node_handle<
+      typename base_t::stored_allocator_type
+      BOOST_MOVE_I pair_key_mapped_of_value
+         <key_type BOOST_MOVE_I mapped_type> >)                                     node_type;
+
+   //allocator_type::value_type type must be std::pair<CONST Key, T>
+   BOOST_STATIC_ASSERT((dtl::is_same<typename allocator_type::value_type, std::pair<const Key, T> >::value));
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty multimap.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE multimap()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value &&
+                        dtl::is_nothrow_default_constructible<Compare>::value)
+      : base_t()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified allocator
+   //!   object and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit multimap(const allocator_type& a)
+      : base_t(a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit multimap(const Compare& comp)
+      : base_t(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE multimap(const Compare& comp, const allocator_type& a)
+      : base_t(comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last)
+      : base_t(false, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const allocator_type& a)
+      : base_t(false, first, last, Compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(false, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
+   //!   and allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last,
+            const Compare& comp, const allocator_type& a)
+      : base_t(false, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap and
+   //! inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last)
+      : base_t(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+   //! inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp,
+         const allocator_type& a)
+      : base_t(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty multimap and
+   //! and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il)
+      : base_t(false, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const allocator_type& a)
+      : base_t(false, il.begin(), il.end(), Compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(false, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.first() - il.end().
+   BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(false, il.begin(), il.end(), comp, a)
+   {}
+
+
+   //! <b>Effects</b>: Constructs an empty map and
+   //! inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il)
+      : base_t(ordered_range, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+   //! inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(ordered_range, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty map and
+   //! inserts elements from the ordered range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, il.begin(), il.end(), comp, a)
+   {}
+
+#endif
+
+   //! <b>Effects</b>: Copy constructs a multimap.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x)
+      : base_t(static_cast<const base_t&>(x))
+   {}
+
+   //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : base_t(BOOST_MOVE_BASE(base_t, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a multimap.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x, const allocator_type &a)
+      : base_t(static_cast<const base_t&>(x), a)
+   {}
+
+   //! <b>Effects</b>: Move constructs a multimap using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
+      : base_t(BOOST_MOVE_BASE(base_t, x), a)
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x)
+   {  return static_cast<multimap&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
+
+   //! <b>Effects</b>: this->swap(x.get()).
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_RV_REF(multimap) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<multimap&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assign content of il to *this.
+   //!
+   BOOST_CONTAINER_FORCEINLINE multimap& operator=(std::initializer_list<value_type> il)
+   {
+       this->clear();
+       insert(il.begin(), il.end());
+       return *this;
+   }
+#endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::set::get_allocator()
+   allocator_type get_allocator() const;
+
+   //! @copydoc ::boost::container::set::get_stored_allocator()
+   stored_allocator_type &get_stored_allocator();
+
+   //! @copydoc ::boost::container::set::get_stored_allocator() const
+   const stored_allocator_type &get_stored_allocator() const;
+
+   //! @copydoc ::boost::container::set::begin()
+   iterator begin();
+
+   //! @copydoc ::boost::container::set::begin() const
+   const_iterator begin() const;
+
+   //! @copydoc ::boost::container::set::cbegin() const
+   const_iterator cbegin() const;
+
+   //! @copydoc ::boost::container::set::end()
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::end() const
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::cend() const
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rbegin()
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rbegin() const
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::crbegin() const
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rend()
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rend() const
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::crend() const
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::empty() const
+   bool empty() const;
+
+   //! @copydoc ::boost::container::set::size() const
+   size_type size() const;
+
+   //! @copydoc ::boost::container::set::max_size() const
+   size_type max_size() const;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_equal(BOOST_MOVE_FWD##N);   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N);  }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
+   { return this->base_t::insert_equal(x); }
+
+   //! <b>Effects</b>: Inserts a new value constructed from x and returns
+   //!   the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const nonconst_value_type& x)
+   { return this->base_t::emplace_equal(x); }
+
+   //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+   //!   the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(nonconst_value_type) x)
+   { return this->base_t::emplace_equal(boost::move(x)); }
+
+   //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+   //!   the iterator pointing to the newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator insert(BOOST_RV_REF(movable_value_type) x)
+   { return this->base_t::emplace_equal(boost::move(x)); }
+
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
+   { return this->base_t::insert_equal(p, x); }
+
+   //! <b>Effects</b>: Inserts a new value constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const nonconst_value_type& x)
+   { return this->base_t::emplace_hint_equal(p, x); }
+
+   //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
+   { return this->base_t::emplace_hint_equal(p, boost::move(x)); }
+
+   //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
+   { return this->base_t::emplace_hint_equal(p, boost::move(x)); }
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+   {  this->base_t::insert_equal(first, last); }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end().
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end())
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->base_t::insert_equal(il.begin(), il.end()); }
+#endif
+
+   //! <b>Requires</b>: nh is empty or this->get_allocator() == nh.get_allocator().
+   //!
+   //! <b>Effects/Returns</b>: If nh is empty, has no effect and returns end(). Otherwise, inserts 
+   //!   the element owned by nh and returns an iterator pointing to the newly inserted element.
+   //!   If a range containing elements with keys equivalent to nh.key() exists, 
+   //!   the element is inserted at the end of that range. nh is always emptied.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      typename base_t::node_type n(boost::move(nh));
+      return this->base_t::insert_equal_node(boost::move(n));
+   }
+
+   //! <b>Effects</b>: Same as `insert(node_type && nh)` but the element is inserted as close as possible
+   //!   to the position just prior to "hint".
+   //!
+   //! <b>Complexity</b>: logarithmic in general, but amortized constant if the element is inserted
+   //!   right before "hint".
+   iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {
+      typename base_t::node_type n(boost::move(nh));
+      return this->base_t::insert_equal_node(hint, boost::move(n));
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::set::erase(const_iterator)
+   iterator erase(const_iterator p);
+
+   //! @copydoc ::boost::container::set::erase(const key_type&)
+   size_type erase(const key_type& x);
+
+   //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator)
+   iterator erase(const_iterator first, const_iterator last);
+   #endif
+
+   //! @copydoc ::boost::container::map::extract(const key_type&)
+   node_type extract(const key_type& k)
+   {
+      typename base_t::node_type base_nh(this->base_t::extract(k));
+      return node_type(boost::move(base_nh));
+   }
+
+   //! @copydoc ::boost::container::map::extract(const_iterator)
+   node_type extract(const_iterator position)
+   {
+      typename base_t::node_type base_nh(this->base_t::extract(position));
+      return node_type (boost::move(base_nh));
+   }
+
+   //! <b>Requires</b>: this->get_allocator() == source.get_allocator().
+   //!
+   //! <b>Effects</b>: Extracts each element in source and insert it into a using
+   //!   the comparison object of *this.
+   //! 
+   //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
+   //!   to those same elements but as members of *this. Iterators referring to the transferred
+   //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
+   //!   not into source.
+   //!
+   //! <b>Throws</b>: Nothing unless the comparison object throws.
+   //!
+   //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
+      this->base_t::merge_equal(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<multimap<Key, T, C2, Allocator, Options>&>(source)); }
+
+   //! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
+      this->base_t::merge_equal(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<map<Key, T, C2, Allocator, Options>&>(source)); }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! @copydoc ::boost::container::set::swap
+   void swap(multiset& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
+
+   //! @copydoc ::boost::container::set::clear
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::key_comp
+   key_compare key_comp() const;
+
+   //! @copydoc ::boost::container::set::value_comp
+   value_compare value_comp() const;
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator find(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   const_iterator find(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   iterator find(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   const_iterator find(const K& x) const;
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   size_type count(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<typename K>
+   size_type count(const K& x) const;
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator lower_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator lower_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator lower_bound(const K& x) const;
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator upper_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator upper_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator upper_bound(const K& x) const;
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   std::pair<iterator,iterator> equal_range(const key_type& x);
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<iterator,iterator> equal_range(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<const_iterator,const_iterator> equal_range(const K& x) const;
+
+   //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
+   //!
+   //! <b>Complexity</b>: Linear
+   void rebalance();
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const multimap& x, const multimap& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(multimap& x, multimap& y);
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+multimap(InputIterator, InputIterator) ->
+   multimap<typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+                        , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+multimap(InputIterator, InputIterator, Allocator const&) ->
+   multimap<typename dtl::remove_const< typename iterator_traits<InputIterator>::value_type::first_type>::type
+                        , typename iterator_traits<InputIterator>::value_type::second_type
+                        , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+                        , Allocator>;
+
+template <typename InputIterator, typename Compare>
+multimap(InputIterator, InputIterator, Compare const&) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+multimap(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+template <typename InputIterator>
+multimap(ordered_range_t, InputIterator, InputIterator) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type>;
+
+template <typename InputIterator, typename Allocator>
+multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , std::less<typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type>
+           , Allocator>;
+
+template <typename InputIterator, typename Compare>
+multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   multimap< typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type
+           , typename iterator_traits<InputIterator>::value_type::second_type
+           , Compare
+           , Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   // BOOST_CONTAINER_MAP_HPP
+
diff --git a/include/boost/container/new_allocator.hpp b/include/boost/container/new_allocator.hpp
new file mode 100644
index 0000000..51065ef
--- /dev/null
+++ b/include/boost/container/new_allocator.hpp
@@ -0,0 +1,179 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-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_NEW_ALLOCATOR_HPP
+#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/throw_exception.hpp>
+#include <cstddef>
+
+//!\file
+
+namespace boost {
+namespace container {
+
+/// @cond
+
+template<bool Value>
+struct new_allocator_bool
+{  static const bool value = Value;  };
+
+template<class T>
+class new_allocator;
+
+/// @endcond
+
+//! Specialization of new_allocator for void types
+template<>
+class new_allocator<void>
+{
+   public:
+   typedef void                                 value_type;
+   typedef void *                               pointer;
+   typedef const void*                          const_pointer;
+   //!A integral constant of type bool with value true
+   typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
+   //!A integral constant of type bool with value true
+   typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
+   // reference-to-void members are impossible
+
+   //!Obtains an new_allocator that allocates
+   //!objects of type T2
+   template<class T2>
+   struct rebind
+   {
+      typedef new_allocator< T2> other;
+   };
+
+   //!Default constructor
+   //!Never throws
+   new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from other new_allocator.
+   //!Never throws
+   new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from related new_allocator.
+   //!Never throws
+   template<class T2>
+   new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Swaps two allocators, does nothing
+   //!because this new_allocator is stateless
+   friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An new_allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An new_allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+};
+
+
+//! This class is a reduced STL-compatible allocator that allocates memory using operator new
+template<class T>
+class new_allocator
+{
+   public:
+   typedef T                                    value_type;
+   typedef T *                                  pointer;
+   typedef const T *                            const_pointer;
+   typedef T &                                  reference;
+   typedef const T &                            const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+   //!A integral constant of type bool with value true
+   typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
+   //!A integral constant of type bool with value true
+   typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
+
+   //!Obtains an new_allocator that allocates
+   //!objects of type T2
+   template<class T2>
+   struct rebind
+   {
+      typedef new_allocator<T2> other;
+   };
+
+   //!Default constructor
+   //!Never throws
+   new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from other new_allocator.
+   //!Never throws
+   new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Constructor from related new_allocator.
+   //!Never throws
+   template<class T2>
+   new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Allocates memory for an array of count elements.
+   //!Throws std::bad_alloc if there is no enough memory
+   pointer allocate(size_type count)
+   {
+      if(BOOST_UNLIKELY(count > this->max_size()))
+         throw_bad_alloc();
+      return static_cast<T*>(::operator new(count*sizeof(T)));
+   }
+
+   //!Deallocates previously allocated memory.
+   //!Never throws
+   void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
+     { ::operator delete((void*)ptr); }
+
+   //!Returns the maximum number of elements that could be allocated.
+   //!Never throws
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return size_type(-1)/sizeof(T);   }
+
+   //!Swaps two allocators, does nothing
+   //!because this new_allocator is stateless
+   friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An new_allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An new_allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
diff --git a/include/boost/container/node_allocator.hpp b/include/boost/container/node_allocator.hpp
new file mode 100644
index 0000000..b5c20a6
--- /dev/null
+++ b/include/boost/container/node_allocator.hpp
@@ -0,0 +1,341 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2013. 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_POOLED_NODE_ALLOCATOR_HPP
+#define BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  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/throw_exception.hpp>
+#include <boost/container/detail/node_pool.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/dlmalloc.hpp>
+#include <boost/container/detail/singleton.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace container {
+
+//!An STL node allocator that uses a modified DlMalloc as memory
+//!source.
+//!
+//!This node allocator shares a segregated storage between all instances
+//!of node_allocator with equal sizeof(T).
+//!
+//!NodesPerBlock is the number of nodes allocated at once when the allocator
+//!runs out of nodes
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template
+   < class T
+   , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block>
+#else
+template
+   < class T
+   , std::size_t NodesPerBlock
+   , std::size_t Version>
+#endif
+class node_allocator
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   //! If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
+   //! the allocator offers advanced expand in place and burst allocation capabilities.
+   public:
+   typedef unsigned int allocation_type;
+   typedef node_allocator<T, NodesPerBlock, Version>   self_t;
+
+   static const std::size_t nodes_per_block = NodesPerBlock;
+
+   BOOST_STATIC_ASSERT((Version <=2));
+   #endif
+
+   public:
+   //-------
+   typedef T                                    value_type;
+   typedef T *                                  pointer;
+   typedef const T *                            const_pointer;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<T>::type     reference;
+   typedef typename ::boost::container::
+      dtl::unvoid_ref<const T>::type     const_reference;
+   typedef std::size_t                          size_type;
+   typedef std::ptrdiff_t                       difference_type;
+
+   typedef boost::container::dtl::
+      version_type<self_t, Version>             version;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef boost::container::dtl::
+      basic_multiallocation_chain<void*>              multiallocation_chain_void;
+   typedef boost::container::dtl::
+      transform_multiallocation_chain
+         <multiallocation_chain_void, T>              multiallocation_chain;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Obtains node_allocator from
+   //!node_allocator
+   template<class T2>
+   struct rebind
+   {
+      typedef node_allocator< T2, NodesPerBlock
+                            #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+                            , Version
+                            #endif
+                            > other;
+   };
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   //!Not assignable from related node_allocator
+   template<class T2, std::size_t N2>
+   node_allocator& operator=
+      (const node_allocator<T2, N2>&);
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //!Default constructor
+   node_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from other node_allocator.
+   node_allocator(const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Copy constructor from related node_allocator.
+   template<class T2>
+   node_allocator
+      (const node_allocator<T2, NodesPerBlock
+            #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+            , Version
+            #endif
+            > &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Destructor
+   ~node_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!Returns the number of elements that could be allocated.
+   //!Never throws
+   size_type max_size() const
+   {  return size_type(-1)/sizeof(T);   }
+
+   //!Allocate memory for an array of count elements.
+   //!Throws std::bad_alloc if there is no enough memory
+   pointer allocate(size_type count, const void * = 0)
+   {
+      if(BOOST_UNLIKELY(count > this->max_size()))
+         boost::container::throw_bad_alloc();
+
+      if(Version == 1 && count == 1){
+         typedef dtl::shared_node_pool
+            <sizeof(T), NodesPerBlock> shared_pool_t;
+         typedef dtl::singleton_default<shared_pool_t> singleton_t;
+         return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
+      }
+      else{
+         void *ret = dlmalloc_malloc(count*sizeof(T));
+         if(BOOST_UNLIKELY(!ret))
+            boost::container::throw_bad_alloc();
+         return static_cast<pointer>(ret);
+      }
+   }
+
+   //!Deallocate allocated memory.
+   //!Never throws
+   void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      (void)count;
+      if(Version == 1 && count == 1){
+         typedef dtl::shared_node_pool
+            <sizeof(T), NodesPerBlock> shared_pool_t;
+         typedef dtl::singleton_default<shared_pool_t> singleton_t;
+         singleton_t::instance().deallocate_node(ptr);
+      }
+      else{
+         dlmalloc_free(ptr);
+      }
+   }
+
+   //!Deallocates all free blocks of the pool
+   static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      typedef dtl::shared_node_pool
+         <sizeof(T), NodesPerBlock> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      singleton_t::instance().deallocate_free_blocks();
+   }
+
+   pointer allocation_command
+      (allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+      if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
+         boost::container::throw_bad_alloc();
+      return ret;
+   }
+
+   //!Returns maximum the number of objects the previously allocated memory
+   //!pointed by p can hold.
+   size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      return dlmalloc_size(p);
+   }
+
+   //!Allocates just one object. Memory allocated with this function
+   //!must be deallocated only with deallocate_one().
+   //!Throws bad_alloc if there is no enough memory
+   pointer allocate_one()
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      typedef dtl::shared_node_pool
+         <sizeof(T), NodesPerBlock> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      return (pointer)singleton_t::instance().allocate_node();
+   }
+
+   //!Allocates many elements of size == 1.
+   //!Elements must be individually deallocated with deallocate_one()
+   void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      typedef dtl::shared_node_pool
+         <sizeof(T), NodesPerBlock> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      typename shared_pool_t::multiallocation_chain ch;
+      singleton_t::instance().allocate_nodes(num_elements, ch);
+      chain.incorporate_after(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
+   }
+
+   //!Deallocates memory previously allocated with allocate_one().
+   //!You should never use deallocate_one to deallocate memory allocated
+   //!with other functions different from allocate_one(). Never throws
+   void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      typedef dtl::shared_node_pool
+         <sizeof(T), NodesPerBlock> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      singleton_t::instance().deallocate_node(p);
+   }
+
+   void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      typedef dtl::shared_node_pool
+         <sizeof(T), NodesPerBlock> shared_pool_t;
+      typedef dtl::singleton_default<shared_pool_t> singleton_t;
+      typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
+      singleton_t::instance().deallocate_nodes(ch);
+   }
+
+   //!Allocates many elements of size elem_size.
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
+      if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after( chain.before_begin()
+                             , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             , BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
+   }
+
+   //!Allocates n_elements elements, each one of size elem_sizes[i]
+   //!Elements must be individually deallocated with deallocate()
+   void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      dlmalloc_memchain ch;
+      dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
+      if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){
+         boost::container::throw_bad_alloc();
+      }
+      chain.incorporate_after( chain.before_begin()
+                             , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             , (T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
+                             , BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
+   }
+
+   void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_STATIC_ASSERT(( Version > 1 ));
+      void *first = &*chain.begin();
+      void *last  = &*chain.last();
+      size_t num  = chain.size();
+      dlmalloc_memchain ch;
+      BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, first, last, num);
+      dlmalloc_multidealloc(&ch);
+   }
+
+   //!Swaps allocators. Does not throw. If each allocator is placed in a
+   //!different memory segment, the result is undefined.
+   friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //!An allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator==(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;   }
+
+   //!An allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;   }
+
+   private:
+   pointer priv_allocation_command
+      (allocation_type command,   std::size_t limit_size
+      ,size_type &prefer_in_recvd_out_size
+      ,pointer &reuse)
+   {
+      std::size_t const preferred_size = prefer_in_recvd_out_size;
+      dlmalloc_command_ret_t ret = {0 , 0};
+      if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
+         return pointer();
+      }
+      std::size_t l_size = limit_size*sizeof(T);
+      std::size_t p_size = preferred_size*sizeof(T);
+      std::size_t r_size;
+      {
+         void* reuse_ptr_void = reuse;
+         ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+         reuse = static_cast<T*>(reuse_ptr_void);
+      }
+      prefer_in_recvd_out_size = r_size/sizeof(T);
+      return (pointer)ret.first;
+   }
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
diff --git a/include/boost/container/node_handle.hpp b/include/boost/container/node_handle.hpp
new file mode 100644
index 0000000..ef1d71f
--- /dev/null
+++ b/include/boost/container/node_handle.hpp
@@ -0,0 +1,443 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2016-2016. 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_NODE_HANDLE_HPP
+#define BOOST_CONTAINER_NODE_HANDLE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/container/detail/placement_new.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/mpl.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+
+#include <boost/type_traits/aligned_storage.hpp>
+
+
+//!\file
+
+namespace boost {
+namespace container {
+
+///@cond
+
+template<class Value, class KeyMapped>
+struct node_handle_keymapped_traits
+{
+   typedef typename KeyMapped::key_type      key_type;
+   typedef typename KeyMapped::mapped_type   mapped_type;
+};
+
+template<class Value>
+struct node_handle_keymapped_traits<Value, void>
+{
+   typedef Value key_type;
+   typedef Value mapped_type;
+};
+
+class node_handle_friend
+{
+   public:
+
+   template<class NH>
+   BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT
+   {  nh.destroy_alloc();  }
+
+   template<class NH>
+   BOOST_CONTAINER_FORCEINLINE static typename NH::node_pointer &get_node_pointer(NH &nh) BOOST_NOEXCEPT
+   {  return nh.get_node_pointer();  }
+};
+
+
+///@endcond
+
+//! A node_handle is an object that accepts ownership of a single element from an associative container.
+//! It may be used to transfer that ownership to another container with compatible nodes. Containers
+//! with compatible nodes have the same node handle type. Elements may be transferred in either direction
+//! between container types in the same row:.
+//!
+//! Container types with compatible nodes
+//!
+//! map<K, T, C1, A> <-> map<K, T, C2, A>
+//!
+//! map<K, T, C1, A> <-> multimap<K, T, C2, A>
+//! 
+//! set<K, C1, A> <-> set<K, C2, A>
+//! 
+//! set<K, C1, A> <-> multiset<K, C2, A>
+//! 
+//! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container
+//! when the element was extracted. If a node handle is empty, it contains no allocator.
+template <class NodeAllocator, class KeyMapped = void>
+class node_handle
+{
+   typedef NodeAllocator                                          nallocator_type;
+   typedef allocator_traits<NodeAllocator>                        nator_traits;
+   typedef typename nator_traits::value_type                      priv_node_t;
+   typedef typename priv_node_t::value_type                       priv_value_t;
+   typedef node_handle_keymapped_traits<priv_value_t, KeyMapped>  keymapped_t;
+
+   public:
+   typedef priv_value_t                                           value_type;
+   typedef typename keymapped_t::key_type                         key_type;
+   typedef typename keymapped_t::mapped_type                      mapped_type;
+   typedef typename nator_traits::template portable_rebind_alloc
+      <value_type>::type                                          allocator_type;
+
+   typedef priv_node_t                                            container_node_type;
+   friend class node_handle_friend;
+
+   ///@cond
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
+
+   typedef typename nator_traits::pointer                         node_pointer;
+   typedef ::boost::aligned_storage
+      < sizeof(nallocator_type)
+      , boost::alignment_of<nallocator_type>::value>              nalloc_storage_t;
+
+   node_pointer      m_ptr;
+   nalloc_storage_t  m_nalloc_storage;
+
+   void move_construct_alloc(nallocator_type &al)
+   {  ::new(m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(al));   }
+
+   void destroy_deallocate_node()
+   {
+      nator_traits::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(m_ptr));
+      nator_traits::deallocate(this->node_alloc(), m_ptr, 1u);
+   }
+
+   template<class OtherNodeHandle>
+   void move_construct_end(OtherNodeHandle &nh)
+   {
+      if(m_ptr){
+         ::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(nh.node_alloc()));
+         node_handle_friend::destroy_alloc(nh);
+         node_handle_friend::get_node_pointer(nh) = node_pointer();
+      }
+      BOOST_ASSERT(nh.empty());
+   }
+
+   void destroy_alloc() BOOST_NOEXCEPT
+   {  static_cast<nallocator_type*>(m_nalloc_storage.address())->~nallocator_type();  }
+
+   node_pointer &get_node_pointer() BOOST_NOEXCEPT
+   {  return m_ptr;  }
+
+   ///@endcond
+
+   public:
+   //! <b>Effects</b>: Initializes m_ptr to nullptr.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT
+      :  m_ptr()
+   { }
+
+   //! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with p.
+   //!   If p != nullptr copy constructs internal allocator from al.
+   node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT
+      :  m_ptr(p)
+   {
+      if(m_ptr){
+         ::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(al);
+      }
+   }
+
+   //! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with a related nh's internal pointer
+   //!   and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
+   //!   allocator with nh's internal allocator and destroy nh's internal allocator.
+   //!
+   //! <b>Postcondition</b>: nh.empty()
+   //!
+   //! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
+   //!   of a node handle is void.
+   template<class KeyMapped2>
+   node_handle( BOOST_RV_REF_BEG node_handle<NodeAllocator, KeyMapped2> BOOST_RV_REF_END nh
+               , typename dtl::enable_if_c
+                  < ((unsigned)dtl::is_same<KeyMapped,  void>::value +
+                     (unsigned)dtl::is_same<KeyMapped2, void>::value) == 1u
+                  >::type* = 0) BOOST_NOEXCEPT
+      :  m_ptr(nh.get())
+   {  this->move_construct_end(nh);  }
+
+   //! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
+   //!   and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
+   //!   allocator with nh's internal allocator and destroy nh's internal allocator.
+   //!
+   //! <b>Postcondition</b>: nh.empty()
+   node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
+      : m_ptr(nh.m_ptr)
+   {  this->move_construct_end(nh);  }
+
+   //! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
+   //!   pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
+   //!   nator_traits::rebind_traits<container_node_type>::deallocate.
+   ~node_handle() BOOST_NOEXCEPT
+   {
+      if(!this->empty()){
+         this->destroy_deallocate_node();
+         this->destroy_alloc();
+      }
+   }
+
+   //! <b>Requires</b>: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or
+   //!   node_alloc() == nh.node_alloc().
+   //!
+   //! <b>Effects</b>: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object
+   //!   pointed to by m_ptr by calling nator_traits::destroy, then deallocates m_ptr by calling
+   //!   nator_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
+   //!   or nator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
+   //!   node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc().
+   //!
+   //! <b>Returns</b>: *this.
+   //!
+   //! <b>Throws</b>: Nothing.
+   node_handle & operator=(BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
+   {
+      BOOST_ASSERT(this->empty() || nator_traits::propagate_on_container_move_assignment::value 
+                   || nator_traits::equal(node_alloc(), nh.node_alloc()));
+
+      bool const was_this_non_null = !this->empty();
+      bool const was_nh_non_null   = !nh.empty();
+
+      if(was_nh_non_null){
+         if(was_this_non_null){
+            this->destroy_deallocate_node();
+            if(nator_traits::propagate_on_container_move_assignment::value){
+               this->node_alloc() = ::boost::move(nh.node_alloc());
+            }
+         }
+         else{
+            this->move_construct_alloc(nh.node_alloc());
+         }
+         m_ptr = nh.m_ptr;
+         nh.m_ptr = node_pointer();
+         nh.destroy_alloc();
+      }
+      else if(was_this_non_null){
+         this->destroy_deallocate_node();
+         this->destroy_alloc();
+         m_ptr = node_pointer();
+      }
+      return *this;
+   }
+
+   //! <b>Requires</b>: empty() == false.
+   //!
+   //! <b>Returns</b>: A reference to the value_type subobject in the container_node_type object pointed to by m_ptr
+   //!
+   //! <b>Throws</b>: Nothing.
+   value_type& value() const BOOST_NOEXCEPT
+   {
+      BOOST_STATIC_ASSERT((dtl::is_same<KeyMapped, void>::value));
+      BOOST_ASSERT(!empty());
+      return m_ptr->get_data();
+   }
+
+   //! <b>Requires</b>: empty() == false.
+   //!
+   //! <b>Returns</b>: A non-const reference to the key_type member of the value_type subobject in the 
+   //!   container_node_type object pointed to by m_ptr.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Requires</b>: Modifying the key through the returned reference is permitted.
+   key_type& key() const BOOST_NOEXCEPT
+   {
+      BOOST_STATIC_ASSERT((!dtl::is_same<KeyMapped, void>::value));
+      BOOST_ASSERT(!empty());
+      return const_cast<key_type &>(KeyMapped().key_of_value(m_ptr->get_data()));
+   }
+
+   //! <b>Requires</b>: empty() == false.
+   //!
+   //! <b>Returns</b>: A reference to the mapped_type member of the value_type subobject
+   //!   in the container_node_type object pointed to by m_ptr
+   //!
+   //! <b>Throws</b>: Nothing.
+   mapped_type& mapped() const BOOST_NOEXCEPT
+   {
+      BOOST_STATIC_ASSERT((!dtl::is_same<KeyMapped, void>::value));
+      BOOST_ASSERT(!empty());
+      return KeyMapped().mapped_of_value(m_ptr->get_data());
+   }
+
+   //! <b>Requires</b>: empty() == false.
+   //!
+   //! <b>Returns</b>: A copy of the internally hold allocator.
+   //!
+   //! <b>Throws</b>: Nothing.
+   allocator_type get_allocator() const
+   {
+      BOOST_ASSERT(!empty());
+      return this->node_alloc();
+   }
+
+   //! <b>Returns</b>: m_ptr != nullptr.
+   //!
+   #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+   BOOST_CONTAINER_FORCEINLINE explicit operator bool
+   #else
+   private: struct bool_conversion {int for_bool; int for_arg(); }; typedef int bool_conversion::* explicit_bool_arg;
+   public: BOOST_CONTAINER_FORCEINLINE operator explicit_bool_arg
+   #endif
+      ()const BOOST_NOEXCEPT
+   {  return m_ptr ? &bool_conversion::for_bool  : explicit_bool_arg(0);  }
+
+   //! <b>Returns</b>: m_ptr == nullptr.
+   //!
+   bool empty() const BOOST_NOEXCEPT
+   {
+      return !this->m_ptr;
+   }
+
+   //! <b>Requires</b>: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or
+   //!   node_alloc() == nh.node_alloc().
+   //!
+   //! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or nator_traits::propagate_on_-
+   //!   container_swap is true calls swap(node_alloc(), nh.node_alloc()).
+   void swap(node_handle &nh)
+      BOOST_NOEXCEPT_IF(nator_traits::propagate_on_container_swap::value || nator_traits::is_always_equal::value)
+   {
+      BOOST_ASSERT(this->empty() || nh.empty() || nator_traits::propagate_on_container_swap::value
+                   || nator_traits::equal(node_alloc(), nh.node_alloc()));
+
+      bool const was_this_non_null = !this->empty();
+      bool const was_nh_non_null   = !nh.empty();
+
+      if(was_nh_non_null){
+         if(was_this_non_null){
+            if(nator_traits::propagate_on_container_swap::value){
+               ::boost::adl_move_swap(this->node_alloc(), nh.node_alloc());
+            }
+         }
+         else{
+            this->move_construct_alloc(nh.node_alloc());
+            nh.destroy_alloc();
+         }
+      }
+      else if(was_this_non_null){
+         nh.move_construct_alloc(this->node_alloc());
+         this->destroy_alloc();
+      }
+      ::boost::adl_move_swap(m_ptr, nh.m_ptr);
+   }
+
+   //! <b>Effects</b>: If this->empty() returns nullptr, otherwise returns m_ptr
+   //!   resets m_ptr to nullptr and destroys the internal allocator.
+   //!
+   //! <b>Postcondition</b>: this->empty()
+   //!
+   //! <b>Note</b>: Non-standard extensions
+   node_pointer release() BOOST_NOEXCEPT
+   {
+      node_pointer p(m_ptr);
+      m_ptr = node_pointer();
+      if(p)
+         this->destroy_alloc();
+      return p;
+   }
+
+   //! <b>Effects</b>: Returns m_ptr.
+   //!
+   //! <b>Note</b>: Non-standard extensions
+   node_pointer get() const BOOST_NOEXCEPT
+   {
+      return m_ptr;
+   }
+
+   //! <b>Effects</b>: Returns a reference to the internal node allocator.
+   //!
+   //! <b>Note</b>: Non-standard extensions
+   nallocator_type &node_alloc() BOOST_NOEXCEPT
+   {
+      BOOST_ASSERT(!empty());
+      return *static_cast<nallocator_type*>(m_nalloc_storage.address());
+   }
+
+
+   //! <b>Effects</b>: Returns a reference to the internal node allocator.
+   //!
+   //! <b>Note</b>: Non-standard extensions
+   const nallocator_type &node_alloc() const BOOST_NOEXCEPT
+   {
+      BOOST_ASSERT(!empty());
+      return *static_cast<const nallocator_type*>(m_nalloc_storage.address());
+   }
+
+   //! <b>Effects</b>: x.swap(y).
+   //!
+   friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
+   {  x.swap(y);  }
+};
+
+//! A class template used to describe the results of inserting a
+//! Container::node_type in a Container with unique keys.
+//! Includes at least the following non-static public data members:
+//!
+//! <ul><li>bool inserted</li>;
+//! <li>Iterator position</li>;
+//! <li>NodeType node</li></ul>
+//!
+//! This type is MoveConstructible, MoveAssignable, DefaultConstructible,
+//! Destructible, and lvalues of that type are swappable
+template<class Iterator, class NodeType>
+struct insert_return_type_base
+{
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_base)
+
+   public:
+   insert_return_type_base()
+      : inserted(false), position(), node()
+   {}
+
+   insert_return_type_base(BOOST_RV_REF(insert_return_type_base) other)
+      : inserted(other.inserted), position(other.position), node(boost::move(other.node))
+   {}
+
+   template<class RelatedIt, class RelatedNode>
+   insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) node)
+      : inserted(insert), position(it), node(boost::move(node))
+   {}
+
+   insert_return_type_base & operator=(BOOST_RV_REF(insert_return_type_base) other)
+   {
+      inserted = other.inserted;
+      position = other.position;
+      node = boost::move(other.node);
+      return *this;
+   }
+
+   bool  inserted;
+   Iterator position;
+   NodeType node;
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_NODE_HANDLE_HPP
diff --git a/include/boost/container/options.hpp b/include/boost/container/options.hpp
new file mode 100644
index 0000000..2ac7783
--- /dev/null
+++ b/include/boost/container/options.hpp
@@ -0,0 +1,245 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2013-2013
+//
+// 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_OPTIONS_HPP
+#define BOOST_CONTAINER_OPTIONS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/intrusive/pack_options.hpp>
+
+namespace boost {
+namespace container {
+
+////////////////////////////////////////////////////////////////
+//
+//
+//       OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS
+//
+//
+////////////////////////////////////////////////////////////////
+
+//! Enumeration used to configure ordered associative containers
+//! with a concrete tree implementation.
+enum tree_type_enum
+{
+   red_black_tree,
+   avl_tree,
+   scapegoat_tree,
+   splay_tree
+};
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template<tree_type_enum TreeType, bool OptimizeSize>
+struct tree_opt
+{
+   static const boost::container::tree_type_enum tree_type = TreeType;
+   static const bool optimize_size = OptimizeSize;
+};
+
+typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
+
+#endif   //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+//!This option setter specifies the underlying tree type
+//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
+BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
+
+//!This option setter specifies if node size is optimized
+//!storing rebalancing data masked into pointers for ordered associative containers
+BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
+
+//! Helper metafunction to combine options into a single type to be used
+//! by \c boost::container::set, \c boost::container::multiset
+//! \c boost::container::map and \c boost::container::multimap.
+//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
+#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
+template<class ...Options>
+#else
+template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
+#endif
+struct tree_assoc_options
+{
+   /// @cond
+   typedef typename ::boost::intrusive::pack_options
+      < tree_assoc_defaults,
+      #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
+      O1, O2, O3, O4
+      #else
+      Options...
+      #endif
+      >::type packed_options;
+   typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+
+//! Helper alias metafunction to combine options into a single type to be used
+//! by tree-based associative containers
+template<class ...Options>
+using tree_assoc_options_t = typename boost::container::tree_assoc_options<Options...>::type;
+
+#endif
+
+////////////////////////////////////////////////////////////////
+//
+//
+//          OPTIONS FOR VECTOR-BASED CONTAINERS
+//
+//
+////////////////////////////////////////////////////////////////
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template<class AllocTraits, class StoredSizeType>
+struct get_stored_size_type_with_alloctraits
+{
+   typedef StoredSizeType type;
+};
+
+template<class AllocTraits>
+struct get_stored_size_type_with_alloctraits<AllocTraits, void>
+{
+   typedef typename AllocTraits::size_type type;
+};
+
+template<class GrowthType, class StoredSizeType>
+struct vector_opt
+{
+   typedef GrowthType      growth_factor_type;
+   typedef StoredSizeType  stored_size_type;
+
+   template<class AllocTraits>
+   struct get_stored_size_type
+      : get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
+   {};
+};
+
+class default_next_capacity;
+
+typedef vector_opt<void, void> vector_null_opt;
+
+#else    //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+//!This growth factor argument specifies that the container should increase it's
+//!capacity a 50% when existing capacity is exhausted.
+struct growth_factor_50{};
+
+//!This growth factor argument specifies that the container should increase it's
+//!capacity a 60% when existing capacity is exhausted.
+struct growth_factor_60{};
+
+//!This growth factor argument specifies that the container should increase it's
+//!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
+struct growth_factor_100{};
+
+#endif   //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+//!This option setter specifies the growth factor strategy of the underlying vector.
+//!
+//!\tparam GrowthFactor A function object that has the following signature:<br/><br/>
+//!`template<class SizeType>`<br/>
+//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.<br/><br/>
+//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity
+//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other 
+//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap`
+//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound,
+//! but the implementation should handle wraparound produced by the growth factor.
+//!
+//!Predefined growth factors that can be passed as arguments to this option are:
+//!\c boost::container::growth_factor_50
+//!\c boost::container::growth_factor_60
+//!\c boost::container::growth_factor_100
+//!
+//!If this option is not specified, a default will be used by the container.
+BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type)
+
+//!This option specifies the unsigned integer type that a user wants the container
+//!to use to hold size-related information inside a container (e.g. current size, current capacity).
+//!
+//!\tparam StoredSizeType A unsigned integer type. It shall be smaller than than the size
+//! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
+//!
+//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit 
+//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
+//!memory can be saved for empty vectors. This could potentially performance benefits due to better
+//!cache usage.
+//!
+//!Note that alignment requirements can disallow theoritical space savings. Example:
+//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
+//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes) 
+//!will not save space when comparing two 16-bit size types because usually
+//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
+//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
+//!Measure the size of the resulting container and do not assume a smaller \c stored_size
+//!will always lead to a smaller sizeof(container).
+//!
+//!If a user tries to insert more elements than representable by \c stored_size, vector
+//!will throw a length_error.
+//!
+//!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
+//!be used to store size-related information inside the container.
+BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type)
+
+//! Helper metafunction to combine options into a single type to be used
+//! by \c boost::container::vector.
+//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
+#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
+template<class ...Options>
+#else
+template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
+#endif
+struct vector_options
+{
+   /// @cond
+   typedef typename ::boost::intrusive::pack_options
+      < vector_null_opt,
+      #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
+      O1, O2, O3, O4
+      #else
+      Options...
+      #endif
+      >::type packed_options;
+   typedef vector_opt< typename packed_options::growth_factor_type
+                     , typename packed_options::stored_size_type> implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+
+//! Helper alias metafunction to combine options into a single type to be used
+//! by \c boost::container::vector.
+//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
+template<class ...Options>
+using vector_options_t = typename boost::container::vector_options<Options...>::type;
+
+#endif
+
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_CONTAINER_OPTIONS_HPP
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
diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp
new file mode 100644
index 0000000..6cd69fe
--- /dev/null
+++ b/include/boost/container/scoped_allocator.hpp
@@ -0,0 +1,907 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2013. 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_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+
+#if defined (_MSC_VER)
+#  pragma once 
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/scoped_allocator_fwd.hpp>
+#include <boost/container/detail/dispatch_uses_allocator.hpp>
+
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <boost/move/adl_move_swap.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/utility_core.hpp>
+
+#include <boost/core/no_exceptions_support.hpp>
+
+namespace boost { namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace dtl {
+
+template <typename Allocator>
+struct is_scoped_allocator_imp
+{
+   typedef char yes_type;
+   struct no_type{ char dummy[2]; };
+
+   template <typename T>
+   static yes_type test(typename T::outer_allocator_type*);
+
+   template <typename T>
+   static int test(...);
+
+   static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
+};
+
+template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
+struct outermost_allocator_type_impl
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl<outer_type>::type type;
+};
+
+template<class MaybeScopedAlloc>
+struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
+{
+   typedef MaybeScopedAlloc type;
+};
+
+template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
+struct outermost_allocator_imp
+{
+   typedef MaybeScopedAlloc type;
+
+   static type &get(MaybeScopedAlloc &a)
+   {  return a;  }
+
+   static const type &get(const MaybeScopedAlloc &a)
+   {  return a;  }
+};
+
+template<class MaybeScopedAlloc>
+struct outermost_allocator_imp<MaybeScopedAlloc, true>
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl<outer_type>::type type;
+
+   static type &get(MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp<outer_type>::get(a.outer_allocator());  }
+
+   static const type &get(const MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp<outer_type>::get(a.outer_allocator());  }
+};
+
+}  //namespace dtl {
+
+template <typename Allocator>
+struct is_scoped_allocator
+   : dtl::is_scoped_allocator_imp<Allocator>
+{};
+
+template <typename Allocator>
+struct outermost_allocator
+   : dtl::outermost_allocator_imp<Allocator>
+{};
+
+template <typename Allocator>
+typename outermost_allocator<Allocator>::type &
+   get_outermost_allocator(Allocator &a)
+{  return outermost_allocator<Allocator>::get(a);   }
+
+template <typename Allocator>
+const typename outermost_allocator<Allocator>::type &
+   get_outermost_allocator(const Allocator &a)
+{  return outermost_allocator<Allocator>::get(a);   }
+
+namespace dtl {
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template <typename OuterAlloc, class ...InnerAllocs>
+class scoped_allocator_adaptor_base
+   : public OuterAlloc
+{
+   typedef allocator_traits<OuterAlloc> outer_traits_type;
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
+
+   public:
+   template <class OuterA2>
+   struct rebind_base
+   {
+      typedef scoped_allocator_adaptor_base<OuterA2, InnerAllocs...> other;
+   };
+
+   typedef OuterAlloc outer_allocator_type;
+   typedef scoped_allocator_adaptor<InnerAllocs...>   inner_allocator_type;
+   typedef allocator_traits<inner_allocator_type>     inner_traits_type;
+   typedef scoped_allocator_adaptor
+      <OuterAlloc, InnerAllocs...>                    scoped_allocator_type;
+   typedef dtl::bool_<
+      outer_traits_type::propagate_on_container_copy_assignment::value ||
+      inner_allocator_type::propagate_on_container_copy_assignment::value
+      > propagate_on_container_copy_assignment;
+   typedef dtl::bool_<
+      outer_traits_type::propagate_on_container_move_assignment::value ||
+      inner_allocator_type::propagate_on_container_move_assignment::value
+      > propagate_on_container_move_assignment;
+   typedef dtl::bool_<
+      outer_traits_type::propagate_on_container_swap::value ||
+      inner_allocator_type::propagate_on_container_swap::value
+      > propagate_on_container_swap;
+   typedef dtl::bool_<
+      outer_traits_type::is_always_equal::value &&
+      inner_allocator_type::is_always_equal::value
+      > is_always_equal;
+
+   scoped_allocator_adaptor_base()
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      , m_inner(args...)
+      {}
+
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
+      : outer_allocator_type(other.outer_allocator())
+      , m_inner(other.inner_allocator())
+      {}
+
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+      : outer_allocator_type(::boost::move(other.outer_allocator()))
+      , m_inner(::boost::move(other.inner_allocator()))
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
+      : outer_allocator_type(other.outer_allocator())
+      , m_inner(other.inner_allocator())
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base
+         <OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
+      : outer_allocator_type(other.outer_allocator())
+      , m_inner(other.inner_allocator())
+      {}
+
+   public:
+   struct internal_type_t{};
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      ( internal_type_t
+      , BOOST_FWD_REF(OuterA2) outerAlloc
+      , const inner_allocator_type &inner)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      , m_inner(inner)
+   {}
+
+   public:
+
+   scoped_allocator_adaptor_base &operator=
+      (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(other.outer_allocator());
+      m_inner = other.inner_allocator();
+      return *this;
+   }
+
+   scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(boost::move(other.outer_allocator()));
+      m_inner = ::boost::move(other.inner_allocator());
+      return *this;
+   }
+
+   void swap(scoped_allocator_adaptor_base &r)
+   {
+      boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
+      boost::adl_move_swap(this->m_inner, r.inner_allocator());
+   }
+
+   friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
+   {  l.swap(r);  }
+
+   inner_allocator_type&       inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_inner; }
+
+   inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return m_inner; }
+
+   outer_allocator_type      & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+      { return static_cast<outer_allocator_type&>(*this); }
+
+   const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+      { return static_cast<const outer_allocator_type&>(*this); }
+
+   scoped_allocator_type select_on_container_copy_construction() const
+   {
+      return scoped_allocator_type
+         (internal_type_t()
+         ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
+         ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
+         );
+   }
+
+   private:
+   inner_allocator_type m_inner;
+};
+
+#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+//Let's add a dummy first template parameter to allow creating
+//specializations up to maximum InnerAlloc count
+template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
+class scoped_allocator_adaptor_base;
+
+//Specializations for the adaptor with InnerAlloc allocators
+
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
+template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
+   : public OuterAlloc\
+{\
+   typedef allocator_traits<OuterAlloc> outer_traits_type;\
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
+   \
+   public:\
+   template <class OuterA2>\
+   struct rebind_base\
+   {\
+      typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
+   };\
+   \
+   typedef OuterAlloc outer_allocator_type;\
+   typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
+   typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
+   typedef allocator_traits<inner_allocator_type> inner_traits_type;\
+   typedef dtl::bool_<\
+      outer_traits_type::propagate_on_container_copy_assignment::value ||\
+      inner_allocator_type::propagate_on_container_copy_assignment::value\
+      > propagate_on_container_copy_assignment;\
+   typedef dtl::bool_<\
+      outer_traits_type::propagate_on_container_move_assignment::value ||\
+      inner_allocator_type::propagate_on_container_move_assignment::value\
+      > propagate_on_container_move_assignment;\
+   typedef dtl::bool_<\
+      outer_traits_type::propagate_on_container_swap::value ||\
+      inner_allocator_type::propagate_on_container_swap::value\
+      > propagate_on_container_swap;\
+   \
+   typedef dtl::bool_<\
+      outer_traits_type::is_always_equal::value &&\
+      inner_allocator_type::is_always_equal::value\
+      > is_always_equal;\
+   \
+   scoped_allocator_adaptor_base(){}\
+   \
+   template <class OuterA2>\
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
+      , m_inner(BOOST_MOVE_ARG##N)\
+      {}\
+   \
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
+      : outer_allocator_type(other.outer_allocator())\
+      , m_inner(other.inner_allocator())\
+      {}\
+   \
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
+      : outer_allocator_type(::boost::move(other.outer_allocator()))\
+      , m_inner(::boost::move(other.inner_allocator()))\
+      {}\
+   \
+   template <class OuterA2>\
+   scoped_allocator_adaptor_base\
+      (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
+      : outer_allocator_type(other.outer_allocator())\
+      , m_inner(other.inner_allocator())\
+      {}\
+   \
+   template <class OuterA2>\
+   scoped_allocator_adaptor_base\
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
+      : outer_allocator_type(other.outer_allocator())\
+      , m_inner(other.inner_allocator())\
+      {}\
+   \
+   public:\
+   struct internal_type_t{};\
+   \
+   template <class OuterA2>\
+   scoped_allocator_adaptor_base\
+      ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
+      , m_inner(inner)\
+   {}\
+   \
+   public:\
+   scoped_allocator_adaptor_base &operator=\
+      (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
+   {\
+      outer_allocator_type::operator=(other.outer_allocator());\
+      m_inner = other.inner_allocator();\
+      return *this;\
+   }\
+   \
+   scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
+   {\
+      outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
+      m_inner = ::boost::move(other.inner_allocator());\
+      return *this;\
+   }\
+   \
+   void swap(scoped_allocator_adaptor_base &r)\
+   {\
+      boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
+      boost::adl_move_swap(this->m_inner, r.inner_allocator());\
+   }\
+   \
+   friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
+   {  l.swap(r);  }\
+   \
+   inner_allocator_type&       inner_allocator()\
+      { return m_inner; }\
+   \
+   inner_allocator_type const& inner_allocator() const\
+      { return m_inner; }\
+   \
+   outer_allocator_type      & outer_allocator()\
+      { return static_cast<outer_allocator_type&>(*this); }\
+   \
+   const outer_allocator_type &outer_allocator() const\
+      { return static_cast<const outer_allocator_type&>(*this); }\
+   \
+   scoped_allocator_type select_on_container_copy_construction() const\
+   {\
+      return scoped_allocator_type\
+         (internal_type_t()\
+         ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
+         ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
+         );\
+   }\
+   private:\
+   inner_allocator_type m_inner;\
+};\
+//!
+BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
+
+#endif   //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE      ,true
+   #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER       BOOST_MOVE_TARG9
+   #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS  BOOST_MOVE_CLASS9
+#else
+   #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
+   #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER       InnerAllocs...
+   #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS  typename... InnerAllocs
+#endif
+
+//Specialization for adaptor without any InnerAlloc
+template <typename OuterAlloc>
+class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
+   : public OuterAlloc
+{
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
+   public:
+
+   template <class U>
+   struct rebind_base
+   {
+      typedef scoped_allocator_adaptor_base
+         <typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
+         BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
+   };
+
+   typedef OuterAlloc                           outer_allocator_type;
+   typedef allocator_traits<OuterAlloc>         outer_traits_type;
+   typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
+   typedef inner_allocator_type                 scoped_allocator_type;
+   typedef allocator_traits<inner_allocator_type>   inner_traits_type;
+   typedef typename outer_traits_type::
+      propagate_on_container_copy_assignment    propagate_on_container_copy_assignment;
+   typedef typename outer_traits_type::
+      propagate_on_container_move_assignment    propagate_on_container_move_assignment;
+   typedef typename outer_traits_type::
+      propagate_on_container_swap               propagate_on_container_swap;
+   typedef typename outer_traits_type::
+      is_always_equal                           is_always_equal;
+
+   scoped_allocator_adaptor_base()
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      {}
+
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
+      : outer_allocator_type(other.outer_allocator())
+      {}
+
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+      : outer_allocator_type(::boost::move(other.outer_allocator()))
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
+      : outer_allocator_type(other.outer_allocator())
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
+      : outer_allocator_type(other.outer_allocator())
+      {}
+
+   public:
+   struct internal_type_t{};
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      {}
+
+   public:
+   scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(other.outer_allocator());
+      return *this;
+   }
+
+   scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(boost::move(other.outer_allocator()));
+      return *this;
+   }
+
+   void swap(scoped_allocator_adaptor_base &r)
+   {
+      boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
+   }
+
+   friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
+   {  l.swap(r);  }
+
+   inner_allocator_type&       inner_allocator()
+      { return static_cast<inner_allocator_type&>(*this); }
+
+   inner_allocator_type const& inner_allocator() const
+      { return static_cast<const inner_allocator_type&>(*this); }
+
+   outer_allocator_type      & outer_allocator()
+      { return static_cast<outer_allocator_type&>(*this); }
+
+   const outer_allocator_type &outer_allocator() const
+      { return static_cast<const outer_allocator_type&>(*this); }
+
+   scoped_allocator_type select_on_container_copy_construction() const
+   {
+      return scoped_allocator_type
+         (internal_type_t()
+         ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
+         //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
+         //as inner_allocator() is equal to *this and that would trigger an infinite loop
+         , this->inner_allocator()
+         );
+   }
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//Scoped allocator
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
+//! The class template scoped_allocator_adaptor is an allocator template that specifies
+//! the memory resource (the outer allocator) to be used by a container (as any other
+//! allocator does) and also specifies an inner allocator resource to be passed to
+//! the constructor of every element within the container.
+//!
+//! This adaptor is
+//! instantiated with one outer and zero or more inner allocator types. If
+//! instantiated with only one allocator type, the inner allocator becomes the
+//! scoped_allocator_adaptor itself, thus using the same allocator resource for the
+//! container and every element within the container and, if the elements themselves
+//! are containers, each of their elements recursively. If instantiated with more than
+//! one allocator, the first allocator is the outer allocator for use by the container,
+//! the second allocator is passed to the constructors of the container's elements,
+//! and, if the elements themselves are containers, the third allocator is passed to
+//! the elements' elements, and so on. If containers are nested to a depth greater
+//! than the number of allocators, the last allocator is used repeatedly, as in the
+//! single-allocator case, for any remaining recursions.
+//!
+//! [<b>Note</b>: The
+//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
+//! substituted for the outer allocator type in most expressions. -end note]
+//!
+//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
+//! an <code>outer_allocator()</code> member function and
+//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
+//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
+//!
+//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
+//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
+//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
+//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
+template <typename OuterAlloc, typename ...InnerAllocs>
+class scoped_allocator_adaptor
+
+#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+template <typename OuterAlloc, typename ...InnerAllocs>
+class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
+
+#endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template <typename OuterAlloc, BOOST_MOVE_CLASS9>
+class scoped_allocator_adaptor
+#endif
+
+   : public dtl::scoped_allocator_adaptor_base
+         <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
+{
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
+
+   public:
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef dtl::scoped_allocator_adaptor_base
+      <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
+   typedef typename base_type::internal_type_t              internal_type_t;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef OuterAlloc                                       outer_allocator_type;
+   //! Type: For exposition only
+   //!
+   typedef allocator_traits<OuterAlloc>                     outer_traits_type;
+   //! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
+   //! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
+   typedef typename base_type::inner_allocator_type         inner_allocator_type;
+   typedef allocator_traits<inner_allocator_type>           inner_traits_type;
+   typedef typename outer_traits_type::value_type           value_type;
+   typedef typename outer_traits_type::size_type            size_type;
+   typedef typename outer_traits_type::difference_type      difference_type;
+   typedef typename outer_traits_type::pointer              pointer;
+   typedef typename outer_traits_type::const_pointer        const_pointer;
+   typedef typename outer_traits_type::void_pointer         void_pointer;
+   typedef typename outer_traits_type::const_void_pointer   const_void_pointer;
+   //! Type: A type with a constant boolean <code>value</code> == true if
+   //!`allocator_traits<Allocator>:: propagate_on_container_copy_assignment::value` is
+   //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
+   typedef typename base_type::
+      propagate_on_container_copy_assignment                propagate_on_container_copy_assignment;
+   //! Type: A type with a constant boolean <code>value</code> == true if
+   //!`allocator_traits<Allocator>:: propagate_on_container_move_assignment::value` is
+   //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
+   typedef typename base_type::
+      propagate_on_container_move_assignment                propagate_on_container_move_assignment;
+
+   //! Type: A type with a constant boolean <code>value</code> == true if
+   //! `allocator_traits<Allocator>:: propagate_on_container_swap::value` is
+   //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
+   typedef typename base_type::
+      propagate_on_container_swap                           propagate_on_container_swap;
+
+   //! Type: A type with a constant boolean <code>value</code> == true if
+   //!`allocator_traits<Allocator>:: is_always_equal::value` is
+   //! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
+   typedef typename base_type::
+      is_always_equal                           is_always_equal;
+
+   //! Type: Rebinds scoped allocator to
+   //!    <code>typedef scoped_allocator_adaptor
+   //!      < typename outer_traits_type::template portable_rebind_alloc<U>::type
+   //!      , InnerAllocs... ></code>
+   template <class U>
+   struct rebind
+   {
+      typedef scoped_allocator_adaptor
+         < typename outer_traits_type::template portable_rebind_alloc<U>::type
+         , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
+   };
+
+   //! <b>Effects</b>: value-initializes the OuterAlloc base class
+   //! and the inner allocator object.
+   scoped_allocator_adaptor()
+      {}
+
+   ~scoped_allocator_adaptor()
+      {}
+
+   //! <b>Effects</b>: initializes each allocator within the adaptor with
+   //! the corresponding allocator from other.
+   scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
+      : base_type(other.base())
+      {}
+
+   //! <b>Effects</b>: move constructs each allocator within the adaptor with
+   //! the corresponding allocator from other.
+   scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
+      : base_type(::boost::move(other.base()))
+      {}
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
+   //!
+   //! <b>Effects</b>: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
+   //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
+   //! corresponding allocator from the argument list).
+   template <class OuterA2>
+   scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
+      : base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
+      {}
+   #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
+   template <class OuterA2>\
+   scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
+      : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
+      {}\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
+   #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
+
+   #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
+   //!
+   //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
+   template <class OuterA2>
+   scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
+      : base_type(other.base())
+      {}
+
+   //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
+   //!
+   //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
+   //! rvalue from other.
+   template <class OuterA2>
+   scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
+      <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
+      : base_type(::boost::move(other.base()))
+      {}
+
+   scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
+   {  return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
+
+   scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
+   {  return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
+
+   #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+   //! <b>Effects</b>: swaps *this with r.
+   //!
+   void swap(scoped_allocator_adaptor &r);
+
+   //! <b>Effects</b>: swaps *this with r.
+   //!
+   friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
+
+   //! <b>Returns</b>:
+   //!   <code>static_cast<OuterAlloc&>(*this)</code>.
+   outer_allocator_type      & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Returns</b>:
+   //!   <code>static_cast<const OuterAlloc&>(*this)</code>.
+   const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Returns</b>:
+   //!   *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
+   inner_allocator_type&       inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! <b>Returns</b>:
+   //!   *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
+   inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Returns</b>:
+   //!   <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return outer_traits_type::max_size(this->outer_allocator());   }
+
+   //! <b>Effects</b>:
+   //!   calls <code>OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p)</code>.
+   template <class T>
+   void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      allocator_traits<typename outermost_allocator<OuterAlloc>::type>
+         ::destroy(get_outermost_allocator(this->outer_allocator()), p);
+   }
+
+   //! <b>Returns</b>:
+   //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
+   pointer allocate(size_type n)
+   {  return outer_traits_type::allocate(this->outer_allocator(), n);   }
+
+   //! <b>Returns</b>:
+   //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
+   pointer allocate(size_type n, const_void_pointer hint)
+   {  return outer_traits_type::allocate(this->outer_allocator(), n, hint);   }
+
+   //! <b>Effects</b>:
+   //! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
+   void deallocate(pointer p, size_type n)
+   {  outer_traits_type::deallocate(this->outer_allocator(), p, n);  }
+
+   #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+   //! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
+   //! Allocator in the adaptor is initialized from the result of calling
+   //! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
+   //! the corresponding allocator in *this.
+   scoped_allocator_adaptor select_on_container_copy_construction() const;
+   #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   base_type &base()             { return *this; }
+
+   const base_type &base() const { return *this; }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>:
+   //! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
+   //!    <code>OUTERMOST_ALLOC_TRAITS(*this)::
+   //!       construct(OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
+   //!
+   //! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
+   //!    <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>:: value</code> is true, calls
+   //!    <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg,
+   //!    inner_allocator(), std::forward<Args>(args)...)</code>.
+   //!
+   //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
+   //! be implemented so that condition will be replaced by
+   //! constructible_with_allocator_prefix<T>::value. -end note]
+   //!
+   //! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
+   //!    <code>is_constructible<T, Args..., inner_allocator_type>:: value</code> is true, calls
+   //!    <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p,
+   //!    std::forward<Args>(args)..., inner_allocator())</code>.
+   //!
+   //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
+   //! implemented so that condition will be replaced by
+   //! <code>constructible_with_allocator_suffix<T>:: value</code>. -end note]
+   //!
+   //! 4) Otherwise, the program is ill-formed.
+   //!
+   //! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
+   //! to true but the specific constructor does not take an allocator. This definition prevents a silent
+   //! failure to pass an inner allocator to a contained element. -end note]
+   template < typename T, class ...Args>
+   void construct(T* p, BOOST_FWD_REF(Args)...args)
+   {
+      dtl::dispatch_uses_allocator
+         ( (get_outermost_allocator)(this->outer_allocator())
+         , this->inner_allocator(), 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_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
+   template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
+   void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
+   {\
+      dtl::dispatch_uses_allocator\
+         ( (get_outermost_allocator)(this->outer_allocator())\
+         , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
+   #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
+
+   #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //Internal function
+   template <class OuterA2>
+   scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
+      : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
+   {}
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+/// @cond
+
+template<bool ZeroInner>
+struct scoped_allocator_operator_equal
+{
+   //Optimize equal outer allocator types with 
+   //allocator_traits::equal which uses is_always_equal
+   template<class IA>
+   static bool equal_outer(const IA &l, const IA &r)
+   {  return allocator_traits<IA>::equal(l, r);  }
+
+   //Otherwise compare it normally
+   template<class IA1, class IA2>
+   static bool equal_outer(const IA1 &l, const IA2 &r)
+   {  return l == r;  }
+
+   //Otherwise compare it normally
+   template<class IA>
+   static bool equal_inner(const IA &l, const IA &r)
+   {  return allocator_traits<IA>::equal(l, r);  }
+};
+
+template<>
+struct scoped_allocator_operator_equal<true>
+   : scoped_allocator_operator_equal<false>
+{
+   //when inner allocator count is zero,
+   //inner_allocator_type is the same as outer_allocator_type
+   //so both types can be different in operator==
+   template<class IA1, class IA2>
+   static bool equal_inner(const IA1 &, const IA2 &)
+   {  return true;  }
+};
+
+/// @endcond
+
+template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
+inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
+                      ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
+{
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
+   #else
+   const bool has_zero_inner = boost::container::dtl::is_same<P0, void>::value;
+   #endif
+   typedef scoped_allocator_operator_equal<has_zero_inner> equal_t;
+   return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) &&
+          equal_t::equal_inner(a.inner_allocator(), b.inner_allocator());
+}
+
+template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
+inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
+                      ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
+{  return !(a == b);   }
+
+}} // namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
diff --git a/include/boost/container/scoped_allocator_fwd.hpp b/include/boost/container/scoped_allocator_fwd.hpp
new file mode 100644
index 0000000..cddf7fa
--- /dev/null
+++ b/include/boost/container/scoped_allocator_fwd.hpp
@@ -0,0 +1,71 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
+#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
+
+//! \file
+//! This header file forward declares boost::container::scoped_allocator_adaptor
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/std_fwd.hpp>
+#include <boost/container/uses_allocator_fwd.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+
+namespace boost { namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+      template <typename OuterAlloc, typename ...InnerAllocs>
+      class scoped_allocator_adaptor;
+
+   #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+      template <typename ...InnerAllocs>
+      class scoped_allocator_adaptor;
+
+      template <typename OuterAlloc, typename ...InnerAllocs>
+      class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
+
+   #endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+#else    // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <typename OuterAlloc, BOOST_MOVE_CLASSDFLT9>
+   class scoped_allocator_adaptor;
+
+#endif
+
+
+#else    //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}} // namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp
new file mode 100644
index 0000000..e300898
--- /dev/null
+++ b/include/boost/container/set.hpp
@@ -0,0 +1,1622 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. 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_SET_HPP
+#define BOOST_CONTAINER_SET_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/container_fwd.hpp>
+// container/detail
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/tree.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// move
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#include <boost/move/detail/move_helpers.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A set is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of the keys themselves.
+//! Class set supports bidirectional iterators.
+//!
+//! A set satisfies all of the requirements of a container and of a reversible container
+//! , and of an associative container. A set also provides most operations described in
+//! for unique keys.
+//!
+//! \tparam Key is the type to be inserted in the set, which is also the key_type
+//! \tparam Compare is the comparison functor used to order keys
+//! \tparam Allocator is the allocator to be used to allocate memory for this container
+//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = void>
+#else
+template <class Key, class Compare, class Allocator, class Options>
+#endif
+class set
+   ///@cond
+   : public dtl::tree
+      < Key, dtl::identity<Key>, Compare, Allocator, Options>
+   ///@endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(set)
+   typedef dtl::tree
+      < Key, dtl::identity<Key>, Compare, Allocator, Options> base_t;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                         key_type;
+   typedef Key                                                                         value_type;
+   typedef Compare                                                                     key_compare;
+   typedef Compare                                                                     value_compare;
+   typedef ::boost::container::allocator_traits<Allocator>                             allocator_traits_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)              stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                           iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                     const_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                   reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)             const_reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type)                          node_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type)                 insert_return_type;
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs an empty set.
+   //!
+   //! <b>Complexity</b>: Constant.
+   
+   BOOST_CONTAINER_FORCEINLINE set()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value &&
+                        dtl::is_nothrow_default_constructible<Compare>::value)
+      : base_t()
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified allocator object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit set(const allocator_type& a)
+      : base_t(a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE explicit set(const Compare& comp)
+      : base_t(comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object
+   //! and allocator.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE set(const Compare& comp, const allocator_type& a)
+      : base_t(comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last)
+      : base_t(true, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const allocator_type& a)
+      : base_t(true, first, last, key_compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(true, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! allocator, and inserts elements from the range [first ,last ).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+   //! the predicate and otherwise N logN, where N is last - first.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : base_t(true, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last)
+      : base_t(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp )
+      : base_t(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last
+      , const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs an empty set and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il)
+      : base_t(true, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const allocator_type& a)
+      : base_t(true, il.begin(), il.end(), Compare(), a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp )
+      : base_t(true, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! allocator, and inserts elements from the range [il.begin(), il.end()).
+   //!
+   //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+   //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+   BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(true, il.begin(), il.end(), comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il)
+      : base_t(ordered_range, il.begin(), il.end())
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(ordered_range, il.begin(), il.end(), comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+   //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+   //! unique values.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, il.begin(), il.end(), comp, a)
+   {}
+#endif
+
+   //! <b>Effects</b>: Copy constructs a set.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE set(const set& x)
+      : base_t(static_cast<const base_t&>(x))
+   {}
+
+   //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Postcondition</b>: x is emptied.
+   BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : base_t(BOOST_MOVE_BASE(base_t, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a set using the specified allocator.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE set(const set& x, const allocator_type &a)
+      : base_t(static_cast<const base_t&>(x), a)
+   {}
+
+   //! <b>Effects</b>: Move constructs a set using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x, const allocator_type &a)
+      : base_t(BOOST_MOVE_BASE(base_t, x), a)
+   {}
+
+   //! <b>Effects</b>: Makes *this a copy of x.
+   //!
+   //! <b>Complexity</b>: Linear in x.size().
+   BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
+   {  return static_cast<set&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
+
+   //! <b>Effects</b>: this->swap(x.get()).
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_RV_REF(set) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Copy all elements from il to *this.
+   //!
+   //! <b>Complexity</b>: Linear in il.size().
+   set& operator=(std::initializer_list<value_type> il)
+   {
+      this->clear();
+      insert(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Returns a copy of the allocator that
+   //!   was passed to the object's constructor.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const;
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator();
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const;
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant
+   iterator begin();
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const;
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const;
+
+   //! <b>Effects</b>: Returns an iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end();
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const;
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin();
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const;
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend();
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const;
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const;
+
+   //! <b>Effects</b>: Returns true if the container contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const;
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const;
+
+   //! <b>Effects</b>: Returns the largest possible size of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const;
+   #endif   //   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>:  Inserts an object x of type Key constructed with
+   //!   std::forward<Args>(args)... if and only if there is
+   //!   no element in the container with equivalent value.
+   //!   and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   Key's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>:  Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)... if and only if there is
+   //!   no element in the container with equivalent value.
+   //!   p is a hint pointing to where the insert
+   //!   should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_unique(BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_SET_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+   //!   with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   std::pair<iterator, bool> insert(const value_type &x);
+
+   //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!
+   //! <b>Returns</b>: The bool component of the returned pair is true if and only
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   std::pair<iterator, bool> insert(value_type &&x);
+   #else
+   private:
+   typedef std::pair<iterator, bool> insert_return_pair;
+   public:
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, const value_type &x);
+
+   //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator insert(const_iterator p, value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+   {  this->base_t::insert_unique(first, last);  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: inserts each element from the range [il.begin(),il.end()) if and only
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end())
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->base_t::insert_unique(il.begin(), il.end()); }
+#endif
+
+   //! @copydoc ::boost::container::map::insert(node_type&&)
+   BOOST_CONTAINER_FORCEINLINE insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {  return this->base_t::insert_unique_node(boost::move(nh));  }
+
+   //! @copydoc ::boost::container::map::insert(const_iterator, node_type&&)
+   BOOST_CONTAINER_FORCEINLINE insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {  return this->base_t::insert_unique_node(hint, boost::move(nh));  }
+
+   //! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t;
+      this->base_t::merge_unique(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::set::merge(set<Key, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source));   }
+
+   //! @copydoc ::boost::container::map::merge(multimap<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t;
+      this->base_t::merge_unique(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::set::merge(multiset<Key, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source));   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Erases the element pointed to by p.
+   //!
+   //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists,
+   //!   returns end().
+   //!
+   //! <b>Complexity</b>: Amortized constant time
+   iterator erase(const_iterator p);
+
+   //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+   //!
+   //! <b>Returns</b>: Returns the number of erased elements.
+   //!
+   //! <b>Complexity</b>: log(size()) + count(k)
+   size_type erase(const key_type& x);
+
+   //! <b>Effects</b>: Erases all the elements in the range [first, last).
+   //!
+   //! <b>Returns</b>: Returns last.
+   //!
+   //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last);
+
+   //! @copydoc ::boost::container::map::extract(const_iterator)
+   node_type extract(const_iterator p);
+
+   //! @copydoc ::boost::container::map::extract(const key_type&)
+   node_type extract(const key_type& x);
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(set& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
+
+   //! <b>Effects</b>: erase(a.begin(),a.end()).
+   //!
+   //! <b>Postcondition</b>: size() == 0.
+   //!
+   //! <b>Complexity</b>: linear in size().
+   void clear();
+
+   //! <b>Effects</b>: Returns the comparison object out
+   //!   of which a was constructed.
+   //!
+   //! <b>Complexity</b>: Constant.
+   key_compare key_comp() const;
+
+   //! <b>Effects</b>: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //!
+   //! <b>Complexity</b>: Constant.
+   value_compare value_comp() const;
+
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator find(const key_type& x);
+
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   const_iterator find(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   iterator find(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template<typename K>
+   const_iterator find(const K& x) const;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
+   {  return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend());  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   template<typename K>
+   BOOST_CONTAINER_FORCEINLINE size_type count(const K& x) const
+   {  return static_cast<size_type>(this->find(x) != this->cend());  }
+
+   //! <b>Returns</b>: The number of elements with key equivalent to x.
+   //!
+   //! <b>Complexity</b>: log(size())+count(k)
+   BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x)
+   {  return static_cast<size_type>(this->base_t::find(x) != this->base_t::end());  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator lower_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator lower_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator lower_bound(const K& x) const;
+
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   iterator upper_bound(const key_type& x);
+
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   iterator upper_bound(const K& x);
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Returns</b>: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   const_iterator upper_bound(const K& x) const;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
+   {  return this->base_t::lower_bound_range(x);  }
+
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+   {  return this->base_t::lower_bound_range(x);  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<iterator,iterator> equal_range(const K& x)
+   {  return this->base_t::lower_bound_range(x);  }
+
+   //! <b>Requires</b>: This overload is available only if
+   //! key_compare::is_transparent exists.
+   //!
+   //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! <b>Complexity</b>: Logarithmic
+   template<typename K>
+   std::pair<const_iterator,const_iterator> equal_range(const K& x) const
+   {  return this->base_t::lower_bound_range(x);  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
+   //!
+   //! <b>Complexity</b>: Linear
+   void rebalance();
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const set& x, const set& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const set& x, const set& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const set& x, const set& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const set& x, const set& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const set& x, const set& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const set& x, const set& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(set& x, set& y);
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
+   {  return this->base_t::insert_unique(::boost::forward<KeyType>(x));  }
+
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+   {  return this->base_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+set(InputIterator, InputIterator) ->
+   set<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+set(InputIterator, InputIterator, Allocator const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, std::less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
+
+template <typename InputIterator, typename Compare>
+set(InputIterator, InputIterator, Compare const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+set(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+template <typename InputIterator>
+set(ordered_unique_range_t, InputIterator, InputIterator) ->
+   set<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, std::less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
+
+template <typename InputIterator, typename Compare>
+set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class Compare, class Options, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A multiset is a kind of associative container that supports equivalent keys
+//! (possibly contains multiple copies of the same key value) and provides for
+//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
+//!
+//! A multiset satisfies all of the requirements of a container and of a reversible
+//! container, and of an associative container). multiset also provides most operations
+//! described for duplicate keys.
+//!
+//! \tparam Key is the type to be inserted in the set, which is also the key_type
+//! \tparam Compare is the comparison functor used to order keys
+//! \tparam Allocator is the allocator to be used to allocate memory for this container
+//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
+#else
+template <class Key, class Compare, class Allocator, class Options>
+#endif
+class multiset
+   /// @cond
+   : public dtl::tree
+      <Key,dtl::identity<Key>, Compare, Allocator, Options>
+   /// @endcond
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(multiset)
+   typedef dtl::tree
+      <Key,dtl::identity<Key>, Compare, Allocator, Options> base_t;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Key                                                                         key_type;
+   typedef Key                                                                         value_type;
+   typedef Compare                                                                     key_compare;
+   typedef Compare                                                                     value_compare;
+   typedef ::boost::container::allocator_traits<Allocator>                             allocator_traits_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type)              stored_allocator_type;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator)                           iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator)                     const_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator)                   reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator)             const_reverse_iterator;
+   typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type)                          node_type;
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! @copydoc ::boost::container::set::set()
+   BOOST_CONTAINER_FORCEINLINE multiset()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value &&
+                        dtl::is_nothrow_default_constructible<Compare>::value)
+      : base_t()
+   {}
+
+   //! @copydoc ::boost::container::set::set(const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE explicit multiset(const allocator_type& a)
+      : base_t(a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(const Compare&)
+   BOOST_CONTAINER_FORCEINLINE explicit multiset(const Compare& comp)
+      : base_t(comp)
+   {}
+
+   //! @copydoc ::boost::container::set::set(const Compare&, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE multiset(const Compare& comp, const allocator_type& a)
+      : base_t(comp, a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(InputIterator, InputIterator)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last)
+      : base_t(false, first, last)
+   {}
+
+   //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const allocator_type& a)
+      : base_t(false, first, last, key_compare(), a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(false, first, last, comp)
+   {}
+
+   //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&, const allocator_type&)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : base_t(false, first, last, comp, a)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multiset and
+   //! and inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last )
+      : base_t(ordered_range, first, last)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
+   //! inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+      : base_t(ordered_range, first, last, comp)
+   {}
+
+   //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
+   //! allocator, and inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+   //!
+   //! <b>Complexity</b>: Linear in N.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, first, last, comp, a)
+   {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>)
+   BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il)
+      : base_t(false, il.begin(), il.end())
+   {}
+
+   //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const allocator_type& a)
+      : base_t(false, il.begin(), il.end(), Compare(), a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&)
+   BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(false, il.begin(), il.end(), comp)
+   {}
+
+   //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(false, il.begin(), il.end(), comp, a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>)
+   BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il)
+      : base_t(ordered_range, il.begin(), il.end())
+   {}
+
+   //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&)
+   BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+      : base_t(ordered_range, il.begin(), il.end(), comp)
+   {}
+
+   //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&, const allocator_type&)
+   BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+      : base_t(ordered_range, il.begin(), il.end(), comp, a)
+   {}
+#endif
+
+   //! @copydoc ::boost::container::set::set(const set &)
+   BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x)
+      : base_t(static_cast<const base_t&>(x))
+   {}
+
+   //! @copydoc ::boost::container::set::set(set &&)
+   BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<Compare>::value)
+      : base_t(BOOST_MOVE_BASE(base_t, x))
+   {}
+
+   //! @copydoc ::boost::container::set::set(const set &, const allocator_type &)
+   BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x, const allocator_type &a)
+      : base_t(static_cast<const base_t&>(x), a)
+   {}
+
+   //! @copydoc ::boost::container::set::set(set &&, const allocator_type &)
+   BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
+      : base_t(BOOST_MOVE_BASE(base_t, x), a)
+   {}
+
+   //! @copydoc ::boost::container::set::operator=(const set &)
+   BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
+   {  return static_cast<multiset&>(this->base_t::operator=(static_cast<const base_t&>(x)));  }
+
+   //! @copydoc ::boost::container::set::operator=(set &&)
+   BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x)
+      BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
+                          allocator_traits_type::is_always_equal::value) &&
+                           boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
+   {  return static_cast<multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x)));  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! @copydoc ::boost::container::set::operator=(std::initializer_list<value_type>)
+   multiset& operator=(std::initializer_list<value_type> il)
+   {
+       this->clear();
+       insert(il.begin(), il.end());
+       return *this;
+   }
+#endif
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::set::get_allocator()
+   allocator_type get_allocator() const;
+
+   //! @copydoc ::boost::container::set::get_stored_allocator()
+   stored_allocator_type &get_stored_allocator();
+
+   //! @copydoc ::boost::container::set::get_stored_allocator() const
+   const stored_allocator_type &get_stored_allocator() const;
+
+   //! @copydoc ::boost::container::set::begin()
+   iterator begin();
+
+   //! @copydoc ::boost::container::set::begin() const
+   const_iterator begin() const;
+
+   //! @copydoc ::boost::container::set::cbegin() const
+   const_iterator cbegin() const;
+
+   //! @copydoc ::boost::container::set::end()
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::end() const
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::cend() const
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rbegin()
+   reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rbegin() const
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::crbegin() const
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rend()
+   reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::rend() const
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::crend() const
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::empty() const
+   bool empty() const;
+
+   //! @copydoc ::boost::container::set::size() const
+   size_type size() const;
+
+   //! @copydoc ::boost::container::set::max_size() const
+   size_type max_size() const;
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)... and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type Key constructed with
+   //!   std::forward<Args>(args)...
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template <class... Args>
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_equal(BOOST_MOVE_FWD##N);  }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {  return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! <b>Complexity</b>: Logarithmic.
+   iterator insert(const value_type &x);
+
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, const value_type &x);
+
+   //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, value_type &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: first, last are not iterators into *this.
+   //!
+   //! <b>Effects</b>: inserts each element from the range [first,last) .
+   //!
+   //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+   template <class InputIterator>
+   BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
+   {  this->base_t::insert_equal(first, last);  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! @copydoc ::boost::container::set::insert(std::initializer_list<value_type>)
+   BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
+   {  this->base_t::insert_equal(il.begin(), il.end());  }
+#endif
+
+   //! @copydoc ::boost::container::multimap::insert(node_type&&)
+   BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {  return this->base_t::insert_equal_node(boost::move(nh));  }
+
+   //! @copydoc ::boost::container::multimap::insert(const_iterator, node_type&&)
+   BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+   {  return this->base_t::insert_equal_node(hint, boost::move(nh));  }
+
+   //! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t;
+      this->base_t::merge_equal(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::multiset::merge(multiset<Key, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source));   }
+
+   //! @copydoc ::boost::container::multimap::merge(map<Key, T, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
+   {
+      typedef dtl::tree
+         <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t;
+      this->base_t::merge_equal(static_cast<base2_t&>(source));
+   }
+
+   //! @copydoc ::boost::container::multiset::merge(set<Key, C2, Allocator, Options>&)
+   template<class C2>
+   BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
+   {  return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source));   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! @copydoc ::boost::container::set::erase(const_iterator)
+   iterator erase(const_iterator p);
+
+   //! @copydoc ::boost::container::set::erase(const key_type&)
+   size_type erase(const key_type& x);
+
+   //! @copydoc ::boost::container::set::erase(const_iterator,const_iterator)
+   iterator erase(const_iterator first, const_iterator last);
+
+   //! @copydoc ::boost::container::multimap::extract(const_iterator)
+   node_type extract(const_iterator p);
+
+   //! @copydoc ::boost::container::multimap::extract(const key_type&)
+   node_type extract(const key_type& x);
+
+   //! @copydoc ::boost::container::set::swap
+   void swap(multiset& x)
+      BOOST_NOEXCEPT_IF(  allocator_traits_type::is_always_equal::value
+                                 && boost::container::dtl::is_nothrow_swappable<Compare>::value );
+
+   //! @copydoc ::boost::container::set::clear
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW;
+
+   //! @copydoc ::boost::container::set::key_comp
+   key_compare key_comp() const;
+
+   //! @copydoc ::boost::container::set::value_comp
+   value_compare value_comp() const;
+
+   //! @copydoc ::boost::container::set::find(const key_type& )
+   iterator find(const key_type& x);
+
+   //! @copydoc ::boost::container::set::find(const key_type& ) const
+   const_iterator find(const key_type& x) const;
+
+   //! @copydoc ::boost::container::set::find(const K& )
+   template<typename K>
+   iterator find(const K& x);
+
+   //! @copydoc ::boost::container::set::find(const K& )
+   template<typename K>
+   const_iterator find(const K& x) const;
+
+   //! @copydoc ::boost::container::set::count(const key_type& ) const
+   size_type count(const key_type& x) const;
+
+   //! @copydoc ::boost::container::set::count(const K& ) const
+   template<typename K>
+   size_type count(const K& x) const;
+
+   //! @copydoc ::boost::container::set::lower_bound(const key_type& )
+   iterator lower_bound(const key_type& x);
+
+   //! @copydoc ::boost::container::set::lower_bound(const key_type& ) const
+   const_iterator lower_bound(const key_type& x) const;
+
+   //! @copydoc ::boost::container::set::lower_bound(const K& )
+   template<typename K>
+   iterator lower_bound(const K& x);
+
+   //! @copydoc ::boost::container::set::lower_bound(const K& ) const
+   template<typename K>
+   const_iterator lower_bound(const K& x) const;
+
+   //! @copydoc ::boost::container::set::upper_bound(const key_type& )
+   iterator upper_bound(const key_type& x);
+
+   //! @copydoc ::boost::container::set::upper_bound(const key_type& ) const
+   const_iterator upper_bound(const key_type& x) const;
+
+   //! @copydoc ::boost::container::set::upper_bound(const K& )
+   template<typename K>
+   iterator upper_bound(const K& x);
+
+   //! @copydoc ::boost::container::set::upper_bound(const K& ) const
+   template<typename K>
+   const_iterator upper_bound(const K& x) const;
+
+   //! @copydoc ::boost::container::set::equal_range(const key_type& ) const
+   std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
+
+   //! @copydoc ::boost::container::set::equal_range(const key_type& )
+   std::pair<iterator,iterator> equal_range(const key_type& x);
+
+   //! @copydoc ::boost::container::set::equal_range(const K& ) const
+   template<typename K>
+   std::pair<const_iterator, const_iterator> equal_range(const K& x) const;
+
+   //! @copydoc ::boost::container::set::equal_range(const K& )
+   template<typename K>
+   std::pair<iterator,iterator> equal_range(const K& x);
+
+   //! @copydoc ::boost::container::set::rebalance()
+   void rebalance();
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const multiset& x, const multiset& y);
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(multiset& x, multiset& y);
+
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x)
+   {  return this->base_t::insert_equal(::boost::forward<KeyType>(x));  }
+
+   template <class KeyType>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+   {  return this->base_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+multiset(InputIterator, InputIterator) ->
+   multiset<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+multiset(InputIterator, InputIterator, Allocator const&) ->
+   multiset< typename iterator_traits<InputIterator>::value_type
+                , std::less<typename iterator_traits<InputIterator>::value_type>
+                , Allocator>;
+
+template <typename InputIterator, typename Compare>
+multiset(InputIterator, InputIterator, Compare const&) ->
+   multiset<typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+multiset(InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+template <typename InputIterator>
+multiset(ordered_range_t, InputIterator, InputIterator) ->
+   multiset<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) ->
+   multiset< typename iterator_traits<InputIterator>::value_type
+                , std::less<typename iterator_traits<InputIterator>::value_type>
+                , Allocator>;
+
+template <typename InputIterator, typename Compare>
+multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) ->
+   multiset< typename iterator_traits<InputIterator>::value_type, Compare>;
+
+template <typename InputIterator, typename Compare, typename Allocator>
+multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) ->
+   multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class Key, class Compare, class Allocator, class Options>
+struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value &&
+                             ::boost::has_trivial_destructor_after_move<Compare>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   // BOOST_CONTAINER_SET_HPP
diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp
new file mode 100644
index 0000000..2769070
--- /dev/null
+++ b/include/boost/container/slist.hpp
@@ -0,0 +1,1714 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-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_SLIST_HPP
+#define BOOST_CONTAINER_SLIST_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/value_functors.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/slist.hpp>
+// move
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class T, class Allocator>
+class slist;
+
+namespace dtl {
+
+template<class VoidPointer>
+struct slist_hook
+{
+   typedef typename dtl::bi::make_slist_base_hook
+      <dtl::bi::void_pointer<VoidPointer>, dtl::bi::link_mode<dtl::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct slist_node
+   :  public slist_hook<VoidPointer>::type
+{
+   private:
+   slist_node();
+
+   public:
+   typedef T value_type;
+   typedef typename slist_hook<VoidPointer>::type hook_type;
+
+   T m_data;
+
+   T &get_data()
+   {  return this->m_data;   }
+
+   const T &get_data() const
+   {  return this->m_data;   }
+};
+
+template <class T, class VoidPointer>
+struct iiterator_node_value_type< slist_node<T,VoidPointer> > {
+  typedef T type;
+};
+
+template<class Allocator>
+struct intrusive_slist_type
+{
+   typedef boost::container::allocator_traits<Allocator>      allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename boost::intrusive::pointer_traits
+      <typename allocator_traits_type::pointer>::template
+         rebind_pointer<void>::type
+            void_pointer;
+   typedef typename dtl::slist_node
+         <value_type, void_pointer>             node_type;
+
+   typedef typename dtl::bi::make_slist
+      <node_type
+      ,dtl::bi::base_hook<typename slist_hook<void_pointer>::type>
+      ,dtl::bi::constant_time_size<true>
+      , dtl::bi::size_type
+         <typename allocator_traits_type::size_type>
+      >::type                                   container_type;
+   typedef container_type                       type ;
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! An slist is a singly linked list: a list where each element is linked to the next
+//! element, but not to the previous element. That is, it is a Sequence that
+//! supports forward but not backward traversal, and (amortized) constant time
+//! insertion and removal of elements. Slists, like lists, have the important
+//! property that insertion and splicing do not invalidate iterators to list elements,
+//! and that even removal invalidates only the iterators that point to the elements
+//! that are removed. The ordering of iterators may be changed (that is,
+//! slist<T>::iterator might have a different predecessor or successor after a list
+//! operation than it did before), but the iterators themselves will not be invalidated
+//! or made to point to different elements unless that invalidation or mutation is explicit.
+//!
+//! The main difference between slist and list is that list's iterators are bidirectional
+//! iterators, while slist's iterators are forward iterators. This means that slist is
+//! less versatile than list; frequently, however, bidirectional iterators are
+//! unnecessary. You should usually use slist unless you actually need the extra
+//! functionality of list, because singly linked lists are smaller and faster than double
+//! linked lists.
+//!
+//! Important performance note: like every other Sequence, slist defines the member
+//! functions insert and erase. Using these member functions carelessly, however, can
+//! result in disastrously slow programs. The problem is that insert's first argument is
+//! an iterator p, and that it inserts the new element(s) before p. This means that
+//! insert must find the iterator just before p; this is a constant-time operation
+//! for list, since list has bidirectional iterators, but for slist it must find that
+//! iterator by traversing the list from the beginning up to p. In other words:
+//! insert and erase are slow operations anywhere but near the beginning of the slist.
+//!
+//! Slist provides the member functions insert_after and erase_after, which are constant
+//! time operations: you should always use insert_after and erase_after whenever
+//! possible. If you find that insert_after and erase_after aren't adequate for your
+//! needs, and that you often need to use insert and erase in the middle of the list,
+//! then you should probably use list instead of slist.
+//!
+//! \tparam T The type of object that is stored in the list
+//! \tparam Allocator The allocator used for all internal memory management
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Allocator = new_allocator<T> >
+#else
+template <class T, class Allocator>
+#endif
+class slist
+   : protected dtl::node_alloc_holder
+      <Allocator, typename dtl::intrusive_slist_type<Allocator>::type>
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef typename
+      dtl::intrusive_slist_type<Allocator>::type           Icont;
+   typedef dtl::node_alloc_holder<Allocator, Icont>        AllocHolder;
+   typedef typename AllocHolder::NodePtr                    NodePtr;
+   typedef typename AllocHolder::NodeAlloc                  NodeAlloc;
+   typedef typename AllocHolder::ValAlloc                   ValAlloc;
+   typedef typename AllocHolder::Node                       Node;
+   typedef dtl::allocator_destroyer<NodeAlloc> Destroyer;
+   typedef typename AllocHolder::alloc_version              alloc_version;
+   typedef boost::container::
+      allocator_traits<Allocator>                           allocator_traits_type;
+   typedef boost::container::equal_to_value<Allocator>      equal_to_value_type;
+
+   BOOST_COPYABLE_AND_MOVABLE(slist)
+   typedef dtl::iterator_from_iiterator<typename Icont::iterator, false>  iterator_impl;
+   typedef dtl::iterator_from_iiterator<typename Icont::iterator, true >  const_iterator_impl;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef T                                                                  value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer          pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer    const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference        reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference  const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type        size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type  difference_type;
+   typedef Allocator                                                                  allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(NodeAlloc)                                  stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(iterator_impl)                              iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl)                        const_iterator;
+
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   slist() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      :  AllocHolder()
+   {}
+
+   //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   explicit slist(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
+      :  AllocHolder(a)
+   {}
+
+   //! <b>Effects</b>: Constructs a list
+   //!   and inserts n value-initialized value_types.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit slist(size_type n)
+      :  AllocHolder(allocator_type())
+   { this->resize(n); }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   slist(size_type n, const allocator_type &a)
+      : AllocHolder(a)
+   {  this->resize(n);  }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
+      :  AllocHolder(a)
+   { this->insert_after(this->cbefore_begin(), n, x); }
+
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the list.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+   template <class InpIt>
+   slist(InpIt first, InpIt last, const allocator_type& a =  allocator_type())
+      : AllocHolder(a)
+   { this->insert_after(this->cbefore_begin(), first, last); }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [il.begin(), il.end()) in the list.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   slist(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : AllocHolder(a)
+   { this->insert_after(this->cbefore_begin(), il.begin(), il.end()); }
+#endif
+
+    //! <b>Effects</b>: Copy constructs a list.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   slist(const slist& x)
+      : AllocHolder(x)
+   { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   slist(BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
+      : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
+   {}
+
+   //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   slist(const slist& x, const allocator_type &a)
+      : AllocHolder(a)
+   { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   slist(BOOST_RV_REF(slist) x, const allocator_type &a)
+      : AllocHolder(a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->insert_after(this->cbefore_begin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
+      }
+   }
+
+   //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements.
+   ~slist() BOOST_NOEXCEPT_OR_NOTHROW
+   {} //AllocHolder clears the slist
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->node_alloc();
+         const NodeAlloc &x_alloc  = x.node_alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   slist& operator=(BOOST_RV_REF(slist) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(this != &x);
+      NodeAlloc &this_alloc = this->node_alloc();
+      NodeAlloc &x_alloc    = x.node_alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy
+         this->clear();
+         //Move allocator if needed
+         this->AllocHolder::move_assign_alloc(x);
+         //Obtain resources
+         this->icont() = boost::move(x.icont());
+      }
+      //Else do a one by one move
+      else{
+         this->assign( boost::make_move_iterator(x.begin())
+                     , boost::make_move_iterator(x.end()));
+      }
+      return *this;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Makes *this contain the same elements as in il.
+   //!
+   //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
+   //! of each of il's elements.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   slist& operator=(std::initializer_list<value_type> il)
+   {
+       assign(il.begin(), il.end());
+       return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Assigns the n copies of val to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   void assign(size_type n, const T& val)
+   {
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->assign(cvalue_iterator(val, n), cvalue_iterator());
+   }
+
+   //! <b>Effects</b>: Assigns the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template <class InpIt>
+   void assign(InpIt first, InpIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible<InpIt, size_type>::type * = 0
+      #endif
+      )
+   {
+      iterator end_n(this->end());
+      iterator prev(this->before_begin());
+      iterator node(this->begin());
+      while (node != end_n && first != last){
+         *node = *first;
+         prev = node;
+         ++node;
+         ++first;
+      }
+      if (first != last)
+         this->insert_after(prev, first, last);
+      else
+         this->erase_after(prev, end_n);
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to range [il.begin(), il.end()).
+
+   void assign(std::initializer_list<value_type> il)
+   {
+       assign(il.begin(), il.end());
+   }
+#endif
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return allocator_type(this->node_alloc()); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->node_alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->node_alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
+   //! when incremented, yields begin().  This iterator may be used
+   //! as the argument to insert_after, erase_after, etc.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator before_begin() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(end());  }
+
+   //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+   //! that, when incremented, yields begin().  This iterator may be used
+   //! as the argument to insert_after, erase_after, etc.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator before_begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->cbefore_begin();  }
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return iterator(this->icont().begin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->cbegin();   }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+   { return iterator(this->icont().end()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->cend();   }
+
+   //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+   //! that, when incremented, yields begin().  This iterator may be used
+   //! as the argument to insert_after, erase_after, etc.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbefore_begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(end());  }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(this->non_const_icont().begin());   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(this->non_const_icont().end());   }
+
+   //! <b>Returns</b>: The iterator to the element before i in the sequence.
+   //!   Returns the end-iterator, if either i is the begin-iterator or the
+   //!   sequence is empty.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements before i.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   iterator previous(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(this->icont().previous(p.get())); }
+
+   //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
+   //!   Returns the end-const_iterator, if either i is the begin-const_iterator or
+   //!   the sequence is empty.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements before i.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const_iterator previous(const_iterator p)
+   {  return const_iterator(this->icont().previous(p.get())); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the list contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const
+   {  return !this->size();   }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const
+   {  return this->icont().size(); }
+
+   //! <b>Effects</b>: Returns the largest possible size of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const
+   {  return AllocHolder::max_size();  }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {
+      const_iterator last_pos;
+      if(!priv_try_shrink(new_size, last_pos)){
+         typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
+         this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator());
+      }
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x)
+   {
+      const_iterator last_pos;
+      if(!priv_try_shrink(new_size, last_pos)){
+         this->insert_after(last_pos, new_size, x);
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference front()
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->begin();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference front() const
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->begin();
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the front of the list
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   template <class... Args>
+   reference emplace_front(BOOST_FWD_REF(Args)... args)
+   {  return *this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... after prev
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant
+   template <class... Args>
+   iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args)
+   {
+      NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
+      return iterator(this->icont().insert_after(prev.get(), *pnode));
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   reference emplace_front(BOOST_MOVE_UREF##N)\
+   {  return *this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+      return iterator(this->icont().insert_after(p.get(), *pnode));\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the beginning of the list
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_front(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+   #endif
+
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts a copy of the value after prev_p.
+   //!
+   //! <b>Returns</b>: An iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   //!
+   //! <b>Note</b>: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_p, const T &x);
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
+   //!    element pointed by prev_p.
+   //!
+   //! <b>Returns</b>: An iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   //!
+   //! <b>Note</b>: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_p, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_after, T, iterator, priv_insert_after, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts n copies of x after prev_p.
+   //!
+   //! <b>Returns</b>: an iterator to the last inserted element or prev_p if n is 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_p, size_type n, const value_type& x)
+   {
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->insert_after(prev_p, cvalue_iterator(x, n), cvalue_iterator());
+   }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts the range pointed by [first, last) after prev_p.
+   //!
+   //! <b>Returns</b>: an iterator to the last inserted element or prev_p if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements inserted.
+   //!
+   //! <b>Note</b>: Does not affect the validity of iterators and references of
+   //!   previous values.
+   template <class InpIt>
+   iterator insert_after(const_iterator prev_p, InpIt first, InpIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::enable_if_c
+         < !dtl::is_convertible<InpIt, size_type>::value
+          && (dtl::is_input_iterator<InpIt>::value
+                || dtl::is_same<alloc_version, version_1>::value
+               )
+         >::type * = 0
+      #endif
+      )
+   {
+      iterator ret_it(prev_p.get());
+      for (; first != last; ++first){
+         ret_it = iterator(this->icont().insert_after(ret_it.get(), *this->create_node_from_it(first)));
+      }
+      return ret_it;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: prev_p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts the range pointed by [il.begin(), il.end()) after prev_p.
+   //!
+   //! <b>Returns</b>: an iterator to the last inserted element or prev_p if il.begin() == il.end().
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements inserted.
+   //!
+   //! <b>Note</b>: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_p, std::initializer_list<value_type> il)
+   {
+       return insert_after(prev_p, il.begin(), il.end());
+   }
+#endif
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   iterator insert_after(const_iterator prev, FwdIt first, FwdIt last
+      , typename dtl::enable_if_c
+         < !dtl::is_convertible<FwdIt, size_type>::value
+            && !(dtl::is_input_iterator<FwdIt>::value
+                || dtl::is_same<alloc_version, version_1>::value
+               )
+         >::type * = 0
+      )
+   {
+      //Optimized allocation and construction
+      insertion_functor func(this->icont(), prev.get());
+      this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
+      return iterator(func.inserted_first());
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the first element from the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void pop_front()
+   {
+      BOOST_ASSERT(!this->empty());
+      this->icont().pop_front_and_dispose(Destroyer(this->node_alloc()));
+   }
+
+   //! <b>Effects</b>: Erases the element after the element pointed by prev_p
+   //!    of the list.
+   //!
+   //! <b>Returns</b>: the first element remaining beyond the removed elements,
+   //!   or end() if no such element exists.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+   iterator erase_after(const_iterator prev_p)
+   {
+      return iterator(this->icont().erase_after_and_dispose(prev_p.get(), Destroyer(this->node_alloc())));
+   }
+
+   //! <b>Effects</b>: Erases the range (before_first, last) from
+   //!   the list.
+   //!
+   //! <b>Returns</b>: the first element remaining beyond the removed elements,
+   //!   or end() if no such element exists.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of erased elements.
+   //!
+   //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+   iterator erase_after(const_iterator before_first, const_iterator last)
+   {
+      return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements on *this and x.
+   void swap(slist& x)
+      BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
+                                || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
+                   allocator_traits_type::is_always_equal::value ||
+                   this->get_stored_allocator() == x.get_stored_allocator());
+      AllocHolder::swap(x);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the list.
+   void clear()
+   {  this->icont().clear_and_dispose(Destroyer(this->node_alloc()));  }
+
+   //////////////////////////////////////////////
+   //
+   //              slist operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //!
+   //! <b>Complexity</b>: Linear to the elements in x.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this != &x);
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice_after(prev_p.get(), x.icont());
+   }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //!
+   //! <b>Complexity</b>: Linear to the elements in x.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(prev_p, static_cast<slist&>(x));  }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   after the element pointed by prev_p.
+   //!   If prev_p == prev or prev_p == ++prev, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice_after(prev_p.get(), x.icont(), prev.get());
+   }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   after the element pointed by prev_p.
+   //!   If prev_p == prev or prev_p == ++prev, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(prev_p, static_cast<slist&>(x), prev);  }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_p must not be contained in [before_first, before_last) range.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to the number of transferred elements.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p,      slist& x,
+      const_iterator before_first,  const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice_after
+         (prev_p.get(), x.icont(), before_first.get(), before_last.get());
+   }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_p must not be contained in [before_first, before_last) range.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to the number of transferred elements.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p,      BOOST_RV_REF(slist) x,
+      const_iterator before_first,  const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last);  }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_p must not be contained in [before_first, before_last) range.
+   //!   n == distance(before_first, before_last).
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p,      slist& x,
+                     const_iterator before_first,  const_iterator before_last,
+                     size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().splice_after
+         (prev_p.get(), x.icont(), before_first.get(), before_last.get(), n);
+   }
+
+   //! <b>Requires</b>: prev_p must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_p must not be contained in [before_first, before_last) range.
+   //!   n == distance(before_first, before_last).
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_p,      BOOST_RV_REF(slist) x,
+                     const_iterator before_first,  const_iterator before_last,
+                     size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last, n);  }
+
+   //! <b>Effects</b>: Removes all the elements that compare equal to value.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void remove(const T& value)
+   {  this->remove_if(equal_to_value_type(value));  }
+
+   //! <b>Effects</b>: Removes all the elements for which a specified
+   //!   predicate is satisfied.
+   //!
+   //! <b>Throws</b>: If pred throws.
+   //!
+   //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template <class Pred>
+   void remove_if(Pred pred)
+   {
+      typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+      this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+   //!   elements that are equal from the list.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void unique()
+   {  this->unique(value_equal_t());  }
+
+   //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+   //!   elements that satisfy some binary predicate from the list.
+   //!
+   //! <b>Throws</b>: If pred throws.
+   //!
+   //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+   //!
+   //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template <class Pred>
+   void unique(Pred pred)
+   {
+      typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+      this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! <b>Requires</b>: The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less<value_type>. The merge is stable;
+   //!   that is, if an element from *this is equivalent to one from x, then the element
+   //!   from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(slist & x)
+   {  this->merge(x, value_less_t()); }
+
+   //! <b>Requires</b>: The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less<value_type>. The merge is stable;
+   //!   that is, if an element from *this is equivalent to one from x, then the element
+   //!   from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(BOOST_RV_REF(slist) x)
+   {  this->merge(static_cast<slist&>(x)); }
+
+   //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is
+   //!   equivalent to one from x, then the element from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //!
+   //! <b>Note</b>: Iterators and references to *this are not invalidated.
+   template <class StrictWeakOrdering>
+   void merge(slist& x, StrictWeakOrdering comp)
+   {
+      typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+      BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+      this->icont().merge(x.icont(), value_to_node_compare_type(comp));
+   }
+
+   //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct.
+   //!
+   //! <b>Effects</b>: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is
+   //!   equivalent to one from x, then the element from *this will precede the one from x.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Complexity</b>: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //!
+   //! <b>Note</b>: Iterators and references to *this are not invalidated.
+   template <class StrictWeakOrdering>
+   void merge(BOOST_RV_REF(slist) x, StrictWeakOrdering comp)
+   {  this->merge(static_cast<slist&>(x), comp); }
+
+   //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //!
+   //! <b>Throws</b>: If comparison throws.
+   //!
+   //! <b>Notes</b>: Iterators and references are not invalidated.
+   //!
+   //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   void sort()
+   {  this->sort(value_less_t());  }
+
+   //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //!
+   //! <b>Throws</b>: If comp throws.
+   //!
+   //! <b>Notes</b>: Iterators and references are not invalidated.
+   //!
+   //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   template <class StrictWeakOrdering>
+   void sort(StrictWeakOrdering comp)
+   {
+      typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+      // nothing if the slist has length 0 or 1.
+      if (this->size() < 2)
+         return;
+      this->icont().sort(value_to_node_compare_type(comp));
+   }
+
+   //! <b>Effects</b>: Reverses the order of elements in the list.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: This function is linear time.
+   //!
+   //! <b>Note</b>: Iterators and references are not invalidated
+   void reverse() BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->icont().reverse();  }
+
+   //////////////////////////////////////////////
+   //
+   //       list compatibility interface
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... before p
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements before p
+   template <class... Args>
+   iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
+   {  return this->emplace_after(this->previous(p), boost::forward<Args>(args)...);  }
+
+   #else
+
+   #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements before p.
+   iterator insert(const_iterator p, const T &x);
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a new element before p with x's resources.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements before p.
+   iterator insert(const_iterator prev_p, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts n copies of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
+   iterator insert(const_iterator p, size_type n, const value_type& x)
+   {
+      const_iterator prev(this->previous(p));
+      this->insert_after(prev, n, x);
+      return ++iterator(prev.get());
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [first, last) plus
+   //!    linear to the elements before p.
+   template <class InIter>
+   iterator insert(const_iterator p, InIter first, InIter last)
+   {
+      const_iterator prev(this->previous(p));
+      this->insert_after(prev, first, last);
+      return ++iterator(prev.get());
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if il.begin() == il.end().
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced std::initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()) plus
+   //!    linear to the elements before p.
+   iterator insert(const_iterator p, std::initializer_list<value_type> il)
+   {
+       return insert(p, il.begin(), il.end());
+   }
+#endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Erases the element at p.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements before p.
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(this->erase_after(previous(p))); }
+
+   //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+   //!
+   //! <b>Effects</b>: Erases the elements pointed by [first, last).
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the distance between first and last plus
+   //!   linear to the elements before first.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(this->erase_after(previous(first), last)); }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(this->previous(p), x);  }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice(p, static_cast<slist&>(x));  }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(this->previous(p), x, x.previous(i));  }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice(p, static_cast<slist&>(x), i);  }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!   this' allocator and x's allocator shall compare equal.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+   //!   and in distance(first, last).
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice_after(this->previous(p), x, x.previous(first), x.previous(last));  }
+
+   //! <b>Requires</b>: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   this' allocator and x's allocator shall compare equal
+   //!
+   //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+   //!   before the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+   //!   and in distance(first, last).
+   //!
+   //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->splice(p, static_cast<slist&>(x), first, last);  }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const slist& x, const slist& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const slist& x, const slist& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const slist& x, const slist& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const slist& x, const slist& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const slist& x, const slist& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const slist& x, const slist& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(slist& x, slist& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   void priv_push_front (const T &x)
+   {  this->insert_after(this->cbefore_begin(), x);  }
+
+   void priv_push_front (BOOST_RV_REF(T) x)
+   {  this->insert_after(this->cbefore_begin(), ::boost::move(x));  }
+
+   bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
+   {
+      typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+      while (++(cur_next = cur) != end_n && new_size > 0){
+         --new_size;
+         cur = cur_next;
+      }
+      last_pos = const_iterator(cur);
+      if (cur_next != end_n){
+         this->erase_after(last_pos, const_iterator(end_n));
+         return true;
+      }
+      else{
+         return false;
+      }
+   }
+
+   template<class U>
+   iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
+   {  return this->insert_after(previous(p), ::boost::forward<U>(x)); }
+
+   template<class U>
+   iterator priv_insert_after(const_iterator prev_p, BOOST_FWD_REF(U) x)
+   {  return iterator(this->icont().insert_after(prev_p.get(), *this->create_node(::boost::forward<U>(x)))); }
+
+   class insertion_functor;
+   friend class insertion_functor;
+
+   class insertion_functor
+   {
+      Icont &icont_;
+      typedef typename Icont::iterator       iiterator;
+      typedef typename Icont::const_iterator iconst_iterator;
+      const iconst_iterator prev_;
+      iiterator   ret_;
+
+      public:
+      insertion_functor(Icont &icont, typename Icont::const_iterator prev)
+         :  icont_(icont), prev_(prev), ret_(prev.unconst())
+      {}
+
+      void operator()(Node &n)
+      {
+         ret_ = this->icont_.insert_after(prev_, n);
+      }
+
+      iiterator inserted_first() const
+      {  return ret_;   }
+   };
+
+   //Functors for member algorithm defaults
+   typedef value_less<value_type>   value_less_t;
+   typedef value_equal<value_type>  value_equal_t;
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InpIt>
+slist(InpIt, InpIt) ->
+   slist<typename iterator_traits<InpIt>::value_type>;
+
+template <typename InpIt, typename Allocator>
+slist(InpIt, InpIt, Allocator const&) ->
+   slist<typename iterator_traits<InpIt>::value_type, Allocator>;
+
+#endif
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+namespace container {
+
+}} //namespace boost{  namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+// Specialization of insert_iterator so that insertions will be constant
+// time rather than linear time.
+
+#include <boost/move/detail/std_ns_begin.hpp>
+BOOST_CONTAINER_DOC1ST(namespace std {, BOOST_MOVE_STD_NS_BEG)
+
+//! A specialization of insert_iterator
+//! that works with slist
+template <class T, class Allocator>
+class insert_iterator<boost::container::slist<T, Allocator> >
+{
+   private:
+   typedef boost::container::slist<T, Allocator> Container;
+   Container* container;
+   typename Container::iterator iter;
+
+   public:
+   typedef Container           container_type;
+   typedef output_iterator_tag iterator_category;
+   typedef void                value_type;
+   typedef void                difference_type;
+   typedef void                pointer;
+   typedef void                reference;
+
+   insert_iterator(Container& x,
+                   typename Container::iterator i,
+                   bool is_previous = false)
+      : container(&x), iter(is_previous ? i : x.previous(i)){ }
+
+   insert_iterator<Container>&
+      operator=(const typename Container::value_type& value)
+   {
+      iter = container->insert_after(iter, value);
+      return *this;
+   }
+   insert_iterator<Container>& operator*(){ return *this; }
+   insert_iterator<Container>& operator++(){ return *this; }
+   insert_iterator<Container>& operator++(int){ return *this; }
+};
+
+BOOST_CONTAINER_DOC1ST( }, BOOST_MOVE_STD_NS_END)
+#include <boost/move/detail/std_ns_end.hpp>
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_SLIST_HPP
diff --git a/include/boost/container/small_vector.hpp b/include/boost/container/small_vector.hpp
new file mode 100644
index 0000000..70704d6
--- /dev/null
+++ b/include/boost/container/small_vector.hpp
@@ -0,0 +1,631 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_CONTAINER_SMALL_VECTOR_HPP
+#define BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// container/detail
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+
+//move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+
+//move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>   //for std::initializer_list
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class T, class Allocator = new_allocator<T> >
+class small_vector_base;
+
+#endif
+
+//! A non-standard allocator used to implement `small_vector`.
+//! Users should never use it directly. It is described here
+//! for documentation purposes.
+//! 
+//! This allocator inherits from a standard-conforming allocator
+//! and forwards member functions to the standard allocator except
+//! when internal storage is being used as memory source.
+//!
+//! This allocator is a "partially_propagable" allocator and
+//! defines `is_partially_propagable` as true_type.
+//! 
+//! A partially propagable allocator means that not all storage
+//! allocatod by an instance of `small_vector_allocator` can be
+//! deallocated by another instance of this type, even if both
+//! instances compare equal or an instance is propagated to another
+//! one using the copy/move constructor or assignment. The storage that
+//! can never be propagated is identified by `storage_is_unpropagable(p)`.
+//!
+//! `boost::container::vector` supports partially propagable allocators
+//! fallbacking to deep copy/swap/move operations when internal storage
+//! is being used to store vector elements.
+//!
+//! `small_vector_allocator` assumes that will be instantiated as
+//! `boost::container::vector< T, small_vector_allocator<Allocator> >`
+//! and internal storage can be obtained downcasting that vector
+//! to `small_vector_base<T>`.
+template<class Allocator>
+class small_vector_allocator
+   : public Allocator
+{
+   typedef unsigned int allocation_type;
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator)
+
+   BOOST_CONTAINER_FORCEINLINE const Allocator &as_base() const
+   {  return static_cast<const Allocator&>(*this);  }
+
+   BOOST_CONTAINER_FORCEINLINE Allocator &as_base() 
+   {  return static_cast<Allocator&>(*this);  }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   typedef typename allocator_traits<Allocator>::value_type          value_type;
+   typedef typename allocator_traits<Allocator>::pointer             pointer;
+   typedef typename allocator_traits<Allocator>::const_pointer       const_pointer;
+   typedef typename allocator_traits<Allocator>::reference           reference;
+   typedef typename allocator_traits<Allocator>::const_reference     const_reference;
+   typedef typename allocator_traits<Allocator>::size_type           size_type;
+   typedef typename allocator_traits<Allocator>::difference_type     difference_type;
+   typedef typename allocator_traits<Allocator>::void_pointer        void_pointer;
+   typedef typename allocator_traits<Allocator>::const_void_pointer  const_void_pointer;
+
+   typedef typename allocator_traits<Allocator>::propagate_on_container_copy_assignment   propagate_on_container_copy_assignment;
+   typedef typename allocator_traits<Allocator>::propagate_on_container_move_assignment   propagate_on_container_move_assignment;
+   typedef typename allocator_traits<Allocator>::propagate_on_container_swap              propagate_on_container_swap;
+   //! An integral constant with member `value == false`
+   typedef BOOST_CONTAINER_IMPDEF(dtl::bool_<false>)                         is_always_equal;
+   //! An integral constant with member `value == true`
+   typedef BOOST_CONTAINER_IMPDEF(dtl::bool_<true>)                          is_partially_propagable;
+
+   BOOST_CONTAINER_DOCIGN(typedef dtl::version_type<small_vector_allocator BOOST_CONTAINER_I 1>  version;)
+
+   //!Obtains an small_vector_allocator that allocates
+   //!objects of type T2
+   template<class T2>
+   struct rebind
+   {
+      typedef typename allocator_traits<Allocator>::template rebind_alloc<T2>::type other;
+   };
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //!Constructor from arbitrary arguments
+      template<class ...Args>
+      BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator(BOOST_FWD_REF(Args) ...args)
+         : Allocator(::boost::forward<Args>(args)...)
+      {}
+   #else
+      #define BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE(N) \
+      BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+      BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator(BOOST_MOVE_UREF##N)\
+         : Allocator(BOOST_MOVE_FWD##N)\
+      {}\
+      //
+      BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE)
+      #undef BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE
+   #endif
+
+   //!Constructor from other small_vector_allocator.
+   //!Never throws
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator
+      (const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(other.as_base())
+   {}
+
+   //!Move constructor from small_vector_allocator.
+   //!Never throws
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator
+      (BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(::boost::move(other.as_base()))
+   {}
+
+   //!Constructor from related small_vector_allocator.
+   //!Never throws
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator
+      (const small_vector_allocator<OtherAllocator> &other) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(other.as_base())
+   {}
+
+   //!Move constructor from related small_vector_allocator.
+   //!Never throws
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator
+      (BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(::boost::move(other.as_base()))
+   {}
+
+   //!Assignment from other small_vector_allocator.
+   //!Never throws
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
+      operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base()));  }
+
+   //!Move constructor from other small_vector_allocator.
+   //!Never throws
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
+      operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base())));  }
+
+   //!Assignment from related small_vector_allocator.
+   //!Never throws
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
+      operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base()));  }
+
+   //!Move assignment from related small_vector_allocator.
+   //!Never throws
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
+      operator=(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base())));  }
+
+   //!Allocates storage from the standard-conforming allocator
+   BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type count, const_void_pointer hint = const_void_pointer())
+   {  return allocator_traits_type::allocate(this->as_base(), count, hint);  }
+
+   //!Deallocates previously allocated memory.
+   //!Never throws
+   void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if(!this->is_internal_storage(ptr))
+         allocator_traits_type::deallocate(this->as_base(), ptr, n);
+   }
+
+   //!Returns the maximum number of elements that could be allocated.
+   //!Never throws
+   BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return allocator_traits_type::max_size(this->as_base());   }
+
+   small_vector_allocator select_on_container_copy_construction() const
+   {  return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); }
+
+   bool storage_is_unpropagable(pointer p) const
+   {  return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p);  }
+
+   //!Swaps two allocators, does nothing
+   //!because this small_vector_allocator is stateless
+   BOOST_CONTAINER_FORCEINLINE friend void swap(small_vector_allocator &l, small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  boost::adl_move_swap(l.as_base(), r.as_base());  }
+
+   //!An small_vector_allocator always compares to true, as memory allocated with one
+   //!instance can be deallocated by another instance (except for unpropagable storage)
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return allocator_traits_type::equal(l.as_base(), r.as_base());  }
+
+   //!An small_vector_allocator always compares to false, as memory allocated with one
+   //!instance can be deallocated by another instance
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return !(l == r);   }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   /*
+   //!An advanced function that offers in-place expansion shrink to fit and new allocation
+   //!capabilities. Memory allocated with this function can only be deallocated with deallocate()
+   //!or deallocate_many().
+   //!This function is available only with Version == 2
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {  return allocator_traits_type::allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);  }
+
+   //!Returns maximum the number of objects the previously allocated memory
+   //!pointed by p can hold.
+   //!Memory must not have been allocated with
+   //!allocate_one or allocate_individual.
+   //!This function is available only with Version == 2
+   size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return allocator_traits_type::size(p);  }
+   */
+   private:
+   /*
+   //!Allocates just one object. Memory allocated with this function
+   //!must be deallocated only with deallocate_one().
+   //!Throws bad_alloc if there is no enough memory
+   //!This function is available only with Version == 2
+   using Allocator::allocate_one;
+   using Allocator::allocate_individual;
+   using Allocator::deallocate_one;
+   using Allocator::deallocate_individual;
+   using Allocator::allocate_many;
+   using Allocator::deallocate_many;*/
+
+   BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(pointer p) const
+   {  return this->internal_storage() == p;  }
+
+   pointer internal_storage() const
+   {
+      typedef typename Allocator::value_type                                              value_type;
+      typedef typename allocator_traits_type::size_type                                   size_type;
+      typedef vector_alloc_holder< small_vector_allocator<Allocator>, size_type >         vector_alloc_holder_t;
+      typedef vector<value_type, small_vector_allocator<Allocator> >                      vector_base;
+      typedef small_vector_base<value_type, Allocator>                                    derived_type;
+      //
+      const vector_alloc_holder_t &v_holder = static_cast<const vector_alloc_holder_t &>(*this);
+      const vector_base &v_base = reinterpret_cast<const vector_base &>(v_holder);
+      const derived_type &d_base = static_cast<const derived_type &>(v_base);
+      return d_base.internal_storage();
+   }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+//! This class consists of common code from all small_vector<T, N> types that don't depend on the
+//! "N" template parameter. This class is non-copyable and non-destructible, so this class typically
+//! used as reference argument to functions that read or write small vectors. Since `small_vector<T, N>`
+//! derives from `small_vector_base<T>`, the conversion to `small_vector_base` is implicit
+//! <pre>
+//!
+//! //Clients can pass any small_vector<Foo, N>.
+//! void read_any_small_vector_of_foo(const small_vector_base<Foo> &in_parameter);
+//!
+//! void modify_any_small_vector_of_foo(small_vector_base<Foo> &in_out_parameter);
+//!
+//! void some_function()
+//! {
+//! 
+//!    small_vector<Foo, 8> myvector;
+//!
+//!    read_any_small_vector_of_foo(myvector);   // Reads myvector
+//!
+//!    modify_any_small_vector_of_foo(myvector); // Modifies myvector
+//! 
+//! }
+//! </pre>
+//!
+//! All `boost::container:vector` member functions are inherited. See `vector` documentation for details.
+//!
+template <class T, class SecondaryAllocator>
+class small_vector_base
+   : public vector<T, small_vector_allocator<SecondaryAllocator> >
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   public:
+   //Make it public as it will be inherited by small_vector and container
+   //must have this public member
+   typedef typename allocator_traits<SecondaryAllocator>::pointer pointer;
+
+   private: 
+   BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
+
+   friend class small_vector_allocator<SecondaryAllocator>;
+
+   pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      return boost::intrusive::pointer_traits<pointer>::pointer_to
+         (*const_cast<T*>(static_cast<const T*>(static_cast<const void*>(m_storage_start.data))));
+   }
+
+   typedef vector<T, small_vector_allocator<SecondaryAllocator> > base_type;
+         base_type &as_base()       { return static_cast<base_type&>(*this); }
+   const base_type &as_base() const { return static_cast<const base_type&>(*this); }
+
+   public:
+   typedef typename dtl::aligned_storage
+      <sizeof(T), dtl::alignment_of<T>::value>::type storage_type;
+   typedef small_vector_allocator<SecondaryAllocator>             allocator_type;
+
+   protected:
+
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity)
+      : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity)
+   {}
+
+   template<class AllocFwd>
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t capacity, BOOST_FWD_REF(AllocFwd) a)
+      : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a))
+   {}
+
+   //~small_vector_base(){}
+
+   private:
+   //The only member
+   storage_type m_storage_start;
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   BOOST_CONTAINER_FORCEINLINE small_vector_base& operator=(BOOST_COPY_ASSIGN_REF(small_vector_base) other)
+   {  return static_cast<small_vector_base&>(this->base_type::operator=(static_cast<base_type const&>(other)));  }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector_base& operator=(BOOST_RV_REF(small_vector_base) other)
+   {  return static_cast<small_vector_base&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
+
+   BOOST_CONTAINER_FORCEINLINE void swap(small_vector_base &other)
+   {  return this->base_type::swap(other);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   protected:
+   void move_construct_impl(base_type &x, const allocator_type &a)
+   {
+      if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
+         this->steal_resources(x);
+      }
+      else{
+         this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
+                     , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end  ()))
+                     );
+      }
+   }
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+/////////////////////////////////////////////////////
+//
+//          small_vector_storage_calculator
+//
+/////////////////////////////////////////////////////
+template<std::size_t Needed, std::size_t Hdr, std::size_t SSize, bool NeedsZero = (0u == Needed || Needed <= Hdr)>
+struct small_vector_storage_calculator_helper
+{
+   static const std::size_t value = (Needed - Hdr - 1u)/SSize + 1u;
+};
+
+template<std::size_t Needed, std::size_t Hdr, std::size_t SSize>
+struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true>
+{
+   static const std::size_t value = 0u;
+};
+
+template<class Storage, class Allocator, class T, std::size_t N>
+struct small_vector_storage_calculator
+{
+   typedef small_vector_base<T, Allocator> svh_type;
+   typedef vector<T, small_vector_allocator<Allocator> > svhb_type;
+   static const std::size_t s_align = dtl::alignment_of<Storage>::value;
+   static const std::size_t s_size = sizeof(Storage);
+   static const std::size_t svh_sizeof = sizeof(svh_type);
+   static const std::size_t svhb_sizeof = sizeof(svhb_type);
+   static const std::size_t s_start = ((svhb_sizeof-1)/s_align+1)*s_align;
+   static const std::size_t header_bytes = svh_sizeof-s_start;
+   static const std::size_t needed_bytes = sizeof(T)*N;
+   static const std::size_t needed_extra_storages =
+      small_vector_storage_calculator_helper<needed_bytes, header_bytes, s_size>::value;
+};
+
+/////////////////////////////////////////////////////
+//
+//          small_vector_storage_definer
+//
+/////////////////////////////////////////////////////
+template<class Storage, std::size_t N>
+struct small_vector_storage
+{
+   Storage m_rest_of_storage[N];
+};
+
+template<class Storage>
+struct small_vector_storage<Storage, 0>
+{};
+
+template<class Allocator, std::size_t N>
+struct small_vector_storage_definer
+{
+   typedef typename Allocator::value_type                                  value_type;
+   typedef typename small_vector_base<value_type, Allocator>::storage_type storage_type;
+   static const std::size_t needed_extra_storages =
+      small_vector_storage_calculator<storage_type, Allocator, value_type, N>::needed_extra_storages;
+   typedef small_vector_storage<storage_type, needed_extra_storages> type;
+};
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! small_vector is a vector-like container optimized for the case when it contains few elements.
+//! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation
+//! when the actual number of elements is below that preallocated threshold.
+//!
+//! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent
+//! from the preallocated element capacity, so client code does not need to be templated on that N argument.
+//!
+//! All `boost::container::vector` member functions are inherited. See `vector` documentation for details.
+//!
+//! \tparam T The type of object that is stored in the small_vector
+//! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size();
+//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N.
+template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) >
+class small_vector : public small_vector_base<T, Allocator>
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   , private small_vector_storage_definer<Allocator, N>::type
+   #endif
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef small_vector_base<T, Allocator> base_type;
+   typedef typename small_vector_storage_definer<Allocator, N>::type remaining_storage_holder;
+
+   BOOST_COPYABLE_AND_MOVABLE(small_vector)
+
+   typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
+
+   public:
+   typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator>
+      ::storage_type, Allocator, T, N> storage_test;
+
+   static const std::size_t needed_extra_storages =  storage_test::needed_extra_storages;
+   static const std::size_t needed_bytes =  storage_test::needed_bytes;
+   static const std::size_t header_bytes =  storage_test::header_bytes;
+   static const std::size_t s_start =  storage_test::s_start;
+
+   typedef typename base_type::allocator_type   allocator_type;
+   typedef typename base_type::size_type        size_type;
+   typedef typename base_type::value_type       value_type;
+
+   BOOST_CONTAINER_FORCEINLINE static std::size_t internal_capacity()
+   {  return (sizeof(small_vector) - storage_test::s_start)/sizeof(T);  }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! @brief The capacity/max size of the container
+   static const size_type static_capacity = N;
+
+   public:
+   BOOST_CONTAINER_FORCEINLINE small_vector()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : base_type(initial_capacity_t(), internal_capacity())
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector(const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector(size_type n)
+      : base_type(initial_capacity_t(), internal_capacity())
+   {  this->resize(n); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->resize(n); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t)
+      : base_type(initial_capacity_t(), internal_capacity())
+   {  this->resize(n, default_init_t()); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t, const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->resize(n, default_init_t()); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v)
+      : base_type(initial_capacity_t(), internal_capacity())
+   {  this->resize(n, v); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v, const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->resize(n, v); }
+
+   template <class InIt>
+   BOOST_CONTAINER_FORCEINLINE small_vector(InIt first, InIt last
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+         < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+         BOOST_MOVE_I dtl::nat >::type * = 0)
+      )
+      : base_type(initial_capacity_t(), internal_capacity())
+   {  this->assign(first, last); }
+
+   template <class InIt>
+   BOOST_CONTAINER_FORCEINLINE small_vector(InIt first, InIt last, const allocator_type& a
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+         < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+         BOOST_MOVE_I dtl::nat >::type * = 0)
+      )
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->assign(first, last); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(const small_vector &other)
+      : base_type( initial_capacity_t(), internal_capacity()
+                 , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
+   {  this->assign(other.cbegin(), other.cend());  }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(const small_vector &other, const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->assign(other.cbegin(), other.cend());  }
+
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector(const base_type &other)
+      : base_type( initial_capacity_t(), internal_capacity()
+                 , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
+   {  this->assign(other.cbegin(), other.cend());  }
+
+   BOOST_CONTAINER_FORCEINLINE explicit small_vector(BOOST_RV_REF(base_type) other)
+      : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
+   {  this->move_construct_impl(other, other.get_stored_allocator());   }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(BOOST_RV_REF(small_vector) other)
+      : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
+   {  this->move_construct_impl(other, other.get_stored_allocator());   }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector(BOOST_RV_REF(small_vector) other, const allocator_type &a)
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {  this->move_construct_impl(other, a);   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   BOOST_CONTAINER_FORCEINLINE small_vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : base_type(initial_capacity_t(), internal_capacity(), a)
+   {
+      this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_COPY_ASSIGN_REF(small_vector) other)
+   {  return static_cast<small_vector&>(this->base_type::operator=(static_cast<base_type const&>(other)));  }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(small_vector) other)
+   {  return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector& operator=(const base_type &other)
+   {  return static_cast<small_vector&>(this->base_type::operator=(other));  }
+
+   BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(base_type) other)
+   {  return static_cast<small_vector&>(this->base_type::operator=(boost::move(other))); }
+
+   BOOST_CONTAINER_FORCEINLINE void swap(small_vector &other)
+   {  return this->base_type::swap(other);  }
+};
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+/*
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+*/
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //   #ifndef  BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp
new file mode 100644
index 0000000..41f45df
--- /dev/null
+++ b/include/boost/container/stable_vector.hpp
@@ -0,0 +1,2124 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Stable vector.
+//
+// Copyright 2008 Joaquin M Lopez Munoz.
+// 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
+#define BOOST_CONTAINER_STABLE_VECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/placement_new.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>   //pair
+// move
+#include <boost/move/utility_core.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/adl_move_swap.hpp>
+// move/detail
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   #include <boost/container/vector.hpp>
+   //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace stable_vector_detail{
+
+template <class C>
+class clear_on_destroy
+{
+   public:
+   clear_on_destroy(C &c)
+      :  c_(c), do_clear_(true)
+   {}
+
+   void release()
+   {  do_clear_ = false; }
+
+   ~clear_on_destroy()
+   {
+      if(do_clear_){
+         c_.clear();
+         c_.priv_clear_pool();
+      }
+   }
+
+   private:
+   clear_on_destroy(const clear_on_destroy &);
+   clear_on_destroy &operator=(const clear_on_destroy &);
+   C &c_;
+   bool do_clear_;
+};
+
+template<typename Pointer>
+struct node;
+
+template<class VoidPtr>
+struct node_base
+{
+   private:
+   typedef typename boost::intrusive::
+      pointer_traits<VoidPtr>                   void_ptr_traits;
+   typedef typename void_ptr_traits::
+      template rebind_pointer
+         <node_base>::type                      node_base_ptr;
+   typedef typename void_ptr_traits::
+      template rebind_pointer
+         <node_base_ptr>::type                  node_base_ptr_ptr;
+
+   public:
+   node_base(const node_base_ptr_ptr &n)
+      : up(n)
+   {}
+
+   node_base()
+      : up()
+   {}
+
+   node_base_ptr_ptr up;
+};
+
+template<typename Pointer>
+struct node
+   : public node_base
+      <typename ::boost::intrusive::pointer_traits<Pointer>::template
+         rebind_pointer<void>::type
+      >
+{
+   private:
+   node();
+
+   public:
+   typename ::boost::intrusive::pointer_traits<Pointer>::element_type value;
+};
+
+template<class VoidPtr, class VoidAllocator>
+struct index_traits
+{
+   typedef boost::intrusive::
+      pointer_traits
+         <VoidPtr>                                    void_ptr_traits;
+   typedef stable_vector_detail::
+      node_base<VoidPtr>                              node_base_type;
+   typedef typename void_ptr_traits::template
+         rebind_pointer<node_base_type>::type         node_base_ptr;
+   typedef typename void_ptr_traits::template
+         rebind_pointer<node_base_ptr>::type          node_base_ptr_ptr;
+   typedef boost::intrusive::
+      pointer_traits<node_base_ptr>                   node_base_ptr_traits;
+   typedef boost::intrusive::
+      pointer_traits<node_base_ptr_ptr>               node_base_ptr_ptr_traits;
+   typedef typename allocator_traits<VoidAllocator>::
+         template portable_rebind_alloc
+            <node_base_ptr>::type                     node_base_ptr_allocator;
+   typedef ::boost::container::vector
+      <node_base_ptr, node_base_ptr_allocator>        index_type;
+   typedef typename index_type::iterator              index_iterator;
+   typedef typename index_type::const_iterator        const_index_iterator;
+   typedef typename index_type::size_type             size_type;
+
+   static const size_type ExtraPointers = 3;
+   //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers:
+   //    back() is this->index.back() - ExtraPointers;
+   //    end node index is    *(this->index.end() - 3)
+   //    Node cache first is  *(this->index.end() - 2);
+   //    Node cache last is   this->index.back();
+
+   static node_base_ptr_ptr ptr_to_node_base_ptr(node_base_ptr &n)
+   {  return node_base_ptr_ptr_traits::pointer_to(n);   }
+
+   static void fix_up_pointers(index_iterator first, index_iterator last)
+   {
+      while(first != last){
+         typedef typename index_type::reference node_base_ptr_ref;
+         node_base_ptr_ref nbp = *first;
+         nbp->up = index_traits::ptr_to_node_base_ptr(nbp);
+         ++first;
+      }
+   }
+
+   static index_iterator get_fix_up_end(index_type &index)
+   {  return index.end() - (ExtraPointers - 1); }
+
+   static void fix_up_pointers_from(index_type & index, index_iterator first)
+   {  index_traits::fix_up_pointers(first, index_traits::get_fix_up_end(index));   }
+
+   static void readjust_end_node(index_type &index, node_base_type &end_node)
+   {
+      if(!index.empty()){
+         index_iterator end_node_it(index_traits::get_fix_up_end(index));
+         node_base_ptr &end_node_idx_ref = *(--end_node_it);
+         end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node);
+         end_node.up      = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref);
+      }
+      else{
+         end_node.up = node_base_ptr_ptr();
+      }
+   }
+
+   static void initialize_end_node(index_type &index, node_base_type &end_node, const size_type index_capacity_if_empty)
+   {
+      if(index.empty()){
+         index.reserve(index_capacity_if_empty + ExtraPointers);
+         index.resize(ExtraPointers);
+         node_base_ptr &end_node_ref = *index.data();
+         end_node_ref = node_base_ptr_traits::pointer_to(end_node);
+         end_node.up = index_traits::ptr_to_node_base_ptr(end_node_ref);
+      }
+   }
+
+   #ifdef STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+   static bool invariants(index_type &index)
+   {
+      for( index_iterator it = index.begin()
+         , it_end = index_traits::get_fix_up_end(index)
+         ; it != it_end
+         ; ++it){
+         if((*it)->up != index_traits::ptr_to_node_base_ptr(*it)){
+            return false;
+         }
+      }
+      return true;
+   }
+   #endif   //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+};
+
+} //namespace stable_vector_detail
+
+template<typename Pointer, bool IsConst>
+class stable_vector_iterator
+{
+   typedef boost::intrusive::pointer_traits<Pointer>                                non_const_ptr_traits;
+   public:
+   typedef std::random_access_iterator_tag                                          iterator_category;
+   typedef typename non_const_ptr_traits::element_type                              value_type;
+   typedef typename non_const_ptr_traits::difference_type                           difference_type;
+   typedef typename ::boost::container::dtl::if_c
+      < IsConst
+      , typename non_const_ptr_traits::template
+         rebind_pointer<const value_type>::type
+      , Pointer
+      >::type                                                                       pointer;
+   typedef boost::intrusive::pointer_traits<pointer>                                ptr_traits;
+   typedef typename ptr_traits::reference                                           reference;
+
+   private:
+   typedef typename non_const_ptr_traits::template
+         rebind_pointer<void>::type             void_ptr;
+   typedef stable_vector_detail::node<Pointer>         node_type;
+   typedef stable_vector_detail::node_base<void_ptr>   node_base_type;
+   typedef typename non_const_ptr_traits::template
+         rebind_pointer<node_type>::type        node_ptr;
+   typedef boost::intrusive::
+      pointer_traits<node_ptr>                  node_ptr_traits;
+   typedef typename non_const_ptr_traits::template
+         rebind_pointer<node_base_type>::type   node_base_ptr;
+   typedef typename non_const_ptr_traits::template
+         rebind_pointer<node_base_ptr>::type    node_base_ptr_ptr;
+
+   node_base_ptr m_pn;
+
+   public:
+
+   explicit stable_vector_iterator(node_base_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_pn(p)
+   {}
+
+   stable_vector_iterator() BOOST_NOEXCEPT_OR_NOTHROW
+      : m_pn() //Value initialization to achieve "null iterators" (N3644)
+   {}
+
+   stable_vector_iterator(stable_vector_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
+      :  m_pn(other.node_pointer())
+   {}
+
+   node_ptr node_pointer() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return node_ptr_traits::static_cast_from(m_pn);  }
+
+   public:
+   //Pointer like operators
+   reference operator*()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return  node_pointer()->value;  }
+
+   pointer   operator->() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return ptr_traits::pointer_to(this->operator*());  }
+
+   //Increment / Decrement
+   stable_vector_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      node_base_ptr_ptr p(this->m_pn->up);
+      this->m_pn = *(++p);
+      return *this;
+   }
+
+   stable_vector_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {  stable_vector_iterator tmp(*this);  ++*this; return stable_vector_iterator(tmp); }
+
+   stable_vector_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      node_base_ptr_ptr p(this->m_pn->up);
+      this->m_pn = *(--p);
+      return *this;
+   }
+
+   stable_vector_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {  stable_vector_iterator tmp(*this);  --*this; return stable_vector_iterator(tmp);  }
+
+   reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return node_ptr_traits::static_cast_from(this->m_pn->up[off])->value;  }
+
+   stable_vector_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if(off) this->m_pn = this->m_pn->up[off];
+      return *this;
+   }
+
+   friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      stable_vector_iterator tmp(left);
+      tmp += off;
+      return tmp;
+   }
+
+   friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      stable_vector_iterator tmp(right);
+      tmp += off;
+      return tmp;
+   }
+
+   stable_vector_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {  *this += -off; return *this;   }
+
+   friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      stable_vector_iterator tmp(left);
+      tmp -= off;
+      return tmp;
+   }
+
+   friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return left.m_pn->up - right.m_pn->up;  }
+
+   //Comparison operators
+   friend bool operator==   (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn == r.m_pn;  }
+
+   friend bool operator!=   (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn != r.m_pn;  }
+
+   friend bool operator<    (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn->up < r.m_pn->up;  }
+
+   friend bool operator<=   (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn->up <= r.m_pn->up;  }
+
+   friend bool operator>    (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn->up > r.m_pn->up;  }
+
+   friend bool operator>=   (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_pn->up >= r.m_pn->up;  }
+};
+
+   #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+      #define STABLE_VECTOR_CHECK_INVARIANT \
+               invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
+               BOOST_JOIN(check_invariant_,__LINE__).touch();
+
+   #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+
+      #define STABLE_VECTOR_CHECK_INVARIANT
+
+   #endif   //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
+//! drop-in replacement implemented as a node container, offering iterator and reference
+//! stability.
+//!
+//! Here are the details taken from the author's blog
+//! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
+//! Introducing stable_vector</a>):
+//!
+//! We present stable_vector, a fully STL-compliant stable container that provides
+//! most of the features of std::vector except element contiguity.
+//!
+//! General properties: stable_vector satisfies all the requirements of a container,
+//! a reversible container and a sequence and provides all the optional operations
+//! present in std::vector. Like std::vector, iterators are random access.
+//! stable_vector does not provide element contiguity; in exchange for this absence,
+//! the container is stable, i.e. references and iterators to an element of a stable_vector
+//! remain valid as long as the element is not erased, and an iterator that has been
+//! assigned the return value of end() always remain valid until the destruction of
+//! the associated  stable_vector.
+//!
+//! Operation complexity: The big-O complexities of stable_vector operations match
+//! exactly those of std::vector. In general, insertion/deletion is constant time at
+//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//! does not internally perform any value_type destruction, copy or assignment
+//! operations other than those exactly corresponding to the insertion of new
+//! elements or deletion of stored elements, which can sometimes compensate in terms
+//! of performance for the extra burden of doing more pointer manipulation and an
+//! additional allocation per element.
+//!
+//! Exception safety: As stable_vector does not internally copy elements around, some
+//! operations provide stronger exception safety guarantees than in std::vector.
+//!
+//! \tparam T The type of object that is stored in the stable_vector
+//! \tparam Allocator The allocator used for all internal memory management
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Allocator = new_allocator<T> >
+#else
+template <class T, class Allocator>
+#endif
+class stable_vector
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef allocator_traits<Allocator>                allocator_traits_type;
+   typedef boost::intrusive::
+      pointer_traits
+         <typename allocator_traits_type::pointer>    ptr_traits;
+   typedef typename ptr_traits::
+         template rebind_pointer<void>::type          void_ptr;
+   typedef typename allocator_traits_type::
+      template portable_rebind_alloc
+         <void>::type                                 void_allocator_type;
+   typedef stable_vector_detail::index_traits
+      <void_ptr, void_allocator_type>                 index_traits_type;
+   typedef typename index_traits_type::node_base_type node_base_type;
+   typedef typename index_traits_type::node_base_ptr  node_base_ptr;
+   typedef typename index_traits_type::
+      node_base_ptr_ptr                               node_base_ptr_ptr;
+   typedef typename index_traits_type::
+      node_base_ptr_traits                            node_base_ptr_traits;
+   typedef typename index_traits_type::
+      node_base_ptr_ptr_traits                        node_base_ptr_ptr_traits;
+   typedef typename index_traits_type::index_type     index_type;
+   typedef typename index_traits_type::index_iterator index_iterator;
+   typedef typename index_traits_type::
+      const_index_iterator                            const_index_iterator;
+   typedef stable_vector_detail::node
+      <typename ptr_traits::pointer>                  node_type;
+   typedef typename ptr_traits::template
+      rebind_pointer<node_type>::type                 node_ptr;
+   typedef boost::intrusive::
+      pointer_traits<node_ptr>                        node_ptr_traits;
+   typedef typename ptr_traits::template
+      rebind_pointer<const node_type>::type           const_node_ptr;
+   typedef boost::intrusive::
+      pointer_traits<const_node_ptr>                  const_node_ptr_traits;
+   typedef typename node_ptr_traits::reference        node_reference;
+   typedef typename const_node_ptr_traits::reference  const_node_reference;
+
+   typedef ::boost::container::dtl::integral_constant
+      <unsigned, boost::container::dtl::
+      version<Allocator>::value>                              alloc_version;
+   typedef typename allocator_traits_type::
+      template portable_rebind_alloc
+         <node_type>::type                            node_allocator_type;
+
+   typedef ::boost::container::dtl::
+      allocator_version_traits<node_allocator_type>                    allocator_version_traits_t;
+   typedef typename allocator_version_traits_t::multiallocation_chain  multiallocation_chain;
+
+   node_ptr allocate_one()
+   {  return allocator_version_traits_t::allocate_one(this->priv_node_alloc());   }
+
+   void deallocate_one(const node_ptr &p)
+   {  allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p);   }
+
+   void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m)
+   {  allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m);   }
+
+   void deallocate_individual(multiallocation_chain &holder)
+   {  allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder);   }
+
+   friend class stable_vector_detail::clear_on_destroy<stable_vector>;
+   typedef stable_vector_iterator
+      < typename allocator_traits<Allocator>::pointer
+      , false>                                           iterator_impl;
+   typedef stable_vector_iterator
+      < typename allocator_traits<Allocator>::pointer
+      , true>                                            const_iterator_impl;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   public:
+
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef T                                                                           value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef node_allocator_type                                                         stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(iterator_impl)                                       iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl)                                 const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(stable_vector)
+   static const size_type ExtraPointers = index_traits_type::ExtraPointers;
+
+   class insert_rollback;
+   friend class insert_rollback;
+
+   class push_back_rollback;
+   friend class push_back_rollback;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Default constructs a stable_vector.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   stable_vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : internal_data(), index()
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW
+      : internal_data(al), index(al)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector
+   //!   and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit stable_vector(size_type n)
+      : internal_data(), index()
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->resize(n);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   stable_vector(size_type n, default_init_t)
+      : internal_data(), index()
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->resize(n, default_init);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit stable_vector(size_type n, const allocator_type &a)
+      : internal_data(), index(a)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->resize(n);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   stable_vector(size_type n, default_init_t, const allocator_type &a)
+      : internal_data(), index(a)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->resize(n, default_init);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's default or copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
+      : internal_data(al), index(al)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->insert(this->cend(), n, t);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the stable_vector.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+   template <class InputIterator>
+   stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
+      : internal_data(al), index(al)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->insert(this->cend(), first, last);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Copy constructs a stable_vector.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   stable_vector(const stable_vector& x)
+      : internal_data(allocator_traits<node_allocator_type>::
+         select_on_container_copy_construction(x.priv_node_alloc()))
+      , index(allocator_traits<allocator_type>::
+         select_on_container_copy_construction(x.index.get_stored_allocator()))
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->insert(this->cend(), x.begin(), x.end());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+   //!  and inserts a copy of the range [il.begin(), il.last()) in the stable_vector
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor
+   //!   throws or T's constructor taking a dereferenced initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   stable_vector(std::initializer_list<value_type> il, const allocator_type& l = allocator_type())
+      : internal_data(l), index(l)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      insert(cend(), il.begin(), il.end());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+#endif
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   stable_vector(BOOST_RV_REF(stable_vector) x) BOOST_NOEXCEPT_OR_NOTHROW
+      : internal_data(boost::move(x.priv_node_alloc())), index(boost::move(x.index))
+   {
+      this->priv_swap_members(x);
+   }
+
+   //! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   stable_vector(const stable_vector& x, const allocator_type &a)
+      : internal_data(a), index(a)
+   {
+      stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+      this->insert(this->cend(), x.begin(), x.end());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
+   stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
+      : internal_data(a), index(a)
+   {
+      if(this->priv_node_alloc() == x.priv_node_alloc()){
+         this->index.swap(x.index);         
+         this->priv_swap_members(x);
+      }
+      else{
+         stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+         this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
+         STABLE_VECTOR_CHECK_INVARIANT;
+         cod.release();
+      }
+   }
+
+   //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements.
+   ~stable_vector()
+   {
+      this->clear();
+      this->priv_clear_pool();
+   }
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if (&x != this){
+         node_allocator_type &this_alloc     = this->priv_node_alloc();
+         const node_allocator_type &x_alloc  = x.priv_node_alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+            this->shrink_to_fit();
+         }
+         dtl::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
+         dtl::assign_alloc(this->index.get_stored_allocator(), x.index.get_stored_allocator(), flag);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
+   //!
+   //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or T's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      //for move constructor, no aliasing (&x != this) is assummed.
+      BOOST_ASSERT(this != &x);
+      node_allocator_type &this_alloc = this->priv_node_alloc();
+      node_allocator_type &x_alloc    = x.priv_node_alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      dtl::bool_<propagate_alloc> flag;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         STABLE_VECTOR_CHECK_INVARIANT
+         //Destroy objects but retain memory in case x reuses it in the future
+         this->clear();
+         //Move allocator if needed
+         dtl::move_alloc(this_alloc, x_alloc, flag);
+         //Take resources
+         this->index.swap(x.index);
+         this->priv_swap_members(x);
+      }
+      //Else do a one by one move
+      else{
+         this->assign( boost::make_move_iterator(x.begin())
+                     , boost::make_move_iterator(x.end()));
+      }
+      return *this;
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Make *this container contains elements from il.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   stable_vector& operator=(std::initializer_list<value_type> il)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      assign(il.begin(), il.end());
+      return *this;
+   }
+#endif
+
+   //! <b>Effects</b>: Assigns the n copies of val to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   void assign(size_type n, const T& t)
+   {
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      this->assign(cvalue_iterator(t, n), cvalue_iterator());
+   }
+
+   //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template<typename InputIterator>
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   typename dtl::disable_if_convertible<InputIterator, size_type>::type
+   #else
+   void
+   #endif
+      assign(InputIterator first,InputIterator last)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      iterator first1   = this->begin();
+      iterator last1    = this->end();
+      for ( ; first1 != last1 && first != last; ++first1, ++first)
+         *first1 = *first;
+      if (first == last){
+         this->erase(first1, last1);
+      }
+      else{
+         this->insert(last1, first, last);
+      }
+   }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing initializer_list iterator throws.
+   //!
+   void assign(std::initializer_list<value_type> il)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      assign(il.begin(), il.end());
+   }
+#endif
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const
+   {  return this->priv_node_alloc();  }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->priv_node_alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->priv_node_alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator  begin() BOOST_NOEXCEPT_OR_NOTHROW
+   {   return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator  begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {   return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ;   }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator        end() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return iterator(this->priv_get_end_node());  }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator  end() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_iterator(this->priv_get_end_node());  }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator       rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return reverse_iterator(this->end());  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_reverse_iterator(this->end());  }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator       rend() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return reverse_iterator(this->begin());   }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_reverse_iterator(this->begin());   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator         cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->begin();   }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator         cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->end();  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->rbegin();  }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend()const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->rend(); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->index.size() <= ExtraPointers;  }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const size_type index_size = this->index.size();
+      return (index_size - ExtraPointers) & (size_type(0u) -size_type(index_size != 0));
+   }
+
+   //! <b>Effects</b>: Returns the largest possible size of the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->index.max_size() - ExtraPointers;  }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n)
+   {
+      typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > this->size())
+         this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
+      else if(n < this->size())
+         this->erase(this->cbegin() + n, this->cend());
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's default initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void resize(size_type n, default_init_t)
+   {
+      typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > this->size())
+         this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
+      else if(n < this->size())
+         this->erase(this->cbegin() + n, this->cend());
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n, const T& t)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > this->size())
+         this->insert(this->cend(), n - this->size(), t);
+      else if(n < this->size())
+         this->erase(this->cbegin() + n, this->cend());
+   }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const size_type index_size             = this->index.size();
+      BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
+      const size_type node_extra_capacity   = this->internal_data.pool_size;
+      //Pool count must be less than index capacity, as index is a vector
+      BOOST_ASSERT(node_extra_capacity <= (this->index.capacity()- index_size));
+      const size_type index_offset =
+         (node_extra_capacity - ExtraPointers) & (size_type(0u) - size_type(index_size != 0));
+      return index_size + index_offset;
+   }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws.
+   void reserve(size_type n)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > this->max_size()){
+         throw_length_error("stable_vector::reserve max_size() exceeded");
+      }
+
+      size_type sz         = this->size();
+      size_type old_capacity = this->capacity();
+      if(n > old_capacity){
+         index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n);
+         const void * old_ptr = &index[0];
+         this->index.reserve(n + ExtraPointers);
+         bool realloced = &index[0] != old_ptr;
+         //Fix the pointers for the newly allocated buffer
+         if(realloced){
+            index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
+         }
+         //Now fill pool if data is not enough
+         if((n - sz) > this->internal_data.pool_size){
+            this->priv_increase_pool((n - sz) - this->internal_data.pool_size);
+         }
+      }
+   }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the stable_vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   void shrink_to_fit()
+   {
+      if(this->capacity()){
+         //First empty allocated node pool
+         this->priv_clear_pool();
+         //If empty completely destroy the index, let's recover default-constructed state
+         if(this->empty()){
+            this->index.clear();
+            this->index.shrink_to_fit();
+            this->internal_data.end_node.up = node_base_ptr_ptr();
+         }
+         //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
+         else{
+            const void* old_ptr = &index[0];
+            this->index.shrink_to_fit();
+            bool realloced = &index[0] != old_ptr;
+            //Fix the pointers for the newly allocated buffer
+            if(realloced){
+               index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
+            }
+         }
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return static_cast<node_reference>(*this->index.front()).value;
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return static_cast<const_node_reference>(*this->index.front()).value;
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return static_cast<node_reference>(*this->index[this->size()-1u]).value;
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return static_cast<const_node_reference>(*this->index[this->size()-1u]).value;
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return static_cast<node_reference>(*this->index[n]).value;
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return static_cast<const_node_reference>(*this->index[n]).value;
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns an iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() >= n);
+      return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns a const_iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() >= n);
+      return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
+   }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->priv_index_of(p.node_pointer());  }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->priv_index_of(p.node_pointer());  }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference at(size_type n)
+   {
+      if(n >= this->size()){
+         throw_out_of_range("vector::at invalid subscript");
+      }
+      return operator[](n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference at(size_type n)const
+   {
+      if(n >= this->size()){
+         throw_out_of_range("vector::at invalid subscript");
+      }
+      return operator[](n);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the end of the stable_vector.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   template<class ...Args>
+   reference emplace_back(Args &&...args)
+   {
+      typedef emplace_functor<Args...>         EmplaceFunctor;
+      typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
+      EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+      return *this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... before p
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   template<class ...Args>
+   iterator emplace(const_iterator p, Args && ...args)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      size_type pos_n = p - cbegin();
+      typedef emplace_functor<Args...>         EmplaceFunctor;
+      typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
+      EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+      this->insert(p, EmplaceIterator(ef), EmplaceIterator());
+      return iterator(this->begin() + pos_n);
+   }
+
+   #else
+
+   #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   reference emplace_back(BOOST_MOVE_UREF##N)\
+   {\
+      typedef emplace_functor##N\
+         BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
+      typedef emplace_iterator<value_type, EmplaceFunctor, difference_type>  EmplaceIterator;\
+      EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
+      return *this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      BOOST_ASSERT(this->priv_in_range_or_end(p));\
+      typedef emplace_functor##N\
+         BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
+      typedef emplace_iterator<value_type, EmplaceFunctor, difference_type>  EmplaceIterator;\
+      EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
+      const size_type pos_n = p - this->cbegin();\
+      this->insert(p, EmplaceIterator(ef), EmplaceIterator());\
+      return this->begin() += pos_n;\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE
+
+   #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the end of the stable_vector
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of x before p.
+   //!
+   //! <b>Returns</b>: An iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator p, const T &x);
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a new element before p with x's resources.
+   //!
+   //! <b>Returns</b>: an iterator to the inserted element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: If p is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator p, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert n copies of x before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   iterator insert(const_iterator p, size_type n, const T& t)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      STABLE_VECTOR_CHECK_INVARIANT;
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->insert(p, cvalue_iterator(t, n), cvalue_iterator());
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   //!
+   //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
+   iterator insert(const_iterator p, std::initializer_list<value_type> il)
+   {
+      //Position checks done by insert()
+      STABLE_VECTOR_CHECK_INVARIANT;
+      return insert(p, il.begin(), il.end());
+   }
+#endif
+
+   //! <b>Requires</b>: pos must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to distance [first, last).
+   template <class InputIterator>
+   iterator insert(const_iterator p, InputIterator first, InputIterator last
+         #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+         //Put this as argument instead of the return type as old GCC's like 3.4
+         //detect this and the next disable_if_or as overloads
+         ,  typename dtl::disable_if_or
+               < void
+               , dtl::is_convertible<InputIterator, size_type>
+               , dtl::is_not_input_iterator<InputIterator>
+               >::type* = 0
+         #endif
+         )
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      STABLE_VECTOR_CHECK_INVARIANT;
+      const size_type pos_n = p - this->cbegin();
+      for(; first != last; ++first){
+         this->emplace(p, *first);
+      }
+      return this->begin() + pos_n;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   typename dtl::disable_if_or
+      < iterator
+      , dtl::is_convertible<FwdIt, size_type>
+      , dtl::is_input_iterator<FwdIt>
+      >::type
+      insert(const_iterator p, FwdIt first, FwdIt last)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      const size_type num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
+      const size_type idx     = static_cast<size_type>(p - this->cbegin());
+      if(num_new){
+         //Fills the node pool and inserts num_new null pointers in idx.
+         //If a new buffer was needed fixes up pointers up to idx so
+         //past-new nodes are not aligned until the end of this function
+         //or in a rollback in case of exception
+         index_iterator it_past_newly_constructed(this->priv_insert_forward_non_templated(idx, num_new));
+         const index_iterator it_past_new(it_past_newly_constructed + num_new);
+         {
+            //Prepare rollback
+            insert_rollback rollback(*this, it_past_newly_constructed, it_past_new);
+            while(first != last){
+               const node_ptr n = this->priv_get_from_pool();
+               BOOST_ASSERT(!!n);
+               //Put it in the index so rollback can return it in pool if construct_in_place throws
+               *it_past_newly_constructed = n;
+               //Constructs and fixes up pointers This can throw
+               this->priv_build_node_from_it(n, it_past_newly_constructed, first);
+               ++first;
+               ++it_past_newly_constructed;
+            }
+            //rollback.~insert_rollback() called in case of exception
+         }
+         //Fix up pointers for past-new nodes (new nodes were fixed during construction) and
+         //nodes before insertion p in priv_insert_forward_non_templated(...)
+         index_traits_type::fix_up_pointers_from(this->index, it_past_newly_constructed);
+      }
+      return this->begin() + idx;
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the last element from the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      this->erase(--this->cend());
+   }
+
+   //! <b>Effects</b>: Erases the element at p.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the elements between p and the
+   //!   last element. Constant if p is the last element.
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->priv_in_range(p));
+      STABLE_VECTOR_CHECK_INVARIANT;
+      const size_type d = p - this->cbegin();
+      index_iterator it = this->index.begin() + d;
+      this->priv_delete_node(p.node_pointer());
+      it = this->index.erase(it);
+      index_traits_type::fix_up_pointers_from(this->index, it);
+      return iterator(node_ptr_traits::static_cast_from(*it));
+   }
+
+   //! <b>Effects</b>: Erases the elements pointed by [first, last).
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the distance between first and last
+   //!   plus linear to the elements between p and the last element.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(first == last ||
+         (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
+      STABLE_VECTOR_CHECK_INVARIANT;
+      const const_iterator cbeg(this->cbegin());
+      const size_type d1 = static_cast<size_type>(first - cbeg),
+                      d2 = static_cast<size_type>(last  - cbeg);
+      size_type d_dif = d2 - d1;
+      if(d_dif){
+         multiallocation_chain holder;
+         const index_iterator it1(this->index.begin() + d1);
+         const index_iterator it2(it1 + d_dif);
+         index_iterator it(it1);
+         while(d_dif--){
+            node_base_ptr &nb = *it;
+            ++it;
+            node_type &n = *node_ptr_traits::static_cast_from(nb);
+            this->priv_destroy_node(n);
+            holder.push_back(node_ptr_traits::pointer_to(n));
+         }
+         this->priv_put_in_pool(holder);
+         const index_iterator e = this->index.erase(it1, it2);
+         index_traits_type::fix_up_pointers_from(this->index, e);
+      }
+      return iterator(last.node_pointer());
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   void swap(stable_vector & x)
+      BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
+                                || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
+                   allocator_traits_type::is_always_equal::value ||
+                   this->get_stored_allocator() == x.get_stored_allocator());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+      dtl::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
+      //vector's allocator is swapped here
+      this->index.swap(x.index);
+      this->priv_swap_members(x);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the stable_vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {   this->erase(this->cbegin(),this->cend()); }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator==(const stable_vector& x, const stable_vector& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator!=(const stable_vector& x, const stable_vector& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const stable_vector& x, const stable_vector& y)
+   {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>(const stable_vector& x, const stable_vector& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<=(const stable_vector& x, const stable_vector& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator>=(const stable_vector& x, const stable_vector& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   friend void swap(stable_vector& x, stable_vector& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+
+   bool priv_in_range(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos < this->end());
+   }
+
+   bool priv_in_range_or_end(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos <= this->end());
+   }
+
+   size_type priv_index_of(node_ptr p) const
+   {
+      //Check range
+      BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up));
+      BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size()));
+      return this->index.empty() ? 0 : p->up - this->index.data();
+   }
+
+   class insert_rollback
+   {
+      public:
+
+      insert_rollback(stable_vector &sv, index_iterator &it_past_constructed, const index_iterator &it_past_new)
+         : m_sv(sv), m_it_past_constructed(it_past_constructed), m_it_past_new(it_past_new)
+      {}
+
+      ~insert_rollback()
+      {
+         if(m_it_past_constructed != m_it_past_new){
+            m_sv.priv_put_in_pool(node_ptr_traits::static_cast_from(*m_it_past_constructed));
+            index_iterator e = m_sv.index.erase(m_it_past_constructed, m_it_past_new);
+            index_traits_type::fix_up_pointers_from(m_sv.index, e);
+         }
+      }
+
+      private:
+      stable_vector &m_sv;
+      index_iterator &m_it_past_constructed;
+      const index_iterator &m_it_past_new;
+   };
+
+   class push_back_rollback
+   {
+      public:
+      push_back_rollback(stable_vector &sv, const node_ptr &p)
+         : m_sv(sv), m_p(p)
+      {}
+
+      ~push_back_rollback()
+      {
+         if(m_p){
+            m_sv.priv_put_in_pool(m_p);
+         }
+      }
+
+      void release()
+      {  m_p = node_ptr();  }
+
+      private:
+      stable_vector &m_sv;
+      node_ptr m_p;
+   };
+
+   index_iterator priv_insert_forward_non_templated(size_type idx, size_type num_new)
+   {
+      index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, num_new);
+
+      //Now try to fill the pool with new data
+      if(this->internal_data.pool_size < num_new){
+         this->priv_increase_pool(num_new - this->internal_data.pool_size);
+      }
+
+      //Now try to make room in the vector
+      const node_base_ptr_ptr old_buffer = this->index.data();
+      this->index.insert(this->index.begin() + idx, num_new, node_ptr());
+      bool new_buffer = this->index.data() != old_buffer;
+
+      //Fix the pointers for the newly allocated buffer
+      const index_iterator index_beg = this->index.begin();
+      if(new_buffer){
+         index_traits_type::fix_up_pointers(index_beg, index_beg + idx);
+      }
+      return index_beg + idx;
+   }
+
+   bool priv_capacity_bigger_than_size() const
+   {
+      return this->index.capacity() > this->index.size() &&
+             this->internal_data.pool_size > 0;
+   }
+
+   template <class U>
+   void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+   {
+      if(BOOST_LIKELY(this->priv_capacity_bigger_than_size())){
+         //Enough memory in the pool and in the index
+         const node_ptr p = this->priv_get_from_pool();
+         BOOST_ASSERT(!!p);
+         {
+            push_back_rollback rollback(*this, p);
+            //This might throw
+            this->priv_build_node_from_convertible(p, ::boost::forward<U>(x));
+            rollback.release();
+         }
+         //This can't throw as there is room for a new elements in the index
+         index_iterator new_index = this->index.insert(this->index.end() - ExtraPointers, p);
+         index_traits_type::fix_up_pointers_from(this->index, new_index);
+      }
+      else{
+         this->insert(this->cend(), ::boost::forward<U>(x));
+      }
+   }
+
+   iterator priv_insert(const_iterator p, const value_type &t)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+      return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator());
+   }
+
+   iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      typedef repeat_iterator<T, difference_type>  repeat_it;
+      typedef boost::move_iterator<repeat_it>      repeat_move_it;
+      //Just call more general insert(p, size, value) and return iterator
+      return this->insert(p, repeat_move_it(repeat_it(x, 1)), repeat_move_it(repeat_it()));
+   }
+
+   void priv_clear_pool()
+   {
+      if(!this->index.empty() && this->index.back()){
+         node_base_ptr &pool_first_ref = *(this->index.end() - 2);
+         node_base_ptr &pool_last_ref  = this->index.back();
+
+         multiallocation_chain holder;
+         holder.incorporate_after( holder.before_begin()
+                                 , node_ptr_traits::static_cast_from(pool_first_ref)
+                                 , node_ptr_traits::static_cast_from(pool_last_ref)
+                                 , internal_data.pool_size);
+         this->deallocate_individual(holder);
+         pool_first_ref = pool_last_ref = 0;
+         this->internal_data.pool_size = 0;
+      }
+   }
+
+   void priv_increase_pool(size_type n)
+   {
+      node_base_ptr &pool_first_ref = *(this->index.end() - 2);
+      node_base_ptr &pool_last_ref  = this->index.back();
+      multiallocation_chain holder;
+      holder.incorporate_after( holder.before_begin()
+                              , node_ptr_traits::static_cast_from(pool_first_ref)
+                              , node_ptr_traits::static_cast_from(pool_last_ref)
+                              , internal_data.pool_size);
+      multiallocation_chain m;
+      this->allocate_individual(n, m);
+      holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
+      this->internal_data.pool_size += n;
+      std::pair<node_ptr, node_ptr> data(holder.extract_data());
+      pool_first_ref = data.first;
+      pool_last_ref = data.second;
+   }
+
+   void priv_put_in_pool(const node_ptr &p)
+   {
+      node_base_ptr &pool_first_ref = *(this->index.end()-2);
+      node_base_ptr &pool_last_ref  = this->index.back();
+      multiallocation_chain holder;
+      holder.incorporate_after( holder.before_begin()
+                              , node_ptr_traits::static_cast_from(pool_first_ref)
+                              , node_ptr_traits::static_cast_from(pool_last_ref)
+                              , internal_data.pool_size);
+      holder.push_front(p);
+      ++this->internal_data.pool_size;
+      std::pair<node_ptr, node_ptr> ret(holder.extract_data());
+      pool_first_ref = ret.first;
+      pool_last_ref  = ret.second;
+   }
+
+   void priv_put_in_pool(multiallocation_chain &ch)
+   {
+      node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1));
+      node_base_ptr &pool_last_ref  = this->index.back();
+      ch.incorporate_after( ch.before_begin()
+                          , node_ptr_traits::static_cast_from(pool_first_ref)
+                          , node_ptr_traits::static_cast_from(pool_last_ref)
+                          , internal_data.pool_size);
+      this->internal_data.pool_size = ch.size();
+      const std::pair<node_ptr, node_ptr> ret(ch.extract_data());
+      pool_first_ref = ret.first;
+      pool_last_ref  = ret.second;
+   }
+
+   node_ptr priv_get_from_pool()
+   {
+      //Precondition: index is not empty
+      BOOST_ASSERT(!this->index.empty());
+      node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1));
+      node_base_ptr &pool_last_ref  = this->index.back();
+      multiallocation_chain holder;
+      holder.incorporate_after( holder.before_begin()
+                              , node_ptr_traits::static_cast_from(pool_first_ref)
+                              , node_ptr_traits::static_cast_from(pool_last_ref)
+                              , internal_data.pool_size);
+      node_ptr ret = holder.pop_front();
+      --this->internal_data.pool_size;
+      if(!internal_data.pool_size){
+         pool_first_ref = pool_last_ref = node_ptr();
+      }
+      else{
+         const std::pair<node_ptr, node_ptr> data(holder.extract_data());
+         pool_first_ref = data.first;
+         pool_last_ref  = data.second;
+      }
+      return ret;
+   }
+
+   node_base_ptr priv_get_end_node() const
+   {  return node_base_ptr_traits::pointer_to(const_cast<node_base_type&>(this->internal_data.end_node));  }
+
+   void priv_destroy_node(const node_type &n)
+   {
+      allocator_traits<node_allocator_type>::
+         destroy(this->priv_node_alloc(), dtl::addressof(n.value));
+      static_cast<const node_base_type*>(&n)->~node_base_type();
+   }
+
+   void priv_delete_node(const node_ptr &n)
+   {
+      this->priv_destroy_node(*n);
+      this->priv_put_in_pool(n);
+   }
+
+   template<class Iterator>
+   void priv_build_node_from_it(const node_ptr &p, const index_iterator &up_index, const Iterator &it)
+   {
+      //This can throw
+      boost::container::construct_in_place
+         ( this->priv_node_alloc()
+         , dtl::addressof(p->value)
+         , it);
+      //This does not throw
+      ::new(static_cast<node_base_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t())
+         node_base_type(index_traits_type::ptr_to_node_base_ptr(*up_index));
+   }
+
+   template<class ValueConvertible>
+   void priv_build_node_from_convertible(const node_ptr &p, BOOST_FWD_REF(ValueConvertible) value_convertible)
+   {
+      //This can throw
+      boost::container::allocator_traits<node_allocator_type>::construct
+         ( this->priv_node_alloc()
+         , dtl::addressof(p->value)
+         , ::boost::forward<ValueConvertible>(value_convertible));
+      //This does not throw
+      ::new(static_cast<node_base_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
+   }
+
+   void priv_swap_members(stable_vector &x)
+   {
+      boost::adl_move_swap(this->internal_data.pool_size, x.internal_data.pool_size);
+      index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
+      index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
+   }
+
+   #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+   bool priv_invariant()const
+   {
+      index_type & index_ref =  const_cast<index_type&>(this->index);
+
+      const size_type index_size = this->index.size();
+      if(!index_size)
+         return !this->capacity() && !this->size();
+
+      if(index_size < ExtraPointers)
+         return false;
+
+      const size_type bucket_extra_capacity = this->index.capacity()- index_size;
+      const size_type node_extra_capacity   = this->internal_data.pool_size;
+      if(bucket_extra_capacity < node_extra_capacity){
+         return false;
+      }
+
+      if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){
+         return false;
+      }
+
+      if(!index_traits_type::invariants(index_ref)){
+         return false;
+      }
+
+      size_type n = this->capacity() - this->size();
+      node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1));
+      node_base_ptr &pool_last_ref  = index_ref.back();
+      multiallocation_chain holder;
+      holder.incorporate_after( holder.before_begin()
+                              , node_ptr_traits::static_cast_from(pool_first_ref)
+                              , node_ptr_traits::static_cast_from(pool_last_ref)
+                              , internal_data.pool_size);
+      typename multiallocation_chain::iterator beg(holder.begin()), end(holder.end());
+      size_type num_pool = 0;
+      while(beg != end){
+         ++num_pool;
+         ++beg;
+      }
+      return n >= num_pool && num_pool == internal_data.pool_size;
+   }
+
+   class invariant_checker
+   {
+      invariant_checker(const invariant_checker &);
+      invariant_checker & operator=(const invariant_checker &);
+      const stable_vector* p;
+
+      public:
+      invariant_checker(const stable_vector& v):p(&v){}
+      ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());}
+      void touch(){}
+   };
+   #endif
+
+   class ebo_holder
+      : public node_allocator_type
+   {
+      private:
+      BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
+
+      public:
+      template<class AllocatorRLValue>
+      explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
+         : node_allocator_type(boost::forward<AllocatorRLValue>(a))
+         , pool_size(0)
+         , end_node()
+      {}
+
+      ebo_holder()
+         : node_allocator_type()
+         , pool_size(0)
+         , end_node()
+      {}
+
+      size_type pool_size;
+      node_base_type end_node;
+   } internal_data;
+
+   node_allocator_type &priv_node_alloc()              { return internal_data;  }
+   const node_allocator_type &priv_node_alloc() const  { return internal_data;  }
+
+   index_type                           index;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+stable_vector(InputIterator, InputIterator) ->
+   stable_vector<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+stable_vector(InputIterator, InputIterator, Allocator const&) ->
+   stable_vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
+
+#endif
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#undef STABLE_VECTOR_CHECK_INVARIANT
+
+}  //namespace container {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+namespace container {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}} //namespace boost{  namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif   //BOOST_CONTAINER_STABLE_VECTOR_HPP
diff --git a/include/boost/container/static_vector.hpp b/include/boost/container/static_vector.hpp
new file mode 100644
index 0000000..b40d5c3
--- /dev/null
+++ b/include/boost/container/static_vector.hpp
@@ -0,0 +1,1242 @@
+// Boost.Container static_vector
+//
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2013 Andrew Hundt.
+// Copyright (c) 2013-2014 Ion Gaztanaga
+//
+// Use, modification and distribution is subject to 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)
+
+#ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP
+#define BOOST_CONTAINER_STATIC_VECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/vector.hpp>
+
+#include <cstddef>
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+namespace boost { namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace dtl {
+
+template<class T, std::size_t N>
+class static_storage_allocator
+{
+   public:
+   typedef T value_type;
+
+   BOOST_CONTAINER_FORCEINLINE static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE static_storage_allocator(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE static_storage_allocator & operator=(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(storage.data)));  }
+
+   BOOST_CONTAINER_FORCEINLINE T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return static_cast<T*>(static_cast<void*>(storage.data));  }
+
+   static const std::size_t internal_capacity = N;
+
+   std::size_t max_size() const
+   {  return N;   }
+
+   typedef boost::container::dtl::version_type<static_storage_allocator, 0>   version;
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return false;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return true;  }
+
+   private:
+   typename aligned_storage<sizeof(T)*N, alignment_of<T>::value>::type storage;
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//!
+//!@brief A variable-size array container with fixed capacity.
+//!
+//!static_vector is a sequence container like boost::container::vector with contiguous storage that can
+//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
+//!
+//!A static_vector is a sequence that supports random access to elements, constant time insertion and
+//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or
+//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
+//!because elements are stored within the object itself similarly to an array. However, objects are
+//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
+//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated
+//!elements in cases with complex object lifetime requirements that would otherwise not be trivially
+//!possible.
+//!
+//!@par Error Handling
+//! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
+//! calling throw_bad_alloc() if not enabled.
+//!
+//! std::out_of_range is thrown if out of bound access is performed in <code>at()</code> if exceptions are
+//! enabled, throw_out_of_range() if not enabled.
+//!
+//!@tparam Value    The type of element that will be stored.
+//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
+template <typename Value, std::size_t Capacity>
+class static_vector
+    : public vector<Value, dtl::static_storage_allocator<Value, Capacity> >
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   typedef vector<Value, dtl::static_storage_allocator<Value, Capacity> > base_t;
+
+   BOOST_COPYABLE_AND_MOVABLE(static_vector)
+
+   template<class U, std::size_t OtherCapacity>
+   friend class static_vector;
+
+   public:
+   typedef dtl::static_storage_allocator<Value, Capacity> allocator_type;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+public:
+    //! @brief The type of elements stored in the container.
+    typedef typename base_t::value_type value_type;
+    //! @brief The unsigned integral type used by the container.
+    typedef typename base_t::size_type size_type;
+    //! @brief The pointers difference type.
+    typedef typename base_t::difference_type difference_type;
+    //! @brief The pointer type.
+    typedef typename base_t::pointer pointer;
+    //! @brief The const pointer type.
+    typedef typename base_t::const_pointer const_pointer;
+    //! @brief The value reference type.
+    typedef typename base_t::reference reference;
+    //! @brief The value const reference type.
+    typedef typename base_t::const_reference const_reference;
+    //! @brief The iterator type.
+    typedef typename base_t::iterator iterator;
+    //! @brief The const iterator type.
+    typedef typename base_t::const_iterator const_iterator;
+    //! @brief The reverse iterator type.
+    typedef typename base_t::reverse_iterator reverse_iterator;
+    //! @brief The const reverse iterator.
+    typedef typename base_t::const_reverse_iterator const_reverse_iterator;
+
+    //! @brief The capacity/max size of the container
+    static const size_type static_capacity = Capacity;
+
+    //! @brief Constructs an empty static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    BOOST_CONTAINER_FORCEINLINE static_vector() BOOST_NOEXCEPT_OR_NOTHROW
+        : base_t()
+    {}
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Constructs a static_vector containing count value initialized values.
+    //!
+    //! @param count    The number of values which will be contained in the container.
+    //!
+    //! @par Throws
+    //!   If Value's value initialization throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE explicit static_vector(size_type count)
+        : base_t(count)
+    {}
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Constructs a static_vector containing count default initialized values.
+    //!
+    //! @param count    The number of values which will be contained in the container.
+    //!
+    //! @par Throws
+    //!   If Value's default initialization throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    //!
+    //! @par Note
+    //!   Non-standard extension
+    BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, default_init_t)
+        : base_t(count, default_init_t())
+    {}
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Constructs a static_vector containing count copies of value.
+    //!
+    //! @param count    The number of copies of a values that will be contained in the container.
+    //! @param value    The value which will be used to copy construct values.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, value_type const& value)
+        : base_t(count, value)
+    {}
+
+    //! @pre
+    //!  @li <tt>distance(first, last) <= capacity()</tt>
+    //!  @li Iterator must meet the \c ForwardTraversalIterator concept.
+    //!
+    //! @brief Constructs a static_vector containing copy of a range <tt>[first, last)</tt>.
+    //!
+    //! @param first    The iterator to the first element in range.
+    //! @param last     The iterator to the one after the last element in range.
+    //!
+    //! @par Throws
+    //!   If Value's constructor taking a dereferenced Iterator throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    BOOST_CONTAINER_FORCEINLINE static_vector(Iterator first, Iterator last)
+        : base_t(first, last)
+    {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+    //! @pre
+    //!  @li <tt>distance(il.begin(), il.end()) <= capacity()</tt>
+    //!
+    //! @brief Constructs a static_vector containing copy of a range <tt>[il.begin(), il.end())</tt>.
+    //!
+    //! @param il       std::initializer_list with values to initialize vector.
+    //!
+    //! @par Throws
+    //!   If Value's constructor taking a dereferenced std::initializer_list throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector(std::initializer_list<value_type> il)
+        : base_t(il)
+    {}
+#endif
+
+    //! @brief Constructs a copy of other static_vector.
+    //!
+    //! @param other    The static_vector which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other)
+        : base_t(other)
+    {}
+
+    BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other, const allocator_type &)
+       : base_t(other)
+    {}
+
+    BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other,  const allocator_type &)
+       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value)
+       : base_t(BOOST_MOVE_BASE(base_t, other))
+    {}
+
+    BOOST_CONTAINER_FORCEINLINE explicit static_vector(const allocator_type &)
+       : base_t()
+    {}
+
+    //! @pre <tt>other.size() <= capacity()</tt>.
+    //!
+    //! @brief Constructs a copy of other static_vector.
+    //!
+    //! @param other    The static_vector which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C>
+    BOOST_CONTAINER_FORCEINLINE static_vector(static_vector<value_type, C> const& other)
+        : base_t(other)
+    {}
+
+    //! @brief Move constructor. Moves Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other)
+      BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value)
+        : base_t(BOOST_MOVE_BASE(base_t, other))
+    {}
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Move constructor. Moves Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C>
+    BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
+        : base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other))
+    {}
+
+    //! @brief Copy assigns Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //! Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
+    {
+        return static_cast<static_vector&>(base_t::operator=(static_cast<base_t const&>(other)));
+    }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+    //! @brief Copy assigns Values stored in std::initializer_list to *this.
+    //!
+    //! @param il    The std::initializer_list which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //! Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector & operator=(std::initializer_list<value_type> il)
+    { return static_cast<static_vector&>(base_t::operator=(il));  }
+#endif
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Copy assigns Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C>
+    BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector<value_type, C> const& other)
+    {
+        return static_cast<static_vector&>(base_t::operator=
+            (static_cast<typename static_vector<value_type, C>::base_t const&>(other)));
+    }
+
+    //! @brief Move assignment. Moves Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF(static_vector) other)
+    {
+        return static_cast<static_vector&>(base_t::operator=(BOOST_MOVE_BASE(base_t, other)));
+    }
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Move assignment. Moves Values stored in the other static_vector to this one.
+    //!
+    //! @param other    The static_vector which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C>
+    BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
+    {
+        return static_cast<static_vector&>(base_t::operator=
+         (BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other)));
+    }
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+    //! @brief Destructor. Destroys Values stored in this container.
+    //!
+    //! @par Throws
+    //!   Nothing
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    ~static_vector();
+
+    //! @brief Swaps contents of the other static_vector and this one.
+    //!
+    //! @param other    The static_vector which content will be swapped with this one's content.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void swap(static_vector & other);
+
+    //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
+    //!
+    //! @brief Swaps contents of the other static_vector and this one.
+    //!
+    //! @param other    The static_vector which content will be swapped with this one's content.
+    //!
+    //! @par Throws
+    //!   @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+    //!   @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C>
+    void swap(static_vector<value_type, C> & other);
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Inserts or erases elements at the end such that
+    //!   the size becomes count. New elements are value initialized.
+    //!
+    //! @param count    The number of elements which will be stored in the container.
+    //!
+    //! @par Throws
+    //!   If Value's value initialization throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void resize(size_type count);
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Inserts or erases elements at the end such that
+    //!   the size becomes count. New elements are default initialized.
+    //!
+    //! @param count    The number of elements which will be stored in the container.
+    //!
+    //! @par Throws
+    //!   If Value's default initialization throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    //!
+    //! @par Note
+    //!   Non-standard extension
+    void resize(size_type count, default_init_t);
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Inserts or erases elements at the end such that
+    //!   the size becomes count. New elements are copy constructed from value.
+    //!
+    //! @param count    The number of elements which will be stored in the container.
+    //! @param value    The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void resize(size_type count, value_type const& value);
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief This call has no effect because the Capacity of this container is constant.
+    //!
+    //! @param count    The number of elements which the container should be able to contain.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void reserve(size_type count)  BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Adds a copy of value at the end.
+    //!
+    //! @param value    The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void push_back(value_type const& value);
+
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Moves value to the end.
+    //!
+    //! @param value    The value to move construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's move constructor throws.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void push_back(BOOST_RV_REF(value_type) value);
+
+    //! @pre <tt>!empty()</tt>
+    //!
+    //! @brief Destroys last value and decreases the size.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void pop_back();
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a copy of element at p.
+    //!
+    //! @param p     The position at which the new value will be inserted.
+    //! @param value The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   @li If Value's copy constructor or copy assignment throws
+    //!   @li If Value's move constructor or move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    iterator insert(const_iterator p, value_type const& value);
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a move-constructed element at p.
+    //!
+    //! @param p     The position at which the new value will be inserted.
+    //! @param value The value used to move construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's move constructor or move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    iterator insert(const_iterator p, BOOST_RV_REF(value_type) value);
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() + count <= capacity()</tt>
+    //!
+    //! @brief Inserts a count copies of value at p.
+    //!
+    //! @param p     The position at which new elements will be inserted.
+    //! @param count The number of new elements which will be inserted.
+    //! @param value The value used to copy construct new elements.
+    //!
+    //! @par Throws
+    //!   @li If Value's copy constructor or copy assignment throws.
+    //!   @li If Value's move constructor or move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator insert(const_iterator p, size_type count, value_type const& value);
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>distance(first, last) <= capacity()</tt>
+    //!  @li \c Iterator must meet the \c ForwardTraversalIterator concept.
+    //!
+    //! @brief Inserts a copy of a range <tt>[first, last)</tt> at p.
+    //!
+    //! @param p     The position at which new elements will be inserted.
+    //! @param first The iterator to the first element of a range used to construct new elements.
+    //! @param last  The iterator to the one after the last element of a range used to construct new elements.
+    //!
+    //! @par Throws
+    //!   @li If Value's constructor and assignment taking a dereferenced \c Iterator.
+    //!   @li If Value's move constructor or move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    iterator insert(const_iterator p, Iterator first, Iterator last);
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>distance(il.begin(), il.end()) <= capacity()</tt>
+    //!
+    //! @brief Inserts a copy of a range <tt>[il.begin(), il.end())</tt> at p.
+    //!
+    //! @param p     The position at which new elements will be inserted.
+    //! @param il    The std::initializer_list which contains elements that will be inserted.
+    //!
+    //! @par Throws
+    //!   @li If Value's constructor and assignment taking a dereferenced std::initializer_list iterator.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator insert(const_iterator p, std::initializer_list<value_type> il);
+
+    //! @pre \c p must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
+    //!
+    //! @brief Erases Value from p.
+    //!
+    //! @param p    The position of the element which will be erased from the container.
+    //!
+    //! @par Throws
+    //!   If Value's move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator erase(const_iterator p);
+
+    //! @pre
+    //!  @li \c first and \c last must define a valid range
+    //!  @li iterators must be in range <tt>[begin(), end()]</tt>
+    //!
+    //! @brief Erases Values from a range <tt>[first, last)</tt>.
+    //!
+    //! @param first    The position of the first element of a range which will be erased from the container.
+    //! @param last     The position of the one after the last element of a range which will be erased from the container.
+    //!
+    //! @par Throws
+    //!   If Value's move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator erase(const_iterator first, const_iterator last);
+
+    //! @pre <tt>distance(first, last) <= capacity()</tt>
+    //!
+    //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
+    //!
+    //! @param first       The iterator to the first element of a range used to construct new content of this container.
+    //! @param last        The iterator to the one after the last element of a range used to construct new content of this container.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws,
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    void assign(Iterator first, Iterator last);
+
+    //! @pre <tt>distance(il.begin(), il.end()) <= capacity()</tt>
+    //!
+    //! @brief Assigns a range <tt>[il.begin(), il.end())</tt> of Values to this container.
+    //!
+    //! @param il       std::initializer_list with values used to construct new content of this container.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws,
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void assign(std::initializer_list<value_type> il);
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Assigns a count copies of value to this container.
+    //!
+    //! @param count       The new number of elements which will be container in the container.
+    //! @param value       The value which will be used to copy construct the new content.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void assign(size_type count, value_type const& value);
+
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a Value constructed with
+    //!   \c std::forward<Args>(args)... in the end of the container.
+    //!
+    //! @return A reference to the created object.
+    //!
+    //! @param args     The arguments of the constructor of the new element which will be created at the end of the container.
+    //!
+    //! @par Throws
+    //!   If in-place constructor throws or Value's move constructor throws.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    template<class ...Args>
+    reference emplace_back(Args &&...args);
+
+    //! @pre
+    //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a Value constructed with
+    //!   \c std::forward<Args>(args)... before p
+    //!
+    //! @param p     The position at which new elements will be inserted.
+    //! @param args  The arguments of the constructor of the new element.
+    //!
+    //! @par Throws
+    //!   If in-place constructor throws or if Value's move constructor or move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    template<class ...Args>
+    iterator emplace(const_iterator p, Args &&...args);
+
+    //! @brief Removes all elements from the container.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void clear()  BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   \c std::out_of_range exception by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference at(size_type i);
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns const reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return const reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   \c std::out_of_range exception by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference at(size_type i) const;
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference operator[](size_type i);
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns const reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return const reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference operator[](size_type i) const;
+
+    //! @pre <tt>i =< size()</tt>
+    //!
+    //! @brief Returns a iterator to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return a iterator to the i-th element.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    iterator nth(size_type i);
+
+    //! @pre <tt>i =< size()</tt>
+    //!
+    //! @brief Returns a const_iterator to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return a const_iterator to the i-th element.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator nth(size_type i) const;
+
+    //! @pre <tt>begin() <= p <= end()</tt>
+    //!
+    //! @brief Returns the index of the element pointed by p.
+    //!
+    //! @param p    An iterator to the element.
+    //!
+    //! @return The index of the element pointed by p.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    size_type index_of(iterator p);
+
+    //! @pre <tt>begin() <= p <= end()</tt>
+    //!
+    //! @brief Returns the index of the element pointed by p.
+    //!
+    //! @param p    A const_iterator to the element.
+    //!
+    //! @return a const_iterator to the i-th element.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    size_type index_of(const_iterator p) const;
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns reference to the first element.
+    //!
+    //! @return reference to the first element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference front();
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns const reference to the first element.
+    //!
+    //! @return const reference to the first element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference front() const;
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns reference to the last element.
+    //!
+    //! @return reference to the last element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference back();
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns const reference to the first element.
+    //!
+    //! @return const reference to the last element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference back() const;
+
+    //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+    //!   For a non-empty vector <tt>data() == &front()</tt>.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    Value * data() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+    //!   For a non-empty vector <tt>data() == &front()</tt>.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const Value * data() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns iterator to the first element.
+    //!
+    //! @return iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const iterator to the first element.
+    //!
+    //! @return const_iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const iterator to the first element.
+    //!
+    //! @return const_iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns iterator to the one after the last element.
+    //!
+    //! @return iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const iterator to the one after the last element.
+    //!
+    //! @return const_iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const iterator to the one after the last element.
+    //!
+    //! @return const_iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns reverse iterator to the first element of the reversed container.
+    //!
+    //! @return reverse_iterator pointing to the beginning
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const reverse iterator to the first element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the beginning
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const reverse iterator to the first element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the beginning
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return reverse_iterator pointing to the one after the last element
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the one after the last element
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the one after the last element
+    //! of the reversed static_vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns container's capacity.
+    //!
+    //! @return container's capacity.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns container's capacity.
+    //!
+    //! @return container's capacity.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Returns the number of stored elements.
+    //!
+    //! @return Number of elements contained in the container.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
+
+    //! @brief Queries if the container contains elements.
+    //!
+    //! @return true if the number of elements contained in the
+    //!   container is equal to 0.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
+#else
+
+   BOOST_CONTAINER_FORCEINLINE friend void swap(static_vector &x, static_vector &y)
+   {
+      x.swap(y);
+   }
+
+#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
+
+};
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! @brief Checks if contents of two static_vectors are equal.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if containers have the same size and elements in both containers are equal.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator== (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Checks if contents of two static_vectors are not equal.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if containers have different size or elements in both containers are not equal.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator!= (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Lexicographically compares static_vectors.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if x compares lexicographically less than y.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator< (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Lexicographically compares static_vectors.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if y compares lexicographically less than x.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator> (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Lexicographically compares static_vectors.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if y don't compare lexicographically less than x.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator<= (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Lexicographically compares static_vectors.
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @return     \c true if x don't compare lexicographically less than y.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator>= (static_vector<V, C1> const& x, static_vector<V, C2> const& y);
+
+//! @brief Swaps contents of two static_vectors.
+//!
+//! This function calls static_vector::swap().
+//!
+//! @ingroup static_vector_non_member
+//!
+//! @param x    The first static_vector.
+//! @param y    The second static_vector.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y);
+
+#else
+
+template<typename V, std::size_t C1, std::size_t C2>
+inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y
+      , typename dtl::enable_if_c< C1 != C2>::type * = 0)
+{
+   x.swap(y);
+}
+
+#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
+
+}} // namespace boost::container
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_STATIC_VECTOR_HPP
diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp
new file mode 100644
index 0000000..6c0cc96
--- /dev/null
+++ b/include/boost/container/string.hpp
@@ -0,0 +1,3459 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_STRING_HPP
+#define BOOST_CONTAINER_STRING_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/min_max.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/next_capacity.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/minimal_char_traits_header.hpp>
+#include <boost/container/detail/algorithm.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/traits.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/functional/hash.hpp>
+
+#include <algorithm>
+#include <iosfwd>
+#include <istream>
+#include <ostream>
+#include <ios>
+#include <locale>
+#include <cstddef>
+#include <climits>
+
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>   //for std::initializer_list
+#endif
+
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace dtl {
+// ------------------------------------------------------------
+// Class basic_string_base.
+
+// basic_string_base is a helper class that makes it it easier to write
+// an exception-safe version of basic_string.  The constructor allocates,
+// but does not initialize, a block of memory.  The destructor
+// deallocates, but does not destroy elements within, a block of
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using string_base's
+// allocator and whose size is this->m_storage.
+template <class Allocator>
+class basic_string_base
+{
+   basic_string_base & operator=(const basic_string_base &);
+   basic_string_base(const basic_string_base &);
+
+   typedef allocator_traits<Allocator> allocator_traits_type;
+ public:
+   typedef Allocator                                   allocator_type;
+   typedef allocator_type                              stored_allocator_type;
+   typedef typename allocator_traits_type::pointer     pointer;
+   typedef typename allocator_traits_type::value_type  value_type;
+   typedef typename allocator_traits_type::size_type   size_type;
+   typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
+
+   basic_string_base()
+      : members_()
+   {  init(); }
+
+   explicit basic_string_base(const allocator_type& a)
+      : members_(a)
+   {  init(); }
+
+   explicit basic_string_base(BOOST_RV_REF(allocator_type) a)
+      :  members_(boost::move(a))
+   {  this->init();  }
+
+   basic_string_base(const allocator_type& a, size_type n)
+      : members_(a)
+   {
+      this->init();
+      this->allocate_initial_block(n);
+   }
+
+   explicit basic_string_base(size_type n)
+      : members_()
+   {
+      this->init();
+      this->allocate_initial_block(n);
+   }
+
+   ~basic_string_base()
+   {
+      if(!this->is_short()){
+         this->deallocate(this->priv_long_addr(), this->priv_long_storage());
+      }
+   }
+
+   private:
+
+   //This is the structure controlling a long string
+   struct long_t
+   {
+      size_type      is_short  : 1;
+      size_type      length    : (sizeof(size_type)*CHAR_BIT - 1);
+      size_type      storage;
+      pointer        start;
+
+      long_t()
+      {}
+
+      long_t(const long_t &other)
+      {
+         this->is_short = false;
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+      }
+
+      long_t &operator= (const long_t &other)
+      {
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+         return *this;
+      }
+   };
+
+   //This type is the first part of the structure controlling a short string
+   //The "data" member stores
+   struct short_header
+   {
+      unsigned char  is_short  : 1;
+      unsigned char  length    : (CHAR_BIT - 1);
+   };
+
+   //This type has the same alignment and size as long_t but it's POD
+   //so, unlike long_t, it can be placed in a union
+
+   typedef typename dtl::aligned_storage
+      <sizeof(long_t), dtl::alignment_of<long_t>::value>::type   long_raw_t;
+
+   protected:
+   static const size_type  MinInternalBufferChars = 8;
+   static const size_type  AlignmentOfValueType =
+      alignment_of<value_type>::value;
+   static const size_type  ShortDataOffset = ((sizeof(short_header)-1)/AlignmentOfValueType+1)*AlignmentOfValueType;
+   static const size_type  ZeroCostInternalBufferChars =
+      (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
+   static const size_type  UnalignedFinalInternalBufferChars =
+      (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
+                ZeroCostInternalBufferChars : MinInternalBufferChars;
+
+   struct short_t
+   {
+      short_header   h;
+      value_type     data[UnalignedFinalInternalBufferChars];
+   };
+
+   union repr_t
+   {
+      long_raw_t  r;
+      short_t     s;
+
+      const short_t &short_repr() const
+      {  return s;  }
+
+      const long_t &long_repr() const
+      {  return *static_cast<const long_t*>(static_cast<const void*>(r.data));  }
+
+      short_t &short_repr()
+      {  return s;  }
+
+      long_t &long_repr()
+      {  return *static_cast<long_t*>(static_cast<void*>(&r));  }
+   };
+
+   struct members_holder
+      :  public Allocator
+   {
+      members_holder()
+         : Allocator()
+      {}
+
+      template<class AllocatorConvertible>
+      explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
+         :  Allocator(boost::forward<AllocatorConvertible>(a))
+      {}
+
+      repr_t m_repr;
+   } members_;
+
+   const Allocator &alloc() const
+   {  return members_;  }
+
+   Allocator &alloc()
+   {  return members_;  }
+
+   static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
+
+   private:
+
+   static const size_type MinAllocation = InternalBufferChars*2;
+
+   protected:
+   bool is_short() const
+   {
+      //Access and copy (to avoid UB) the first byte of the union to know if the
+      //active representation is short or long
+      short_header hdr;
+      BOOST_STATIC_ASSERT((sizeof(short_header) == 1));
+      *(unsigned char*)&hdr = *(unsigned char*)&this->members_.m_repr;
+      return hdr.is_short != 0;
+   }
+
+   void is_short(bool yes)
+   {
+      const bool was_short = this->is_short();
+      if(yes && !was_short){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
+            );
+         this->members_.m_repr.s.h.is_short = true;
+      }
+      else if(!yes && was_short){
+         allocator_traits_type::construct
+            ( this->alloc()
+            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
+            );
+         this->members_.m_repr.s.h.is_short = false;
+      }
+   }
+
+   private:
+   void init()
+   {
+      this->members_.m_repr.s.h.is_short = 1;
+      this->members_.m_repr.s.h.length   = 0;
+   }
+
+   protected:
+
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::version<Allocator>::value> alloc_version;
+
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
+         reuse = 0;
+         command &= ~(expand_fwd | expand_bwd);
+      }
+      return dtl::allocator_version_traits<Allocator>::allocation_command
+         (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
+   }
+
+   size_type next_capacity(size_type additional_objects) const
+   {
+      return growth_factor_100()
+            ( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc()));
+   }
+
+   void deallocate(pointer p, size_type n)
+   {
+      if (p && (n > InternalBufferChars))
+         this->alloc().deallocate(p, n);
+   }
+
+   void construct(pointer p, const value_type &value = value_type())
+   {
+      allocator_traits_type::construct
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(p)
+         , value
+         );
+   }
+
+   void destroy(pointer p, size_type n)
+   {
+      value_type *raw_p = boost::movelib::to_raw_pointer(p);
+      for(; n--; ++raw_p){
+         allocator_traits_type::destroy( this->alloc(), raw_p);
+      }
+   }
+
+   void destroy(pointer p)
+   {
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(p)
+         );
+   }
+
+   void allocate_initial_block(size_type n)
+   {
+      if (n <= this->max_size()) {
+         if(n > InternalBufferChars){
+            size_type new_cap = this->next_capacity(n);
+            pointer reuse = 0;
+            pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
+            this->is_short(false);
+            this->priv_long_addr(p);
+            this->priv_long_size(0);
+            this->priv_storage(new_cap);
+         }
+      }
+      else{
+         throw_length_error("basic_string::allocate_initial_block max_size() exceeded");
+      }
+   }
+
+   void deallocate_block()
+   {  this->deallocate(this->priv_addr(), this->priv_storage());  }
+
+   size_type max_size() const
+   {  return allocator_traits_type::max_size(this->alloc()) - 1; }
+
+   protected:
+   size_type priv_capacity() const
+   { return this->priv_storage() - 1; }
+
+   pointer priv_short_addr() const
+   {  return pointer_traits::pointer_to(const_cast<value_type&>(this->members_.m_repr.short_repr().data[0]));  }
+
+   pointer priv_long_addr() const
+   {  return this->members_.m_repr.long_repr().start;  }
+
+   pointer priv_addr() const
+   {
+      return this->is_short()
+         ? priv_short_addr()
+         : priv_long_addr()
+         ;
+   }
+
+   pointer priv_end_addr() const
+   {
+      return this->is_short()
+         ? this->priv_short_addr() + this->priv_short_size()
+         : this->priv_long_addr()  + this->priv_long_size()
+         ;
+   }
+
+   void priv_long_addr(pointer addr)
+   {  this->members_.m_repr.long_repr().start = addr;  }
+
+   size_type priv_storage() const
+   {  return this->is_short() ? priv_short_storage() : priv_long_storage();  }
+
+   size_type priv_short_storage() const
+   {  return InternalBufferChars;  }
+
+   size_type priv_long_storage() const
+   {  return this->members_.m_repr.long_repr().storage;  }
+
+   void priv_storage(size_type storage)
+   {
+      if(!this->is_short())
+         this->priv_long_storage(storage);
+   }
+
+   void priv_long_storage(size_type storage)
+   {
+      this->members_.m_repr.long_repr().storage = storage;
+   }
+
+   size_type priv_size() const
+   {  return this->is_short() ? this->priv_short_size() : this->priv_long_size();  }
+
+   size_type priv_short_size() const
+   {  return this->members_.m_repr.short_repr().h.length;  }
+
+   size_type priv_long_size() const
+   {  return this->members_.m_repr.long_repr().length;  }
+
+   void priv_size(size_type sz)
+   {
+      if(this->is_short())
+         this->priv_short_size(sz);
+      else
+         this->priv_long_size(sz);
+   }
+
+   void priv_short_size(size_type sz)
+   {
+      this->members_.m_repr.s.h.length = (unsigned char)sz;
+   }
+
+   void priv_long_size(size_type sz)
+   {
+      this->members_.m_repr.long_repr().length = sz;
+   }
+
+   void swap_data(basic_string_base& other)
+   {
+      if(this->is_short()){
+         if(other.is_short()){
+            repr_t tmp(this->members_.m_repr);
+            this->members_.m_repr = other.members_.m_repr;
+            other.members_.m_repr = tmp;
+         }
+         else{
+            short_t short_backup(this->members_.m_repr.short_repr());
+            this->members_.m_repr.short_repr().~short_t();
+            ::new(&this->members_.m_repr.long_repr()) long_t(other.members_.m_repr.long_repr());
+            other.members_.m_repr.long_repr().~long_t();
+            ::new(&other.members_.m_repr.short_repr()) short_t(short_backup);
+         }
+      }
+      else{
+         if(other.is_short()){
+            short_t short_backup(other.members_.m_repr.short_repr());
+            other.members_.m_repr.short_repr().~short_t();
+            ::new(&other.members_.m_repr.long_repr()) long_t(this->members_.m_repr.long_repr());
+            this->members_.m_repr.long_repr().~long_t();
+            ::new(&this->members_.m_repr.short_repr()) short_t(short_backup);
+         }
+         else{
+            boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+         }
+      }
+   }
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! The basic_string class represents a Sequence of characters. It contains all the
+//! usual operations of a Sequence, and, additionally, it contains standard string
+//! operations such as search and concatenation.
+//!
+//! The basic_string class is parameterized by character type, and by that type's
+//! Character Traits.
+//!
+//! This class has performance characteristics very much like vector<>, meaning,
+//! for example, that it does not perform reference-count or copy-on-write, and that
+//! concatenation of two strings is an O(N) operation.
+//!
+//! Some of basic_string's member functions use an unusual method of specifying positions
+//! and ranges. In addition to the conventional method using iterators, many of
+//! basic_string's member functions use a single value pos of type size_type to represent a
+//! position (in which case the position is begin() + pos, and many of basic_string's
+//! member functions use two values, pos and n, to represent a range. In that case pos is
+//! the beginning of the range and n is its size. That is, the range is
+//! [begin() + pos, begin() + pos + n).
+//!
+//! Note that the C++ standard does not specify the complexity of basic_string operations.
+//! In this implementation, basic_string has performance characteristics very similar to
+//! those of vector: access to a single character is O(1), while copy and concatenation
+//! are O(N).
+//!
+//! In this implementation, begin(),
+//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
+//! In this implementation, iterators are only invalidated by member functions that
+//! explicitly change the string's contents.
+//!
+//! \tparam CharT The type of character it contains.
+//! \tparam Traits The Character Traits type, which encapsulates basic character operations
+//! \tparam Allocator The allocator, used for internal memory management.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> >
+#else
+template <class CharT, class Traits, class Allocator>
+#endif
+class basic_string
+   :  private dtl::basic_string_base<Allocator>
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   BOOST_COPYABLE_AND_MOVABLE(basic_string)
+   typedef dtl::basic_string_base<Allocator> base_t;
+   static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
+
+   protected:
+   // Allocator helper class to use a char_traits as a function object.
+
+   template <class Tr>
+   struct Eq_traits
+   {
+      //Compatibility with std::binary_function
+      typedef typename Tr::char_type   first_argument_type;
+      typedef typename Tr::char_type   second_argument_type;
+      typedef bool   result_type;
+
+      bool operator()(const first_argument_type& x, const second_argument_type& y) const
+         { return Tr::eq(x, y); }
+   };
+
+   template <class Tr>
+   struct Not_within_traits
+   {
+      typedef typename Tr::char_type   argument_type;
+      typedef bool                     result_type;
+
+      typedef const typename Tr::char_type* Pointer;
+      const Pointer m_first;
+      const Pointer m_last;
+
+      Not_within_traits(Pointer f, Pointer l)
+         : m_first(f), m_last(l) {}
+
+      bool operator()(const typename Tr::char_type& x) const
+      {
+         return boost::container::find_if(m_first, m_last,
+                        boost::container::bind1st(Eq_traits<Tr>(), x)) == m_last;
+      }
+   };
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Traits                                                                      traits_type;
+   typedef CharT                                                                       value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(allocator_type)                                      stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(pointer)                                             iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_pointer)                                       const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+   static const size_type npos = size_type(-1);
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   typedef constant_iterator<CharT, difference_type> cvalue_iterator;
+   typedef typename base_t::alloc_version  alloc_version;
+   typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:                         // Constructor, destructor, assignment.
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   struct reserve_t {};
+
+   basic_string(reserve_t, size_type n,
+                const allocator_type& a = allocator_type())
+      //Select allocator as in copy constructor as reserve_t-based constructors
+      //are two step copies optimized for capacity
+      : base_t( allocator_traits_type::select_on_container_copy_construction(a)
+              , n + 1)
+   { this->priv_terminate_string(); }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Default constructs a basic_string.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   basic_string() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : base_t()
+   { this->priv_terminate_string(); }
+
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
+      : base_t(a)
+   { this->priv_terminate_string(); }
+
+   //! <b>Effects</b>: Copy constructs a basic_string.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
+   basic_string(const basic_string& s)
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
+   {
+      this->priv_terminate_string();
+      this->assign(s.begin(), s.end());
+   }
+
+   //! <b>Effects</b>: Same as basic_string(sv.data(), sv.size(), a).
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
+   template<template <class, class> class BasicStringView>
+   explicit basic_string(BasicStringView<CharT, Traits> sv, const Allocator& a = Allocator())
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(a))
+   {
+      this->priv_terminate_string();
+      this->assign(sv);
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   basic_string(BOOST_RV_REF(basic_string) s) BOOST_NOEXCEPT_OR_NOTHROW
+      : base_t(boost::move(s.alloc()))
+   {
+      if(s.alloc() == this->alloc()){
+         this->swap_data(s);
+      }
+      else{
+         this->assign(s.begin(), s.end());
+      }
+   }
+
+   //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocation throws.
+   basic_string(const basic_string& s, const allocator_type &a)
+      :  base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s.begin(), s.end());
+   }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves s's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocation throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
+   basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      if(a == this->alloc()){
+         this->swap_data(s);
+      }
+      else{
+         this->assign(s.begin(), s.end());
+      }
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by a specific number of characters of the s string.
+   basic_string(const basic_string& s, size_type pos, size_type n = npos)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      if (pos > s.size())
+         throw_out_of_range("basic_string::basic_string out of range position");
+      else
+         this->assign
+            (s.begin() + pos, s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s string.
+   basic_string(const basic_string& s, size_type pos, size_type n, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      if (pos > s.size())
+         throw_out_of_range("basic_string::basic_string out of range position");
+      else
+         this->assign
+            (s.begin() + pos, s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking a default-constructed allocator,
+   //!   and is initialized by a specific number of characters of the s c-string.
+   basic_string(const CharT* s, size_type n)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + n);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s c-string.
+   basic_string(const CharT* s, size_type n, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + n);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by the null-terminated s c-string.
+   basic_string(const CharT* s)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + Traits::length(s));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by the null-terminated s c-string.
+   basic_string(const CharT* s, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + Traits::length(s));
+   }
+
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by n copies of c.
+   basic_string(size_type n, CharT c)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(n, c);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by n copies of c.
+   basic_string(size_type n, CharT c, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(n, c);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by n default-initialized characters.
+   basic_string(size_type n, default_init_t)
+      : base_t(n + 1)
+   {
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by n default-initialized characters.
+   basic_string(size_type n, default_init_t, const allocator_type& a)
+      : base_t(a, n + 1)
+   {
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and a range of iterators.
+   template <class InputIterator>
+   basic_string(InputIterator f, InputIterator l)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(f, l);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and a range of iterators.
+   template <class InputIterator>
+   basic_string(InputIterator f, InputIterator l, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(f, l);
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Same as basic_string(il.begin(), il.end(), a).
+   //!
+   basic_string(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   ~basic_string() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //! <b>Effects</b>: Copy constructs a string.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            if(!this->is_short()){
+               this->deallocate_block();
+               this->is_short(true);
+               Traits::assign(*this->priv_addr(), CharT(0));
+               this->priv_short_size(0);
+            }
+         }
+         dtl::assign_alloc(this->alloc(), x.alloc(), flag);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and allocation throws
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   basic_string& operator=(BOOST_RV_REF(basic_string) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      //for move constructor, no aliasing (&x != this) is assummed.
+      BOOST_ASSERT(this != &x);
+      allocator_type &this_alloc = this->alloc();
+      allocator_type &x_alloc    = x.alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      dtl::bool_<propagate_alloc> flag;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy objects but retain memory in case x reuses it in the future
+         this->clear();
+         //Move allocator if needed
+         dtl::move_alloc(this_alloc, x_alloc, flag);
+         //Nothrow swap
+         this->swap_data(x);
+      }
+      //Else do a one by one move
+      else{
+         this->assign( x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Assignment from a null-terminated c-string.
+   //!
+   basic_string& operator=(const CharT* s)
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! <b>Effects</b>: Returns *this = basic_string(1, c).
+   //!
+   basic_string& operator=(CharT c)
+   { return this->assign(static_cast<size_type>(1), c); }
+
+   //! <b>Effects</b>: Equivalent to return assign(sv).
+   //!
+   template<template <class, class> class BasicStringView>
+   basic_string& operator=(BasicStringView<CharT, Traits> sv)
+   { return this->assign(sv.data(), sv.size()); }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns *this = basic_string(il);
+   //!
+   basic_string& operator=(std::initializer_list<CharT> il)
+   {
+      return this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin()  BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->priv_end_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crbegin(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend()  BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->priv_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crend(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->priv_end_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->priv_addr()); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the vector contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return !this->priv_size(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const    BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_size(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type length() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->size(); }
+
+   //! <b>Effects</b>: Returns the largest possible size of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return base_t::max_size(); }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n, CharT c)
+   {
+      if (n <= this->size())
+         this->erase(this->begin() + n, this->end());
+      else
+         this->append(n - this->size(), c);
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n)
+   { resize(n, CharT()); }
+
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are uninitialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void resize(size_type n, default_init_t)
+   {
+      if (n <= this->size())
+         this->erase(this->begin() + n, this->end());
+      else{
+         this->priv_reserve(n, false);
+         this->priv_size(n);
+         this->priv_terminate_string();
+      }
+   }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_capacity(); }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws
+   void reserve(size_type res_arg)
+   {  this->priv_reserve(res_arg);  }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the string is unchanged
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   void shrink_to_fit()
+   {
+      //Check if shrinking is possible
+      if(this->priv_storage() > InternalBufferChars){
+         //Check if we should pass from dynamically allocated buffer
+         //to the internal storage
+         if(this->priv_size() < InternalBufferChars){
+            //Dynamically allocated buffer attributes
+            pointer   long_addr    = this->priv_long_addr();
+            size_type long_storage = this->priv_long_storage();
+            size_type long_size    = this->priv_long_size();
+            //Shrink from allocated buffer to the internal one, including trailing null
+            Traits::copy( boost::movelib::to_raw_pointer(this->priv_short_addr())
+                        , boost::movelib::to_raw_pointer(long_addr)
+                        , long_size+1);
+            this->is_short(true);
+            this->alloc().deallocate(long_addr, long_storage);
+         }
+         else{
+            //Shrinking in dynamic buffer
+            this->priv_shrink_to_fit_dynamic_buffer(alloc_version());
+         }
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->priv_addr();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->priv_addr();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(this->priv_addr() + (this->size() - 1u) );
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   back()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(this->priv_addr() + (this->size() - 1u) );
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference at(size_type n)
+   {
+      if (n >= this->size())
+         throw_out_of_range("basic_string::at invalid subscript");
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference at(size_type n) const {
+      if (n >= this->size())
+         throw_out_of_range("basic_string::at invalid subscript");
+      return *(this->priv_addr() + n);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Calls append(str.data, str.size()).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(const basic_string& s)
+   {  return this->append(s); }
+
+   //! <b>Effects</b>: Same as `return append(sv)`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& operator+=(BasicStringView<CharT, Traits> sv)
+   {
+      return this->append(sv);
+   }
+
+   //! <b>Effects</b>: Calls append(s).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(const CharT* s)
+   {  return this->append(s); }
+
+   //! <b>Effects</b>: Calls append(1, c).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(CharT c)
+   {  this->push_back(c); return *this;   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns append(il)
+   //!
+   basic_string& operator+=(std::initializer_list<CharT> il)
+   {
+      return this->append(il);
+   }
+   #endif
+
+   //! <b>Effects</b>: Calls append(str.data(), str.size()).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const basic_string& s)
+   {  return this->append(s.begin(), s.end());  }
+
+   //! <b>Effects</b>: Same as return append(sv.data(), sv.size()).
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& append(BasicStringView<CharT, Traits> sv)
+   {  return this->append(sv.data(), sv.size());  }
+
+   //! <b>Requires</b>: pos <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to append
+   //! as the smaller of n and str.size() - pos and calls append(str.data() + pos, rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws and out_of_range if pos > str.size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const basic_string& s, size_type pos, size_type n = npos)
+   {
+      if (pos > s.size())
+         throw_out_of_range("basic_string::append out of range position");
+      return this->append(s.begin() + pos,
+                          s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Effects</b>: The function replaces the string controlled by *this with
+   //!   a string of length size() + n whose irst size() elements are a copy of the
+   //!   original string controlled by *this and whose remaining
+   //!   elements are a copy of the initial n elements of s.
+   //!
+   //! <b>Throws</b>: If memory allocation throws length_error if size() + n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const CharT* s, size_type n)
+   {  return this->append(s, s + n);  }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls append(s, traits::length(s)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const CharT* s)
+   {  return this->append(s, s + Traits::length(s));  }
+
+   //! <b>Effects</b>: Equivalent to append(basic_string(n, c)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(size_type n, CharT c)
+   {  return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! <b>Requires</b>: [first,last) is a valid range.
+   //!
+   //! <b>Effects</b>: Equivalent to append(basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& append(InputIter first, InputIter last)
+   {  this->insert(this->end(), first, last);   return *this;  }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns append(il.begin(), il.size()).
+   //!
+   basic_string& append(std::initializer_list<CharT> il)
+   {
+      return this->append(il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c).
+   //!
+   void push_back(CharT c)
+   {
+      const size_type old_size = this->priv_size();
+      if (old_size < this->capacity()){
+         const pointer addr = this->priv_addr();
+         this->priv_construct_null(addr + old_size + 1);
+         Traits::assign(addr[old_size], c);
+         this->priv_size(old_size+1);
+      }
+      else{
+         //No enough memory, insert a new object at the end
+         this->append(size_type(1), c);
+      }
+   }
+
+   //! <b>Effects</b>: Equivalent to assign(str, 0, npos).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const basic_string& s)
+   {  return this->operator=(s); }
+
+   //! <b>Effects</b>: Equivalent to return assign(sv.data(), sv.size()).
+   //!
+   //! <b>Returns</b>: *this
+   template<template <class, class> class BasicStringView>
+   basic_string& assign(BasicStringView<CharT, Traits> sv)
+   {  return this->operator=(sv); }
+
+   //! <b>Effects</b>: The function replaces the string controlled by *this
+   //!    with a string of length str.size() whose elements are a copy of the string
+   //!   controlled by str. Leaves str in a valid but unspecified state.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->swap_data(ms), *this;  }
+
+   //! <b>Requires</b>: pos <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to assign as
+   //!   the smaller of n and str.size() - pos and calls assign(str.data() + pos rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const basic_string& s, size_type pos, size_type n)
+   {
+      if (pos > s.size())
+         throw_out_of_range("basic_string::assign out of range position");
+      return this->assign(s.begin() + pos,
+                          s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Effects</b>: Replaces the string controlled by *this with a string of
+   //! length n whose elements are a copy of those pointed to by s.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or length_error if n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const CharT* s, size_type n)
+   {  return this->assign(s, s + n);   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls assign(s, traits::length(s)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const CharT* s)
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(n, c)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(size_type n, CharT c)
+   {  return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
+    //!
+    //! <b>Returns</b>: *this
+    basic_string& assign(const CharT* first, const CharT* last)
+    {
+       size_type n = static_cast<size_type>(last - first);
+       this->reserve(n);
+       CharT* ptr = boost::movelib::to_raw_pointer(this->priv_addr());
+       Traits::copy(ptr, first, n);
+       this->priv_construct_null(ptr + n);
+       this->priv_size(n);
+       return *this;
+    }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& assign(InputIter first, InputIter last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible<InputIter, size_type>::type * = 0
+      #endif
+      )
+   {
+      size_type cur = 0;
+      const pointer addr = this->priv_addr();
+      CharT *ptr = boost::movelib::to_raw_pointer(addr);
+      const size_type old_size = this->priv_size();
+      while (first != last && cur != old_size) {
+         Traits::assign(*ptr, *first);
+         ++first;
+         ++cur;
+         ++ptr;
+      }
+      if (first == last)
+         this->erase(addr + cur, addr + old_size);
+      else
+         this->append(first, last);
+      return *this;
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns assign(il.begin(), il.size()).
+   //!
+   basic_string& assign(std::initializer_list<CharT> il)
+   {
+      return this->assign(il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Requires</b>: pos <= size().
+   //!
+   //! <b>Effects</b>: Calls insert(pos, str.data(), str.size()).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const basic_string& s)
+   {
+      const size_type sz = this->size();
+      if (pos > sz)
+         throw_out_of_range("basic_string::insert out of range position");
+      if (sz > this->max_size() - s.size())
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s.begin(), s.end());
+      return *this;
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to insert as
+   //!   the smaller of n and str.size() - pos2 and calls insert(pos1, str.data() + pos2, rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n = npos)
+   {
+      const size_type sz = this->size();
+      const size_type str_size = s.size();
+      if (pos1 > sz || pos2 > str_size)
+         throw_out_of_range("basic_string::insert out of range position");
+      size_type len = dtl::min_value(n, str_size - pos2);
+      if (sz > this->max_size() - len)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      const CharT *beg_ptr = boost::movelib::to_raw_pointer(s.begin()) + pos2;
+      const CharT *end_ptr = beg_ptr + len;
+      this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
+      return *this;
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT and pos <= size().
+   //!
+   //! <b>Effects</b>: Replaces the string controlled by *this with a string of length size() + n
+   //!   whose first pos elements are a copy of the initial elements of the original string
+   //!   controlled by *this and whose next n elements are a copy of the elements in s and whose
+   //!   remaining elements are a copy of the remaining elements of the original string controlled by *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size() or
+   //!   length_error if size() + n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const CharT* s, size_type n)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      if (this->size() > this->max_size() - n)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s, s + n);
+      return *this;
+   }
+
+   //! <b>Requires</b>: pos <= size() and s points to an array of at least traits::length(s) + 1 elements of CharT
+   //!
+   //! <b>Effects</b>: Calls insert(pos, s, traits::length(s)).
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - Traits::length(s)
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const CharT* s)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      size_type len = Traits::length(s);
+      if (this->size() > this->max_size() - len)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s, s + len);
+      return *this;
+   }
+
+   //! <b>Effects</b>: Equivalent to insert(pos, basic_string(n, c)).
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - n
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, size_type n, CharT c)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      if (this->size() > this->max_size() - n)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(const_iterator(this->priv_addr() + pos), n, c);
+      return *this;
+   }
+
+   //! <b>Effects</b>: Same as `return insert(pos, sv.data(), sv.size())`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& insert(size_type pos, BasicStringView<CharT, Traits> sv)
+   {  return this->insert(pos, sv.data(), sv.size());  }
+
+   //! <b>Requires</b>: p is a valid iterator on *this.
+   //!
+   //! <b>Effects</b>: inserts a copy of c before the character referred to by p.
+   //!
+   //! <b>Returns</b>: An iterator which refers to the copy of the inserted character.
+   iterator insert(const_iterator p, CharT c)
+   {
+      size_type new_offset = p - this->priv_addr();
+      this->insert(p, cvalue_iterator(c, 1), cvalue_iterator());
+      return this->priv_addr() + new_offset;
+   }
+
+   //! <b>Requires</b>: p is a valid iterator on *this.
+   //!
+   //! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+   iterator insert(const_iterator p, size_type n, CharT c)
+   {  return this->insert(p, cvalue_iterator(c, n), cvalue_iterator());  }
+
+   //! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
+   //!
+   //! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   template <class InputIter>
+   iterator insert(const_iterator p, InputIter first, InputIter last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InputIter, size_type>
+         , dtl::is_not_input_iterator<InputIter>
+         >::type * = 0
+      #endif
+      )
+   {
+      const size_type n_pos = p - this->cbegin();
+      for ( ; first != last; ++first, ++p) {
+         p = this->insert(p, *first);
+      }
+      return this->begin() + n_pos;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class ForwardIter>
+   iterator insert(const_iterator p, ForwardIter first, ForwardIter last
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<ForwardIter, size_type>
+         , dtl::is_input_iterator<ForwardIter>
+         >::type * = 0
+      )
+   {
+      const size_type n_pos = p - this->cbegin();
+      if (first != last) {
+         const size_type n = boost::container::iterator_distance(first, last);
+         const size_type old_size = this->priv_size();
+         const size_type remaining = this->capacity() - old_size;
+         const pointer old_start = this->priv_addr();
+         bool enough_capacity = false;
+         size_type new_cap = 0;
+
+         //Check if we have enough capacity
+         pointer hint = pointer();
+         pointer allocation_ret = pointer();
+         if (remaining >= n){
+            enough_capacity = true;
+         }
+         else {
+            //Otherwise expand current buffer or allocate new storage
+            new_cap  = this->next_capacity(n);
+            hint = old_start;
+            allocation_ret = this->allocation_command
+                  (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
+
+            //Check forward expansion
+            if(old_start == allocation_ret){
+               enough_capacity = true;
+               this->priv_storage(new_cap);
+            }
+         }
+
+         //Reuse same buffer
+         if(enough_capacity){
+            const size_type elems_after = old_size - (p - old_start);
+            const size_type old_length = old_size;
+            if (elems_after >= n) {
+               const pointer pointer_past_last = old_start + old_size + 1;
+               priv_uninitialized_copy(old_start + (old_size - n + 1),
+                                       pointer_past_last, pointer_past_last);
+
+               this->priv_size(old_size+n);
+               Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
+                           boost::movelib::to_raw_pointer(p),
+                           (elems_after - n) + 1);
+               this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
+            }
+            else {
+               ForwardIter mid = first;
+               boost::container::iterator_advance(mid, elems_after + 1);
+
+               priv_uninitialized_copy(mid, last, old_start + old_size + 1);
+               const size_type newer_size = old_size + (n - elems_after);
+               this->priv_size(newer_size);
+               priv_uninitialized_copy
+                  (p, const_iterator(old_start + old_length + 1),
+                  old_start + newer_size);
+               this->priv_size(newer_size + elems_after);
+               this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
+            }
+         }
+         else{
+            pointer new_start = allocation_ret;
+            if(!hint){
+               //Copy data to new buffer
+               size_type new_length = 0;
+               //This can't throw, since characters are POD
+               new_length += priv_uninitialized_copy
+                              (const_iterator(old_start), p, new_start);
+               new_length += priv_uninitialized_copy
+                              (first, last, new_start + new_length);
+               new_length += priv_uninitialized_copy
+                              (p, const_iterator(old_start + old_size),
+                              new_start + new_length);
+               this->priv_construct_null(new_start + new_length);
+
+               this->deallocate_block();
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(new_length);
+               this->priv_long_storage(new_cap);
+            }
+            else{
+               //value_type is POD, so backwards expansion is much easier
+               //than with vector<T>
+               value_type * const oldbuf     = boost::movelib::to_raw_pointer(old_start);
+               value_type * const newbuf     = boost::movelib::to_raw_pointer(new_start);
+               const value_type *const pos   = boost::movelib::to_raw_pointer(p);
+               const size_type before  = pos - oldbuf;
+
+               //First move old data
+               Traits::move(newbuf, oldbuf, before);
+               Traits::move(newbuf + before + n, pos, old_size - before);
+               //Now initialize the new data
+               priv_uninitialized_copy(first, last, new_start + before);
+               this->priv_construct_null(new_start + (old_size + n));
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(old_size + n);
+               this->priv_long_storage(new_cap);
+            }
+         }
+      }
+      return this->begin() + n_pos;
+   }
+   #endif
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: As if by insert(p, il.begin(), il.end()).
+   //!
+   //! <b>Returns</b>: An iterator which refers to the copy of the first inserted
+   //!   character, or p if i1 is empty.
+   iterator insert(const_iterator p, std::initializer_list<CharT> il)
+   {
+      return this->insert(p, il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the last element from the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      iterator p = this->end();
+      this->erase(--p);
+   }
+
+   //! <b>Requires</b>: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
+   //!   The function then replaces the string controlled by *this with a string of length size() - xlen
+   //!   whose first pos elements are a copy of the initial elements of the original string controlled by *this,
+   //!   and whose remaining elements are a copy of the elements of the original string controlled by *this
+   //!   beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& erase(size_type pos = 0, size_type n = npos)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::erase out of range position");
+      const pointer addr = this->priv_addr();
+      erase(addr + pos, addr + pos + dtl::min_value(n, this->size() - pos));
+      return *this;
+   }
+
+   //! <b>Effects</b>: Removes the character referred to by p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
+   //!    erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      // The move includes the terminating null.
+      CharT * const ptr = const_cast<CharT*>(boost::movelib::to_raw_pointer(p));
+      const size_type old_size = this->priv_size();
+      Traits::move(ptr,
+                   boost::movelib::to_raw_pointer(p + 1),
+                   old_size - (p - this->priv_addr()));
+      this->priv_size(old_size-1);
+      return iterator(ptr);
+   }
+
+   //! <b>Requires</b>: first and last are valid iterators on *this, defining a range [first,last).
+   //!
+   //! <b>Effects</b>: Removes the characters in the range [first,last).
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
+   //!   the other elements being erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      CharT * f = const_cast<CharT*>(boost::movelib::to_raw_pointer(first));
+      if (first != last) { // The move includes the terminating null.
+         const size_type num_erased = last - first;
+         const size_type old_size = this->priv_size();
+         Traits::move(f,
+                      boost::movelib::to_raw_pointer(last),
+                      (old_size + 1)-(last - this->priv_addr()));
+         const size_type new_length = old_size - num_erased;
+         this->priv_size(new_length);
+      }
+      return iterator(f);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the vector.
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if (!this->empty()) {
+         Traits::assign(*this->priv_addr(), CharT(0));
+         this->priv_size(0);
+      }
+   }
+
+   //! <b>Requires</b>: pos1 <= size().
+   //!
+   //! <b>Effects</b>: Calls replace(pos1, n1, str.data(), str.size()).
+   //!
+   //! <b>Throws</b>: if memory allocation throws or out_of_range if pos1 > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, const basic_string& str)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      if (this->size() - len >= this->max_size() - str.size())
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr = this->priv_addr();
+      return this->replace( const_iterator(addr + pos1)
+                          , const_iterator(addr + pos1 + len)
+                          , str.begin(), str.end());
+   }
+
+   //! <b>Effects</b>: Calls `return replace(pos1, n1, sv.data(), sv.size());`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv)
+   {
+      return this->replace(pos1, n1, sv.data(), sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size().
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to be
+   //!   inserted as the smaller of n2 and str.size() - pos2 and calls
+   //!   replace(pos1, n1, str.data() + pos2, rlen).
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1,
+                         const basic_string& str, size_type pos2, size_type n2 = npos)
+   {
+      if (pos2 > str.size())
+         throw_out_of_range("basic_string::replace out of range position");
+      return this->replace(pos1, n1, str.data()+pos2, dtl::min_value(n2, str.size() - pos2));
+   }
+
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size().
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to be inserted as the
+   //!   smaller of n2 and sv.size() - pos2 and calls `replace(pos1, n1, sv.data() + pos2, rlen)`.
+   //!
+   //! <b>Returns</b>: *this.
+   template<template<class, class> class BasicStringView>
+   basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv,
+                         size_type pos2, size_type n2 = npos)
+   {
+      if (pos2 > sv.size())
+         throw_out_of_range("basic_string::replace out of range position");
+      return this->replace(pos1, n1, sv.data()+pos2, dtl::min_value(n2, sv.size() - pos2));
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the
+   //!   smaller of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error.
+   //!   Otherwise, the function replaces the string controlled by *this with a string of
+   //!   length size() - xlen + n2 whose first pos1 elements are a copy of the initial elements
+   //!   of the original string controlled by *this, whose next n2 elements are a copy of the
+   //!   initial n2 elements of s, and whose remaining elements are a copy of the elements of
+   //!   the original string controlled by *this beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      const size_type max_size = this->max_size();
+      if (n2 > max_size || (this->size() - len) >= (max_size - n2))
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr = this->priv_addr() + pos1;
+      return this->replace(addr, addr + len, s, s + n2);
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller
+   //! of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error. Otherwise,
+   //! the function replaces the string controlled by *this with a string of length size() - xlen + n2
+   //! whose first pos1 elements are a copy of the initial elements of the original string controlled
+   //! by *this, whose next n2 elements are a copy of the initial n2 elements of s, and whose
+   //! remaining elements are a copy of the elements of the original string controlled by *this
+   //! beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos, size_type n1, const CharT* s)
+   {
+      return this->replace(pos, n1, s, Traits::length(s));
+   }
+
+   //! <b>Requires</b>: pos1 <= size().
+   //!
+   //! <b>Effects</b>: Equivalent to replace(pos1, n1, basic_string(n2, c)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the  resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, size_type n2, CharT c)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2)
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr    = this->priv_addr();
+      return this->replace(addr + pos1, addr + pos1 + len, n2, c);
+   }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, str).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str)
+   { return this->replace(i1, i2, str.data(), str.data()+str.size()); }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and
+   //!   s points to an array of at least n elements
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, n).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n)
+   { return this->replace(i1, i2, s, s + n); }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and s points to an
+   //!   array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, traits::length(s)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s)
+   {  return this->replace(i1, i2, s, s + Traits::length(s));   }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(n, c)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, size_type n, CharT c)
+   {
+      const size_type len = static_cast<size_type>(i2 - i1);
+      if (len >= n) {
+         Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), n, c);
+         erase(i1 + n, i2);
+      }
+      else {
+         Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), len, c);
+         insert(i2, n - len, c);
+      }
+      return *this;
+   }
+
+   //! <b>Requires</b>: [begin(),i1), [i1,i2) and [j1,j2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(j1, j2)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InputIter, size_type>
+         , dtl::is_input_iterator<InputIter>
+         >::type * = 0
+      #endif
+      )
+   {
+      for ( ; i1 != i2 && j1 != j2; ++i1, ++j1){
+         Traits::assign(*const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), *j1);
+      }
+
+      if (j1 == j2)
+         this->erase(i1, i2);
+      else
+         this->insert(i2, j1, j2);
+      return *this;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class ForwardIter>
+   basic_string& replace(const_iterator i1, const_iterator i2, ForwardIter j1, ForwardIter j2
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<ForwardIter, size_type>
+         , dtl::is_not_input_iterator<ForwardIter>
+         >::type * = 0
+      )
+   {
+      difference_type n = boost::container::iterator_distance(j1, j2);
+      const difference_type len = i2 - i1;
+      if (len >= n) {
+         this->priv_copy(j1, j2, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
+         this->erase(i1 + n, i2);
+      }
+      else {
+         ForwardIter m = j1;
+         boost::container::iterator_advance(m, len);
+         this->priv_copy(j1, m, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
+         this->insert(i2, m, j2);
+      }
+      return *this;
+   }
+   #endif
+
+   //! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls `replace(i1 - begin(), i2 - i1, sv).`.
+   //!
+   //! <b>Returns</b>: *this.
+   template<template <class, class> class BasicStringView>
+   basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv)
+   {
+      return this->replace( static_cast<size_type>(i1 - this->cbegin())
+                          , static_cast<size_type>(i2 - i1), sv);
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
+   //!
+   //! <b>Returns</b>: *this.
+   basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
+   {
+      return this->replace( static_cast<size_type>(i1 - this->cbegin())
+                          , static_cast<size_type>(i2 - i1)
+                          , il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Requires</b>: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as the
+   //!   smaller of n and size() - pos. s shall designate an array of at least rlen elements.
+   //!   The function then replaces the string designated by s with a string of length rlen
+   //!   whose elements are a copy of the string controlled by *this beginning at position pos.
+   //!   The function does not append a null object to the string designated by s.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: rlen
+   size_type copy(CharT* s, size_type n, size_type pos = 0) const
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::copy out of range position");
+      const size_type len = dtl::min_value(n, this->size() - pos);
+      Traits::copy(s, boost::movelib::to_raw_pointer(this->priv_addr() + pos), len);
+      return len;
+   }
+
+   //! <b>Effects</b>: *this contains the same sequence of characters that was in s,
+   //!   s contains the same sequence of characters that was in *this.
+   //!
+   //! <b>Throws</b>: Nothing
+   void swap(basic_string& x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+                               || allocator_traits_type::is_always_equal::value)
+   {
+      this->base_t::swap_data(x);
+      dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+      dtl::swap_alloc(this->alloc(), x.alloc(), flag);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                 data access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+   //!
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+   //!
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   const CharT* data()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   CharT* data()  BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   #ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
+   //! <b>Returns</b>: a string_view to the characters in the string.
+   //!
+   //! <b>Complexity</b>: constant time.
+   template<template <class, class> class BasicStringView>
+   operator BasicStringView<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->to_view< BasicStringView<CharT, Traits> >(); }
+   #endif
+
+   //! <b>Returns</b>: a string_view to the characters in the string.
+   //!
+   //! <b>Complexity</b>: constant time.
+   //!
+   //! <b>Note</b>: This function is available to write portable code for compilers
+   //!   that don't support templated conversion operators.
+   template<class BasicStringView>
+   BasicStringView to_view() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return BasicStringView(this->data(), this->size()); }
+
+   //////////////////////////////////////////////
+   //
+   //             string operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
+   //!   of the following conditions hold:
+   //!   1) pos <= xpos and xpos + str.size() <= size();
+   //!   2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find(const basic_string& s, size_type pos = 0) const
+   { return find(s.c_str(), pos, s.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
+   //!   of the following conditions hold:
+   //!   1) pos <= xpos and xpos + sv.size() <= size();
+   //!   2) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+   { return find(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(s,n),pos).
+   size_type find(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos + n > this->size())
+         return npos;
+      else {
+         const pointer addr = this->priv_addr();
+         pointer finish = addr + this->priv_size();
+         const const_iterator result =
+            boost::container::search(boost::movelib::to_raw_pointer(addr + pos),
+                   boost::movelib::to_raw_pointer(finish),
+                   s, s + n, Eq_traits<Traits>());
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string(s), pos).
+   size_type find(const CharT* s, size_type pos = 0) const
+   { return this->find(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
+   size_type find(CharT c, size_type pos = 0) const
+   {
+      const size_type sz = this->size();
+      if (pos >= sz)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         pointer finish = addr + sz;
+         const const_iterator result =
+            boost::container::find_if(addr + pos, finish,
+                  boost::container::bind2nd(Eq_traits<Traits>(), c));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such
+   //!   that both of the following conditions obtain:
+   //!   a) xpos <= pos and xpos + str.size() <= size();
+   //!   b) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type rfind(const basic_string& str, size_type pos = npos) const
+      { return rfind(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such
+   //!   that both of the following conditions obtain:
+   //!   a) xpos <= pos and xpos + sv.size() <= size();
+   //!   b) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type rfind(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return rfind(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string(s, n), pos).
+   size_type rfind(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (n > len)
+         return npos;
+      else if (n == 0)
+         return dtl::min_value(len, pos);
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - n, pos) + n;
+         const const_iterator result = find_end(begin(), last,
+                                                s, s + n,
+                                                Eq_traits<Traits>());
+         return result != last ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: pos <= size() and s points to an array of at least
+   //!   traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string(s), pos).
+   size_type rfind(const CharT* s, size_type pos = npos) const
+      { return rfind(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string<CharT,traits,Allocator>(1,c),pos).
+   size_type rfind(CharT c, size_type pos = npos) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                  boost::container::bind2nd(Eq_traits<Traits>(), c));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
+   //!   following conditions obtain: a) pos <= xpos and xpos < size();
+   //!   b) traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_of(const basic_string& str, size_type pos = 0) const
+      { return this->find_first_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
+   //!   following conditions obtain: a) pos <= xpos and xpos < size();
+   //!   b) traits::eq(at(xpos), sv.at(I)) for some element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+      { return this->find_first_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
+   size_type find_first_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type sz = this->size();
+      if (pos >= sz)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         pointer finish = addr + sz;
+         const_iterator result = boost::container::find_first_of
+            (addr + pos, finish, s, s + n, Eq_traits<Traits>());
+         return result != finish ? result - this->begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string(s), pos).
+   size_type find_first_of(const CharT* s, size_type pos = 0) const
+      { return this->find_first_of(s, pos, Traits::length(s)); }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos).
+   size_type find_first_of(CharT c, size_type pos = 0) const
+    { return this->find(c, pos); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
+   //!   the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+   //!   traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_of(const basic_string& str, size_type pos = npos) const
+      { return this->find_last_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
+   //!   the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+   //!   traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return this->find_last_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string(s, n), pos).
+   size_type find_last_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         const const_iterator last = addr + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_first_of(const_reverse_iterator(last), rend(),
+                               s, s + n, Eq_traits<Traits>());
+         return rresult != rend() ? (rresult.base() - 1) - addr : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string<CharT,traits,Allocator>(1,c),pos).
+   size_type find_last_of(const CharT* s, size_type pos = npos) const
+      { return find_last_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string(s), pos).
+   size_type find_last_of(CharT c, size_type pos = npos) const
+      {  return rfind(c, pos);   }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
+   //!   both of the following conditions obtain:
+   //!   a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), str.at(I)) for no
+   //!   element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
+      { return find_first_not_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
+   //!   both of the following conditions obtain:
+   //!   a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), sv.at(I)) for no
+   //!   element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_first_not_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+      { return find_first_not_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(s, n), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos > this->size())
+         return npos;
+      else {
+         const pointer addr   = this->priv_addr();
+         const pointer finish = addr + this->priv_size();
+         const const_iterator result = boost::container::find_if
+            (addr + pos, finish, Not_within_traits<Traits>(s, s + n));
+         return result != finish ? result - addr : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(s), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos = 0) const
+      { return find_first_not_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(1, c), pos).
+   size_type find_first_not_of(CharT c, size_type pos = 0) const
+   {
+      if (pos > this->size())
+         return npos;
+      else {
+         const pointer addr   = this->priv_addr();
+         const pointer finish = addr + this->priv_size();
+         const const_iterator result
+            = boost::container::find_if(addr + pos, finish,
+                     boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that
+   //!   both of the following conditions obtain: a) xpos <= pos and xpos < size();
+   //!   b) traits::eq(at(xpos), str.at(I)) for no element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
+      { return find_last_not_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that
+   //!   both of the following conditions obtain: a) xpos <= pos and xpos < size();
+   //!   b) traits::eq(at(xpos), sv.at(I)) for no element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_last_not_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return find_last_not_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(s, n), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                    Not_within_traits<Traits>(s, s + n));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(s), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos = npos) const
+      { return find_last_not_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(1, c), pos).
+   size_type find_last_not_of(CharT c, size_type pos = npos) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                  boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: Requires: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of n and size() - pos.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: basic_string<CharT,traits,Allocator>(data()+pos,rlen).
+   basic_string substr(size_type pos = 0, size_type n = npos) const
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::substr out of range position");
+      const pointer addr = this->priv_addr();
+      return basic_string(addr + pos,
+                          addr + pos + dtl::min_value(n, size() - pos), this->alloc());
+   }
+
+   //! <b>Effects</b>: Determines the effective length rlen of the string to compare as
+   //!   the smaller of size() and str.size(). The function then compares the two strings by
+   //!   calling traits::compare(data(), str.data(), rlen).
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: The nonzero result if the result of the comparison is nonzero.
+   //!   Otherwise, returns a value < 0 if size() < str.size(), a 0 value if size() == str.size(),
+   //!   and value > 0 if size() > str.size()
+   int compare(const basic_string& str) const
+   {
+      const pointer addr     = this->priv_addr();
+      const pointer str_addr = str.priv_addr();
+      return s_compare(addr, addr + this->priv_size(), str_addr, str_addr + str.priv_size());
+   }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: compare(basic_string(sv)).
+   template<template <class, class> class BasicStringView>
+   int compare(BasicStringView<CharT,Traits> sv) const
+   {
+      const pointer addr = this->priv_addr();
+      return s_compare(addr, addr + this->priv_size(), sv.data(), sv.data() + sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to compare as
+   //!   the smaller of (this->size() - pos1), n1 and str.size(). The function then compares the two strings by
+   //!   calling traits::compare(data()+pos1, str.data(), rlen).
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(str).
+   int compare(size_type pos1, size_type n1, const basic_string& str) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr    = this->priv_addr();
+      const pointer str_addr = str.priv_addr();
+      return s_compare(addr + pos1,
+                        addr + pos1 + dtl::min_value(n1, this->size() - pos1),
+                        str_addr, str_addr + str.priv_size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size()
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(sv).
+   template<template <class, class> class BasicStringView>
+   int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr    = this->priv_addr() + pos1;
+      const CharT* str_addr = sv.data();
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                       str_addr, str_addr + sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
+   int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const
+   {
+      if (pos1 > this->size() || pos2 > str.size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr     = this->priv_addr() + pos1;
+      const pointer str_addr = str.priv_addr() + pos2;
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                        str_addr, str_addr + dtl::min_value(n2, str.size() - pos2));
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(BasicStringView<CharT, Traits>(sv, pos2, n2)).
+   template<template <class, class> class BasicStringView>
+   int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv, size_type pos2, size_type n2) const
+   {
+      if (pos1 > this->size() || pos2 > sv.size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr     = this->priv_addr() + pos1;
+      const CharT * str_addr = sv.data() + pos2;
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                       str_addr, str_addr + dtl::min_value(n2, sv.size() - pos2));
+   }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: compare(basic_string(s)).
+   int compare(const CharT* s) const
+   {
+      const pointer addr = this->priv_addr();
+      return s_compare(addr, addr + this->priv_size(), s, s + Traits::length(s));
+   }
+
+   //! <b>Requires</b>: pos1 > size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr = this->priv_addr();
+      return s_compare( addr + pos1,
+                        addr + pos1 + dtl::min_value(n1, this->size() - pos1),
+                        s, s + n2);
+   }
+
+   //! <b>Requires</b>: pos1 > size() and s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1, const CharT* s) const
+   {  return this->compare(pos1, n1, s, Traits::length(s)); }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   void priv_reserve(size_type res_arg, const bool null_terminate = true)
+   {
+      if (res_arg > this->max_size()){
+         throw_length_error("basic_string::reserve max_size() exceeded");
+      }
+
+      if (this->capacity() < res_arg){
+         size_type n = dtl::max_value(res_arg, this->size()) + 1;
+         size_type new_cap = this->next_capacity(n);
+         pointer reuse = 0;
+         pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse);
+         size_type new_length = 0;
+
+         const pointer addr = this->priv_addr();
+         new_length += priv_uninitialized_copy
+            (addr, addr + this->priv_size(), new_start);
+         if(null_terminate){
+            this->priv_construct_null(new_start + new_length);
+         }
+         this->deallocate_block();
+         this->is_short(false);
+         this->priv_long_addr(new_start);
+         this->priv_long_size(new_length);
+         this->priv_storage(new_cap);
+      }
+   }
+
+   template<class It1, class It2>
+   static int s_compare(It1 f1, It1 l1, It2 f2, It2 l2)
+   {
+      const difference_type n1 = l1 - f1;
+      const difference_type n2 = l2 - f2;
+      const int cmp = Traits::compare(boost::movelib::to_raw_pointer(f1),
+                                      boost::movelib::to_raw_pointer(f2),
+                                      dtl::min_value(n1, n2));
+      return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
+   }
+
+   template<class AllocVersion>
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion
+      , typename dtl::enable_if<dtl::is_same<AllocVersion, version_1> >::type* = 0)
+   {
+      //Allocate a new buffer.
+      size_type real_cap = 0;
+      const pointer   long_addr    = this->priv_long_addr();
+      const size_type long_size    = this->priv_long_size();
+      const size_type long_storage = this->priv_long_storage();
+      //We can make this nothrow as chars are always NoThrowCopyables
+      BOOST_TRY{
+         pointer reuse = 0;
+         real_cap = long_size+1;
+         const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
+         //Copy and update
+         Traits::copy( boost::movelib::to_raw_pointer(ret)
+                     , boost::movelib::to_raw_pointer(this->priv_long_addr())
+                     , long_size+1);
+         this->priv_long_addr(ret);
+         this->priv_storage(real_cap);
+         //And release old buffer
+         this->alloc().deallocate(long_addr, long_storage);
+      }
+      BOOST_CATCH(...){
+         return;
+      }
+      BOOST_CATCH_END
+   }
+
+   template<class AllocVersion>
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion
+      , typename dtl::enable_if<dtl::is_same<AllocVersion, version_2> >::type* = 0)
+   {
+      size_type received_size = this->priv_long_size()+1;
+      pointer hint = this->priv_long_addr();
+      if(this->alloc().allocation_command
+         ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
+         this->priv_storage(received_size);
+      }
+   }
+
+   void priv_construct_null(pointer p)
+   {  this->construct(p, CharT(0));  }
+
+   // Helper functions used by constructors.  It is a severe error for
+   // any of them to be called anywhere except from within constructors.
+   void priv_terminate_string()
+   {  this->priv_construct_null(this->priv_end_addr());  }
+
+   template<class FwdIt, class Count> inline
+   void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
+   {
+      //Save initial position
+      FwdIt init = first;
+
+      BOOST_TRY{
+         //Construct objects
+         for (; count--; ++first){
+            this->construct(first, val);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; init != first; ++init){
+            this->destroy(init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template<class InpIt, class FwdIt> inline
+   size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
+   {
+      //Save initial destination position
+      FwdIt dest_init = dest;
+      size_type constructed = 0;
+
+      BOOST_TRY{
+         //Try to build objects
+         for (; first != last; ++dest, ++first, ++constructed){
+            this->construct(dest, *first);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; constructed--; ++dest_init){
+            this->destroy(dest_init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+      return (constructed);
+   }
+
+   template <class InputIterator, class OutIterator>
+   void priv_copy(InputIterator first, InputIterator last, OutIterator result)
+   {
+      for ( ; first != last; ++first, ++result)
+         Traits::assign(*result, *first);
+   }
+
+   void priv_copy(const CharT* first, const CharT* last, CharT* result)
+   {  Traits::copy(result, first, last - first);  }
+
+   template <class Integer>
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       Integer n, Integer x,
+                                       dtl::true_)
+   {  return this->replace(first, last, (size_type) n, (CharT) x);   }
+
+   template <class InputIter>
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       InputIter f, InputIter l,
+                                       dtl::false_)
+   {
+      typedef typename boost::container::iterator_traits<InputIter>::iterator_category Category;
+      return this->priv_replace(first, last, f, l, Category());
+   }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+basic_string(InputIterator, InputIterator) ->
+   basic_string<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+basic_string(InputIterator, InputIterator, Allocator const&) ->
+   basic_string<typename iterator_traits<InputIterator>::value_type, Allocator>;
+
+#endif
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   <char
+   ,std::char_traits<char>
+   ,new_allocator<char> >
+string;
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   <wchar_t
+   ,std::char_traits<wchar_t>
+   ,new_allocator<wchar_t> >
+wstring;
+
+#else
+
+template <class CharT, class Traits, class Allocator>
+const typename basic_string<CharT,Traits,Allocator>::size_type
+   basic_string<CharT,Traits,Allocator>::npos;
+
+template<class S>
+struct is_string
+{
+   static const bool value = false;
+};
+
+template<class C, class T, class A>
+struct is_string< basic_string<C, T, A> >
+{
+   static const bool value = true;
+};
+
+#endif
+
+// ------------------------------------------------------------
+// Non-member functions.
+
+// Operator+
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator>
+   operator+(const basic_string<CharT,Traits,Allocator>& x
+            ,const basic_string<CharT,Traits,Allocator>& y)
+{
+   typedef basic_string<CharT,Traits,Allocator> str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
+   result.append(x);
+   result.append(y);
+   return result;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
+      , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
+{
+   x += y;
+   return boost::move(x);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
+      , const basic_string<CharT,Traits,Allocator>& y)
+{
+   x += y;
+   return boost::move(x);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      (const basic_string<CharT,Traits,Allocator>& x
+      ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
+{
+   y.insert(y.begin(), x.begin(), x.end());
+   return boost::move(y);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      (const CharT* s, basic_string<CharT, Traits, Allocator> y)
+{
+   y.insert(y.begin(), s, s + Traits::length(s));
+   return y;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (basic_string<CharT,Traits,Allocator> x, const CharT* s)
+{
+   x += s;
+   return x;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (CharT c, basic_string<CharT,Traits,Allocator> y)
+{
+   y.insert(y.begin(), c);
+   return y;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (basic_string<CharT,Traits,Allocator> x, const CharT c)
+{
+   x += c;
+   return x;
+}
+
+// Operator== and operator!=
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
+   return n == y.size() && Traits::compare(s, y.data(), n) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
+   return x.size() == n && Traits::compare(x.data(), s, n) == 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline 
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+      operator==( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+      operator==( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x == y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(s == y); }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(x == s);   }
+
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator!=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x == y);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator!=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(x == y);  }
+
+// Operator< (and also >, <=, and >=).
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.compare(y) < 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return y.compare(s) > 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   return x.compare(s) < 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return y.compare(x) > 0;  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<(  const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return x.compare(y) < 0;  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y) {
+   return y < x;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const CharT* s, const basic_string<CharT,Traits,Allocator>& y) {
+   return y < s;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   return s < x;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return y < x;  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return y < x;  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+  return !(y < x);
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(y < s);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(s < x);  }
+
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(y < x);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(y < x);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const basic_string<CharT,Traits,Allocator>& x,
+           const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x < y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(s < y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(x < s);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x < y);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(x < y);  }
+
+// Swap.
+template <class CharT, class Traits, class Allocator>
+inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
+{  x.swap(y);  }
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+// I/O.
+namespace dtl {
+
+template <class CharT, class Traits>
+inline bool
+string_fill(std::basic_ostream<CharT, Traits>& os,
+                  std::basic_streambuf<CharT, Traits>* buf,
+                  std::size_t n)
+{
+   CharT f = os.fill();
+   std::size_t i;
+   bool ok = true;
+
+   for (i = 0; i < n; i++)
+      ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
+   return ok;
+}
+
+}  //namespace dtl {
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class CharT, class Traits, class Allocator>
+std::basic_ostream<CharT, Traits>&
+operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s)
+{
+   typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
+   bool ok = false;
+
+   if (sentry) {
+      ok = true;
+      typename basic_string<CharT,Traits,Allocator>::size_type n = s.size();
+      typename basic_string<CharT,Traits,Allocator>::size_type pad_len = 0;
+      const bool left = (os.flags() & std::ios::left) != 0;
+      const std::size_t w = os.width(0);
+      std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
+
+      if (w != 0 && n < w)
+         pad_len = w - n;
+
+      if (!left)
+         ok = dtl::string_fill(os, buf, pad_len);
+
+      ok = ok &&
+            buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
+
+      if (left)
+         ok = ok && dtl::string_fill(os, buf, pad_len);
+   }
+
+   if (!ok)
+      os.setstate(std::ios_base::failbit);
+
+   return os;
+}
+
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>&
+operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
+{
+   typename std::basic_istream<CharT, Traits>::sentry sentry(is);
+
+   if (sentry) {
+      std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+      const std::ctype<CharT>& ctype = std::use_facet<std::ctype<CharT> >(is.getloc());
+
+      s.clear();
+      std::size_t n = is.width(0);
+      if (n == 0)
+         n = static_cast<std::size_t>(-1);
+      else
+         s.reserve(n);
+
+      while (n-- > 0) {
+         typename Traits::int_type c1 = buf->sbumpc();
+
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            CharT c = Traits::to_char_type(c1);
+
+            if (ctype.is(std::ctype<CharT>::space, c)) {
+               if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
+                  is.setstate(std::ios_base::failbit);
+               break;
+            }
+            else
+               s.push_back(c);
+         }
+      }
+
+      // If we have read no characters, then set failbit.
+      if (s.size() == 0)
+         is.setstate(std::ios_base::failbit);
+   }
+   else
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>&
+getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type nread = 0;
+   typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
+   if (sentry) {
+      std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+      s.clear();
+
+      while (nread < s.max_size()) {
+         int c1 = buf->sbumpc();
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            ++nread;
+            CharT c = Traits::to_char_type(c1);
+            if (!Traits::eq(c, delim))
+               s.push_back(c);
+            else
+               break;              // Character is extracted but not appended.
+         }
+      }
+   }
+   if (nread == 0 || nread >= s.max_size())
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline std::basic_istream<CharT, Traits>&
+getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
+{
+   return getline(is, s, '\n');
+}
+
+template <class Ch, class Allocator>
+inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator> const& v)
+{
+   return hash_range(v.begin(), v.end());
+}
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class C, class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_STRING_HPP
diff --git a/include/boost/container/throw_exception.hpp b/include/boost/container/throw_exception.hpp
new file mode 100644
index 0000000..1b6eec1
--- /dev/null
+++ b/include/boost/container/throw_exception.hpp
@@ -0,0 +1,181 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2013. 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_THROW_EXCEPTION_HPP
+#define BOOST_CONTAINER_THROW_EXCEPTION_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#ifndef BOOST_NO_EXCEPTIONS
+   #include <stdexcept> //for std exception types
+   #include <string>    //for implicit std::string conversion
+   #include <new>       //for std::bad_alloc
+#else
+   #include <boost/assert.hpp>
+   #include <cstdlib>   //for std::abort
+#endif
+
+namespace boost {
+namespace container {
+
+#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
+   //The user must provide definitions for the following functions
+
+   void throw_bad_alloc();
+
+   void throw_out_of_range(const char* str);
+
+   void throw_length_error(const char* str);
+
+   void throw_logic_error(const char* str);
+
+   void throw_runtime_error(const char* str);
+
+#elif defined(BOOST_NO_EXCEPTIONS)
+
+   inline void throw_bad_alloc()
+   {
+      const char msg[] = "boost::container bad_alloc thrown";
+      (void)msg;
+      BOOST_ASSERT(!msg);
+      std::abort();
+   }
+
+   inline void throw_out_of_range(const char* str)
+   {
+      const char msg[] = "boost::container out_of_range thrown";
+      (void)msg; (void)str;
+      BOOST_ASSERT_MSG(!msg, str);
+      std::abort();
+   }
+
+   inline void throw_length_error(const char* str)
+   {
+      const char msg[] = "boost::container length_error thrown";
+      (void)msg; (void)str;
+      BOOST_ASSERT_MSG(!msg, str);
+      std::abort();
+   }
+
+   inline void throw_logic_error(const char* str)
+   {
+      const char msg[] = "boost::container logic_error thrown";
+      (void)msg; (void)str;
+      BOOST_ASSERT_MSG(!msg, str);
+      std::abort();
+   }
+
+   inline void throw_runtime_error(const char* str)
+   {
+      const char msg[] = "boost::container runtime_error thrown";
+      (void)msg; (void)str;
+      BOOST_ASSERT_MSG(!msg, str);
+      std::abort();
+   }
+
+#else //defined(BOOST_NO_EXCEPTIONS)
+
+   //! Exception callback called by Boost.Container when fails to allocate the requested storage space.
+   //! <ul>
+   //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
+   //!   is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
+   //!   and <code>std::abort()</code> if the former returns.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
+   //!   the user must provide an implementation and the function should not return.</li>
+   //! </ul>
+   inline void throw_bad_alloc()
+   {
+      throw std::bad_alloc();
+   }
+
+   //! Exception callback called by Boost.Container to signal arguments out of range.
+   //! <ul>
+   //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
+   //!   is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
+   //!   and <code>std::abort()</code> if the former returns.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
+   //!   the user must provide an implementation and the function should not return.</li>
+   //! </ul>
+   inline void throw_out_of_range(const char* str)
+   {
+      throw std::out_of_range(str);
+   }
+
+   //! Exception callback called by Boost.Container to signal errors resizing.
+   //! <ul>
+   //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
+   //!   is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
+   //!   and <code>std::abort()</code> if the former returns.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
+   //!   the user must provide an implementation and the function should not return.</li>
+   //! </ul>
+   inline void throw_length_error(const char* str)
+   {
+      throw std::length_error(str);
+   }
+
+   //! Exception callback called by Boost.Container  to report errors in the internal logical
+   //! of the program, such as violation of logical preconditions or class invariants.
+   //! <ul>
+   //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
+   //!   is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
+   //!   and <code>std::abort()</code> if the former returns.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
+   //!   the user must provide an implementation and the function should not return.</li>
+   //! </ul>
+   inline void throw_logic_error(const char* str)
+   {
+      throw std::logic_error(str);
+   }
+
+   //! Exception callback called by Boost.Container  to report errors that can only be detected during runtime.
+   //! <ul>
+   //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
+   //!   is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
+   //!   and <code>std::abort()</code> if the former returns.</li>
+   //!
+   //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
+   //!   the user must provide an implementation and the function should not return.</li>
+   //! </ul>
+   inline void throw_runtime_error(const char* str)
+   {
+      throw std::runtime_error(str);
+   }
+
+#endif
+
+}}  //namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
diff --git a/include/boost/container/uses_allocator.hpp b/include/boost/container/uses_allocator.hpp
new file mode 100644
index 0000000..e0e3518
--- /dev/null
+++ b/include/boost/container/uses_allocator.hpp
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2013. 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_USES_ALLOCATOR_HPP
+#define BOOST_CONTAINER_USES_ALLOCATOR_HPP
+
+#include <boost/container/uses_allocator_fwd.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+namespace boost {
+namespace container {
+
+//! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed
+//! with an allocator as its last constructor argument.  Ideally, all constructors of T (including the
+//! copy and move constructors) should have a variant that accepts a final argument of
+//! allocator_type.
+//!
+//! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type,
+//! allocator_type and at least one constructor for which allocator_type is the last
+//! parameter.  If not all constructors of T can be called with a final allocator_type argument,
+//! and if T is used in a context where a container must call such a constructor, then the program is
+//! ill-formed.
+//!
+//! <code>
+//!  template <class T, class Allocator = allocator<T> >
+//!  class Z {
+//!    public:
+//!      typedef Allocator allocator_type;
+//!
+//!    // Default constructor with optional allocator suffix
+//!    Z(const allocator_type& a = allocator_type());
+//!
+//!    // Copy constructor and allocator-extended copy constructor
+//!    Z(const Z& zz);
+//!    Z(const Z& zz, const allocator_type& a);
+//! };
+//!
+//! // Specialize trait for class template Z
+//! template <class T, class Allocator = allocator<T> >
+//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
+//! { static const bool value = true;  };
+//! </code>
+//!
+//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)"
+//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
+//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
+//! Applications aiming portability with several compilers should always define this trait.
+//!
+//! In conforming C++11 compilers or compilers supporting SFINAE expressions
+//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
+//! to detect if a type should be constructed with suffix or prefix allocator arguments.
+template <class T>
+struct constructible_with_allocator_suffix
+{  static const bool value = false; };
+
+//! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed
+//! with allocator_arg and T::allocator_type as its first two constructor arguments.
+//! Ideally, all constructors of T (including the copy and move constructors) should have a variant
+//! that accepts these two initial arguments.
+//!
+//! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type,
+//! allocator_type and at least one constructor for which allocator_arg_t is the first
+//! parameter and allocator_type is the second parameter.  If not all constructors of T can be
+//! called with these initial arguments, and if T is used in a context where a container must call such
+//! a constructor, then the program is ill-formed.
+//!
+//! <code>
+//! template <class T, class Allocator = allocator<T> >
+//! class Y {
+//!    public:
+//!       typedef Allocator allocator_type;
+//!
+//!       // Default constructor with and allocator-extended default constructor
+//!       Y();
+//!       Y(allocator_arg_t, const allocator_type& a);
+//!
+//!       // Copy constructor and allocator-extended copy constructor
+//!       Y(const Y& yy);
+//!       Y(allocator_arg_t, const allocator_type& a, const Y& yy);
+//!
+//!       // Variadic constructor and allocator-extended variadic constructor
+//!       template<class ...Args> Y(Args&& args...);
+//!       template<class ...Args>
+//!       Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args);
+//! };
+//!
+//! // Specialize trait for class template Y
+//! template <class T, class Allocator = allocator<T> >
+//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
+//! { static const bool value = true;  };
+//!
+//! </code>
+//!
+//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
+//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
+//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
+//! Applications aiming portability with several compilers should always define this trait.
+//!
+//! In conforming C++11 compilers or compilers supporting SFINAE expressions
+//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
+//! to detect if a type should be constructed with suffix or prefix allocator arguments.
+template <class T>
+struct constructible_with_allocator_prefix
+{  static const bool value = false; };
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace dtl {
+
+template<typename T, typename Allocator>
+struct uses_allocator_imp
+{
+   // Use SFINAE (Substitution Failure Is Not An Error) to detect the
+   // presence of an 'allocator_type' nested type convertilble from Allocator.
+   private:
+   typedef char yes_type;
+   struct no_type{ char dummy[2]; };
+
+   // Match this function if T::allocator_type exists and is
+   // implicitly convertible from Allocator
+   template <class U>
+   static yes_type test(typename U::allocator_type);
+
+   // Match this function if T::allocator_type exists and it's type is `erased_type`.
+   template <class U, class V>
+   static typename dtl::enable_if
+      < dtl::is_same<typename U::allocator_type, erased_type>
+      , yes_type
+      >::type  test(const V&);
+
+   // Match this function if TypeT::allocator_type does not exist or is
+   // not convertible from Allocator.
+   template <typename U>
+   static no_type test(...);
+   static Allocator alloc;  // Declared but not defined
+
+   public:
+   static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type);
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! <b>Remark</b>: Automatically detects whether T has a nested allocator_type that is convertible from
+//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
+//! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not
+//! have a nested allocator_type but is nonetheless constructible using the specified Allocator where either:
+//! the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or
+//! the last argument of a constructor has type Alloc.
+//!
+//! <b>Result</b>: uses_allocator<T, Allocator>::value== true if a type T::allocator_type
+//! exists and either is_convertible<Alloc, T::allocator_type>::value != false or T::allocator_type
+//! is an alias `erased_type`. False otherwise.
+template <typename T, typename Allocator>
+struct uses_allocator
+   : dtl::uses_allocator_imp<T, Allocator>
+{};
+
+}} //namespace boost::container
+
+#endif   //BOOST_CONTAINER_USES_ALLOCATOR_HPP
diff --git a/include/boost/container/uses_allocator_fwd.hpp b/include/boost/container/uses_allocator_fwd.hpp
new file mode 100644
index 0000000..42a5b90
--- /dev/null
+++ b/include/boost/container/uses_allocator_fwd.hpp
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_USES_ALLOCATOR_FWD_HPP
+#define BOOST_CONTAINER_USES_ALLOCATOR_FWD_HPP
+
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/std_fwd.hpp>
+
+//! \file
+//!   This header forward declares boost::container::constructible_with_allocator_prefix,
+//!   boost::container::constructible_with_allocator_suffix and
+//!   boost::container::uses_allocator. Also defines the following types:
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   template <int Dummy = 0>
+   struct std_allocator_arg_holder
+   {
+      static ::std::allocator_arg_t *dummy;
+   };
+
+   template <int Dummy>                                             //Silence null-reference compiler warnings
+   ::std::allocator_arg_t *std_allocator_arg_holder<Dummy>::dummy = reinterpret_cast< ::std::allocator_arg_t * >(0x1234);
+
+typedef const std::allocator_arg_t & allocator_arg_t;
+
+#else
+
+//! The allocator_arg_t struct is an empty structure type used as a unique type to
+//! disambiguate constructor and function overloading. Specifically, several types
+//! have constructors with allocator_arg_t as the first argument, immediately followed
+//! by an argument of a type that satisfies Allocator requirements
+typedef unspecified allocator_arg_t;
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! The `erased_type` struct is an empty struct that serves as a placeholder for a type
+//! T in situations where the actual type T is determined at runtime. For example,
+//! the nested type, `allocator_type`, is an alias for `erased_type` in classes that
+//! use type-erased allocators.
+struct erased_type {};
+
+//! A instance of type
+//! allocator_arg_t
+static allocator_arg_t allocator_arg = BOOST_CONTAINER_DOC1ST(unspecified, *std_allocator_arg_holder<>::dummy);
+
+// @cond
+
+template <class T>
+struct constructible_with_allocator_suffix;
+
+template <class T>
+struct constructible_with_allocator_prefix;
+
+template <typename T, typename Allocator>
+struct uses_allocator;
+
+// @endcond
+
+}} // namespace boost { namespace container {
+
+#endif   //BOOST_CONTAINER_USES_ALLOCATOR_HPP
diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp
new file mode 100644
index 0000000..c3baebc
--- /dev/null
+++ b/include/boost/container/vector.hpp
@@ -0,0 +1,3392 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-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_CONTAINER_VECTOR_HPP
+#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+#include <boost/container/options.hpp>
+// container detail
+#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/container/detail/algorithm.hpp> //equal()
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/copy_move_algo.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/next_capacity.hpp>
+#include <boost/container/detail/value_functors.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// move/algo
+#include <boost/move/algo/adaptive_merge.hpp>
+#include <boost/move/algo/unique.hpp>
+#include <boost/move/algo/predicate.hpp>
+#include <boost/move/algo/detail/set_difference.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>   //for std::initializer_list
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+
+template <class Pointer, bool IsConst>
+class vec_iterator
+{
+   public:
+   typedef std::random_access_iterator_tag                                          iterator_category;
+   typedef typename boost::intrusive::pointer_traits<Pointer>::element_type         value_type;
+   typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type      difference_type;
+   typedef typename dtl::if_c
+      < IsConst
+      , typename boost::intrusive::pointer_traits<Pointer>::template
+                                 rebind_pointer<const value_type>::type
+      , Pointer
+      >::type                                                                       pointer;
+   typedef typename boost::intrusive::pointer_traits<pointer>                       ptr_traits;
+   typedef typename ptr_traits::reference                                           reference;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   Pointer m_ptr;
+
+   public:
+   BOOST_CONTAINER_FORCEINLINE const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return   m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return   m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_ptr(ptr)
+   {}
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+
+   //Constructors
+   BOOST_CONTAINER_FORCEINLINE vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW
+      : m_ptr()   //Value initialization to achieve "null iterators" (N3644)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE vec_iterator(vec_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
+      :  m_ptr(other.get_ptr())
+   {}
+
+   //Pointer like operators
+   BOOST_CONTAINER_FORCEINLINE reference operator*()   const BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr);  return *m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE pointer operator->()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr);  return m_ptr[off];  }
+
+   //Increment / Decrement
+   BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); ++m_ptr;  return *this; }
+
+   BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); }
+
+   BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); --m_ptr; return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); }
+
+   //Arithmetic
+   BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); m_ptr += off; return *this;   }
+
+   BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!m_ptr); m_ptr -= off; return *this;   }
+
+   BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!x.m_ptr); return vec_iterator(x.m_ptr+off);  }
+
+   BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!right.m_ptr); right.m_ptr += off;  return right; }
+
+   BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
+   {  BOOST_ASSERT(!!left.m_ptr); left.m_ptr -= off;  return left; }
+
+   BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return left.m_ptr - right.m_ptr;   }
+
+   //Comparison operators
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==   (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr == r.m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=   (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr != r.m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<    (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr < r.m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=   (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr <= r.m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>    (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr > r.m_ptr;  }
+
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=   (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return l.m_ptr >= r.m_ptr;  }
+};
+
+template<class BiDirPosConstIt, class BiDirValueIt>
+struct vector_insert_ordered_cursor
+{
+   typedef typename iterator_traits<BiDirPosConstIt>::value_type  size_type;
+   typedef typename iterator_traits<BiDirValueIt>::reference      reference;
+
+   BOOST_CONTAINER_FORCEINLINE vector_insert_ordered_cursor(BiDirPosConstIt posit, BiDirValueIt valueit)
+      : last_position_it(posit), last_value_it(valueit)
+   {}
+
+   void operator --()
+   {
+      --last_value_it;
+      --last_position_it;
+      while(this->get_pos() == size_type(-1)){
+         --last_value_it;
+         --last_position_it;
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE size_type get_pos() const
+   {  return *last_position_it;  }
+
+   BOOST_CONTAINER_FORCEINLINE reference get_val()
+   {  return *last_value_it;  }
+
+   BiDirPosConstIt last_position_it;
+   BiDirValueIt last_value_it;
+};
+
+struct initial_capacity_t{};
+
+template<class Pointer, bool IsConst>
+BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
+{  return   it.get_ptr();  }
+
+template<class Pointer, bool IsConst>
+BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
+{  return  it.get_ptr();  }
+
+struct vector_uninitialized_size_t {};
+static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t();
+
+template <class T>
+struct vector_value_traits_base
+{
+   static const bool trivial_dctr = dtl::is_trivially_destructible<T>::value;
+   static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value;
+   static const bool trivial_copy = dtl::is_trivially_copy_constructible<T>::value;
+   static const bool nothrow_copy = dtl::is_nothrow_copy_constructible<T>::value || trivial_copy;
+   static const bool trivial_assign = dtl::is_trivially_copy_assignable<T>::value;
+   static const bool nothrow_assign = dtl::is_nothrow_copy_assignable<T>::value || trivial_assign;
+};
+
+
+template <class Allocator>
+struct vector_value_traits
+   : public vector_value_traits_base<typename Allocator::value_type>
+{
+   typedef vector_value_traits_base<typename Allocator::value_type> base_t;
+   //This is the anti-exception array destructor
+   //to deallocate values already constructed
+   typedef typename dtl::if_c
+      <base_t::trivial_dctr
+      ,dtl::null_scoped_destructor_n<Allocator>
+      ,dtl::scoped_destructor_n<Allocator>
+      >::type   ArrayDestructor;
+   //This is the anti-exception array deallocator
+   typedef dtl::scoped_array_deallocator<Allocator> ArrayDeallocator;
+};
+
+//!This struct deallocates and allocated memory
+template < class Allocator
+         , class StoredSizeType
+         , class AllocatorVersion = typename dtl::version<Allocator>::type
+         >
+struct vector_alloc_holder
+   : public Allocator
+{
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
+
+   public:
+   typedef Allocator                                     allocator_type;
+   typedef StoredSizeType                                stored_size_type;
+   typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
+   typedef typename allocator_traits_type::pointer       pointer;
+   typedef typename allocator_traits_type::size_type     size_type;
+   typedef typename allocator_traits_type::value_type    value_type;
+
+   static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator)
+   {
+      (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc;
+      const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value ||
+                                          !allocator_traits_type::storage_is_unpropagable(from_alloc, p);
+      return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc));
+   }
+
+   static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator)
+   {
+      (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a;
+      const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || 
+              !(allocator_traits_type::storage_is_unpropagable(l_a, l_p) || allocator_traits_type::storage_is_unpropagable(r_a, r_p));
+      return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(l_a, r_a));
+   }
+
+   //Constructor, does not throw
+   vector_alloc_holder()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : Allocator(), m_start(), m_size(), m_capacity()
+   {}
+
+   //Constructor, does not throw
+   template<class AllocConvertible>
+   explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
+   {}
+
+   //Constructor, does not throw
+   template<class AllocConvertible>
+   vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
+      : Allocator(boost::forward<AllocConvertible>(a))
+      , m_start()
+      //Size is initialized here so vector should only call uninitialized_xxx after this
+      , m_size(static_cast<stored_size_type>(initial_size))
+      , m_capacity()
+   {
+      if(initial_size){
+         pointer reuse = pointer();
+         size_type final_cap = initial_size;
+         m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
+         m_capacity = static_cast<stored_size_type>(final_cap);
+      }
+   }
+
+   //Constructor, does not throw
+   vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
+      : Allocator()
+      , m_start()
+      //Size is initialized here so vector should only call uninitialized_xxx after this
+      , m_size(static_cast<stored_size_type>(initial_size))
+      , m_capacity()
+   {
+      if(initial_size){
+         pointer reuse = pointer();
+         size_type final_cap = initial_size;
+         m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
+         m_capacity = static_cast<stored_size_type>(final_cap);
+      }
+   }
+
+   vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(BOOST_MOVE_BASE(Allocator, holder))
+      , m_start(holder.m_start)
+      , m_size(holder.m_size)
+      , m_capacity(holder.m_capacity)
+   {
+      holder.m_start = pointer();
+      holder.m_size = holder.m_capacity = 0;
+   }
+
+   vector_alloc_holder(initial_capacity_t, pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder)
+      : Allocator(BOOST_MOVE_BASE(Allocator, holder))
+      , m_start(p)
+      , m_size(holder.m_size)
+      , m_capacity(static_cast<stored_size_type>(capacity))
+   {
+      allocator_type &this_alloc = this->alloc();
+      allocator_type &x_alloc = holder.alloc();
+      if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){
+         if(this->m_capacity){
+            this->deallocate(this->m_start, this->m_capacity);
+         }
+         m_start = holder.m_start;
+         m_capacity = holder.m_capacity;
+         holder.m_start = pointer();
+         holder.m_capacity = holder.m_size = 0;
+      }
+      else if(this->m_capacity < holder.m_size){
+         size_type const n = holder.m_size;
+         pointer reuse = pointer();
+         size_type final_cap = n;
+         m_start = this->allocation_command(allocate_new, n, final_cap, reuse);
+         m_capacity = static_cast<stored_size_type>(final_cap);
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         this->num_alloc += n != 0;
+         #endif
+      }
+   }
+
+   vector_alloc_holder(initial_capacity_t, pointer p, size_type n)
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : Allocator()
+      , m_start(p)
+      , m_size()
+      //n is guaranteed to fit into stored_size_type
+      , m_capacity(static_cast<stored_size_type>(n))
+   {}
+
+   template<class AllocFwd>
+   vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a)
+      : Allocator(::boost::forward<AllocFwd>(a))
+      , m_start(p)
+      , m_size()
+      , m_capacity(n)
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if(this->m_capacity){
+         this->deallocate(this->m_start, this->m_capacity);
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE pointer allocation_command(boost::container::allocation_type command,
+                              size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
+   {
+      typedef typename dtl::version<Allocator>::type alloc_version;
+      return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n)
+   {
+      const size_type max_alloc = allocator_traits_type::max_size(this->alloc());
+      const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1);
+      if ( max < n )
+         boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
+
+      return allocator_traits_type::allocate(this->alloc(), n);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void deallocate(const pointer &p, size_type n)
+   {
+      allocator_traits_type::deallocate(this->alloc(), p, n);
+   }
+
+   bool try_expand_fwd(size_type at_least)
+   {
+      //There is not enough memory, try to expand the old one
+      const size_type new_cap = this->capacity() + at_least;
+      size_type real_cap = new_cap;
+      pointer reuse = this->start();
+      bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse);
+      //Check for forward expansion
+      if(success){
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_expand_fwd;
+         #endif
+         this->capacity(real_cap);
+      }
+      return success;
+   }
+
+   template<class GrowthFactorType>
+   size_type next_capacity(size_type additional_objects) const
+   {
+      BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size));
+      size_type max = allocator_traits_type::max_size(this->alloc());
+      (clamp_by_stored_size_type)(max, stored_size_type());
+      const size_type remaining_cap = max - size_type(this->m_capacity);
+      const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size);
+
+      if ( remaining_cap < min_additional_cap )
+         boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
+
+      return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max);
+   }
+
+   pointer           m_start;
+   stored_size_type  m_size;
+   stored_size_type  m_capacity;
+
+   void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      boost::adl_move_swap(this->m_start, x.m_start);
+      boost::adl_move_swap(this->m_size, x.m_size);
+      boost::adl_move_swap(this->m_capacity, x.m_capacity);
+   }
+
+   void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      this->m_start     = x.m_start;
+      this->m_size      = x.m_size;
+      this->m_capacity  = x.m_capacity;
+      x.m_start = pointer();
+      x.m_size = x.m_capacity = 0;
+   }
+
+   BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE const pointer   &start() const     BOOST_NOEXCEPT_OR_NOTHROW
+      {  return m_start;  }
+   BOOST_CONTAINER_FORCEINLINE       size_type capacity() const     BOOST_NOEXCEPT_OR_NOTHROW
+      {  return m_capacity;  }
+   BOOST_CONTAINER_FORCEINLINE void start(const pointer &p)       BOOST_NOEXCEPT_OR_NOTHROW
+      {  m_start = p;  }
+   BOOST_CONTAINER_FORCEINLINE void capacity(const size_type &c)  BOOST_NOEXCEPT_OR_NOTHROW
+      {  BOOST_ASSERT( c <= stored_size_type(-1)); m_capacity = c;  }
+
+   private:
+   void priv_first_allocation(size_type cap)
+   {
+      if(cap){
+         pointer reuse = pointer();
+         m_start = this->allocation_command(allocate_new, cap, cap, reuse);
+         m_capacity = cap;
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_alloc;
+         #endif
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &, size_type)
+   {}
+
+   template<class SomeStoredSizeType>
+   BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &s, SomeStoredSizeType)
+   {
+      if (s >= SomeStoredSizeType(-1) ) 
+         s = SomeStoredSizeType(-1);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      (void)command;
+      BOOST_ASSERT( (command & allocate_new));
+      BOOST_ASSERT(!(command & nothrow_allocation));
+      //First detect overflow on smaller stored_size_types
+      if (limit_size > stored_size_type(-1)){
+         boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
+      }
+      (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
+      pointer const p = this->allocate(prefer_in_recvd_out_size);
+      reuse = pointer();
+      return p;
+   }
+
+   pointer priv_allocation_command(version_2, boost::container::allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      //First detect overflow on smaller stored_size_types
+      if (limit_size > stored_size_type(-1)){
+         boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
+      }
+      (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
+      //Allocate memory 
+      pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+      //If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it.
+      (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
+      return p;
+   }
+};
+
+//!This struct deallocates and allocated memory
+template <class Allocator, class StoredSizeType>
+struct vector_alloc_holder<Allocator, StoredSizeType, version_0>
+   : public Allocator
+{
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
+
+   public:
+   typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
+   typedef typename allocator_traits_type::pointer       pointer;
+   typedef typename allocator_traits_type::size_type     size_type;
+   typedef typename allocator_traits_type::value_type    value_type;
+   typedef StoredSizeType                                stored_size_type;
+
+   template <class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
+   friend struct vector_alloc_holder;
+
+   //Constructor, does not throw
+   vector_alloc_holder()
+      BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : Allocator(), m_size()
+   {}
+
+   //Constructor, does not throw
+   template<class AllocConvertible>
+   explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
+      : Allocator(boost::forward<AllocConvertible>(a)), m_size()
+   {}
+
+   //Constructor, does not throw
+   template<class AllocConvertible>
+   vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
+      : Allocator(boost::forward<AllocConvertible>(a))
+      , m_size(initial_size)  //Size is initialized here...
+   {
+      //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
+      this->priv_first_allocation(initial_size);
+   }
+
+   //Constructor, does not throw
+   vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
+      : Allocator()
+      , m_size(initial_size)  //Size is initialized here...
+   {
+      //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
+      this->priv_first_allocation(initial_size);
+   }
+
+   vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
+      : Allocator(BOOST_MOVE_BASE(Allocator, holder))
+      , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
+   {
+      ::boost::container::uninitialized_move_alloc_n
+         (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
+   }
+
+   template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
+   vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> BOOST_RV_REF_END holder)
+      : Allocator()
+      , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort
+   {
+      //Different allocator type so we must check we have enough storage
+      const size_type n = holder.m_size;
+      this->priv_first_allocation(n);
+      ::boost::container::uninitialized_move_alloc_n
+         (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start()));
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap)
+   {
+      if(cap > Allocator::internal_capacity){
+         throw_bad_alloc();
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void deep_swap(vector_alloc_holder &x)
+   {
+      this->priv_deep_swap(x);
+   }
+
+   template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
+   void deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
+   {
+      if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){
+         throw_bad_alloc();
+      }
+      this->priv_deep_swap(x);
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW
+   {  //Containers with version 0 allocators can't be moved without moving elements one by one
+      throw_bad_alloc();
+   }
+
+
+   BOOST_CONTAINER_FORCEINLINE void steal_resources(vector_alloc_holder &)
+   {  //Containers with version 0 allocators can't be moved without moving elements one by one
+      throw_bad_alloc();
+   }
+
+   BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return *this;  }
+
+   BOOST_CONTAINER_FORCEINLINE bool try_expand_fwd(size_type at_least)
+   {  return !at_least;  }
+
+   BOOST_CONTAINER_FORCEINLINE pointer start() const       BOOST_NOEXCEPT_OR_NOTHROW {  return Allocator::internal_storage();  }
+   BOOST_CONTAINER_FORCEINLINE size_type  capacity() const BOOST_NOEXCEPT_OR_NOTHROW {  return Allocator::internal_capacity;  }
+   stored_size_type m_size;
+
+   private:
+
+   template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
+   void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
+   {
+      const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
+      value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
+      value_type *const first_x = boost::movelib::to_raw_pointer(x.start());
+
+      if(this->m_size < x.m_size){
+         boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
+      }
+      else{
+         boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_x, x.m_size, first_this, this->m_size);
+      }
+      boost::adl_move_swap(this->m_size, x.m_size);
+   }
+};
+
+struct growth_factor_60;
+
+template<class T, class Default>
+struct default_if_void
+{
+   typedef T type;
+};
+
+template<class Default>
+struct default_if_void<void, Default>
+{
+   typedef Default type;
+};
+
+template<class Options, class AllocatorSizeType>
+struct get_vector_opt
+{
+   typedef vector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
+                     , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
+                     > type;
+};
+
+template<class AllocatorSizeType>
+struct get_vector_opt<void, AllocatorSizeType>
+{
+   typedef vector_opt<growth_factor_60, AllocatorSizeType> type;
+};
+
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! A vector is a sequence that supports random access to elements, constant
+//! time insertion and removal of elements at the end, and linear time insertion
+//! and removal of elements at the beginning or in the middle. The number of
+//! elements in a vector may vary dynamically; memory management is automatic.
+//!
+//! \tparam T The type of object that is stored in the vector
+//! \tparam Allocator The allocator used for all internal memory management
+//! \tparam Options A type produced from \c boost::container::vector_options.
+template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>), class Options BOOST_CONTAINER_DOCONLY(= void) >
+class vector
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   typedef typename boost::container::allocator_traits<Allocator>::size_type  alloc_size_type;
+   typedef typename get_vector_opt<Options, alloc_size_type>::type            options_type;
+   typedef typename options_type::growth_factor_type                          growth_factor_type;
+   typedef typename options_type::stored_size_type                            stored_size_type;
+   typedef value_less<T>                                                      value_less_t;
+
+   //If provided the stored_size option must specify a type that is equal or a type that is smaller.
+   BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) ||
+                        dtl::is_same<stored_size_type, alloc_size_type>::value) );
+
+   typedef typename dtl::version<Allocator>::type alloc_version;
+   typedef boost::container::vector_alloc_holder<Allocator, stored_size_type> alloc_holder_t;
+   alloc_holder_t m_holder;
+   typedef allocator_traits<Allocator>                      allocator_traits_type;
+   template <class U, class UAllocator, class UOptions>
+   friend class vector;
+
+   typedef typename allocator_traits_type::pointer  pointer_impl;
+   typedef vec_iterator<pointer_impl, false> iterator_impl;
+   typedef vec_iterator<pointer_impl, true > const_iterator_impl;
+
+   protected:
+   static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator)
+   {  return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator);  }
+
+   static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p
+                                  , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator)
+   {  return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator);  }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+
+   typedef T                                                                           value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef Allocator                                                                   stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(iterator_impl)                                       iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl)                                 const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(vector)
+   typedef vector_value_traits<Allocator> value_traits;
+   typedef constant_iterator<T, difference_type>            cvalue_iterator;
+
+   protected:
+
+   BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x)
+   {  return this->m_holder.steal_resources(x.m_holder);   }
+
+   template<class AllocFwd>
+   BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a)
+      : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward<AllocFwd>(a))
+   {}
+
+   BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity)
+      : m_holder(initial_capacity_t(), initial_memory, capacity)
+   {}
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : m_holder()
+   {}
+
+   //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
+      : m_holder(a)
+   {}
+
+   //! <b>Effects</b>: Constructs a vector and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit vector(size_type n)
+      :  m_holder(vector_uninitialized_size, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_value_init_alloc_n
+         (this->m_holder.alloc(), n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n value initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   explicit vector(size_type n, const allocator_type &a)
+      :  m_holder(vector_uninitialized_size, a, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_value_init_alloc_n
+         (this->m_holder.alloc(), n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's default initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   vector(size_type n, default_init_t)
+      :  m_holder(vector_uninitialized_size, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_default_init_alloc_n
+         (this->m_holder.alloc(), n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n default initialized values.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's default initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   vector(size_type n, default_init_t, const allocator_type &a)
+      :  m_holder(vector_uninitialized_size, a, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_default_init_alloc_n
+         (this->m_holder.alloc(), n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   vector(size_type n, const T& value)
+      :  m_holder(vector_uninitialized_size, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_fill_alloc_n
+         (this->m_holder.alloc(), value, n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! <b>Throws</b>: If allocation
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   vector(size_type n, const T& value, const allocator_type& a)
+      :  m_holder(vector_uninitialized_size, a, n)
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += n != 0;
+      #endif
+      boost::container::uninitialized_fill_alloc_n
+         (this->m_holder.alloc(), value, n, this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Constructs a vector
+   //!   and inserts a copy of the range [first, last) in the vector.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+//    template <class InIt>
+//    vector(InIt first, InIt last
+//           BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+//                                  < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+//                                  BOOST_MOVE_I dtl::nat >::type * = 0)
+//           ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
+   template <class InIt>
+   vector(InIt first, InIt last
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+         < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+         BOOST_MOVE_I dtl::nat >::type * = 0)
+      )
+      :  m_holder()
+   {  this->assign(first, last); }
+
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the vector.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's constructor taking a dereferenced InIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [first, last).
+//    template <class InIt>
+//    vector(InIt first, InIt last, const allocator_type& a
+//           BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+//                                  < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+//                                  BOOST_MOVE_I dtl::nat >::type * = 0)
+//           ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
+   template <class InIt>
+   vector(InIt first, InIt last, const allocator_type& a
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+         < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+         BOOST_MOVE_I dtl::nat >::type * = 0)
+      )
+      :  m_holder(a)
+   {  this->assign(first, last); }
+
+   //! <b>Effects</b>: Copy constructs a vector.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's allocation
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   vector(const vector &x)
+      :  m_holder( vector_uninitialized_size
+                 , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc())
+                 , x.size())
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += x.size() != 0;
+      #endif
+      ::boost::container::uninitialized_copy_alloc_n
+         ( this->m_holder.alloc(), x.priv_raw_begin()
+         , x.size(), this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW
+      :  m_holder(boost::move(x.m_holder))
+   {  BOOST_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value));  }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+   //!  and inserts a copy of the range [il.begin(), il.last()) in the vector
+   //!
+   //! <b>Throws</b>: If T's constructor taking a dereferenced initializer_list iterator throws.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : m_holder(a)
+   {
+      this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If T's move constructor or allocation throws
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension to support static_vector
+   template<class OtherAllocator>
+   vector(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
+         , typename dtl::enable_if_c
+            < dtl::is_version<OtherAllocator, 0>::value>::type * = 0
+         )
+      :  m_holder(boost::move(x.m_holder))
+   {}
+
+   #endif   //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocation
+   //!   throws or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   vector(const vector &x, const allocator_type &a)
+      :  m_holder(vector_uninitialized_size, a, x.size())
+   {
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      this->num_alloc += x.size() != 0;
+      #endif
+      ::boost::container::uninitialized_copy_alloc_n_source
+         ( this->m_holder.alloc(), x.priv_raw_begin()
+         , x.size(), this->priv_raw_begin());
+   }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves x's resources to *this if a == allocator_type().
+   //!                 Otherwise copies values from x to *this.
+   //!
+   //! <b>Throws</b>: If allocation or T's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+   vector(BOOST_RV_REF(vector) x, const allocator_type &a)
+      :  m_holder( vector_uninitialized_size, a
+                 , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size()
+                 )
+   {
+      if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){
+         this->m_holder.steal_resources(x.m_holder);
+      }
+      else{
+         const size_type n = x.size();
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         this->num_alloc += n != 0;
+         #endif
+         ::boost::container::uninitialized_move_alloc_n_source
+            ( this->m_holder.alloc(), x.priv_raw_begin()
+            , n, this->priv_raw_begin());
+      }
+   }
+
+   //! <b>Effects</b>: Destroys the vector. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements.
+   ~vector() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      boost::container::destroy_alloc_n
+         (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
+      //vector_alloc_holder deallocates the data
+   }
+
+   //! <b>Effects</b>: Makes *this contain the same elements as x.
+   //!
+   //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+   //! of each of x's elements.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in x.
+   BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
+   {
+      if (&x != this){
+         this->priv_copy_assign(x);
+      }
+      return *this;
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Make *this container contains elements from il.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   BOOST_CONTAINER_FORCEINLINE vector& operator=(std::initializer_list<value_type> il)
+   {
+      this->assign(il.begin(), il.end());
+      return *this;
+   }
+   #endif
+
+   //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
+   //!
+   //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and (allocation throws or value_type's move constructor throws)
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_RV_REF(vector) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                        || allocator_traits_type::is_always_equal::value)
+   {
+      BOOST_ASSERT(&x != this);
+      this->priv_move_assign(boost::move(x));
+      return *this;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
+   //!
+   //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension to support static_vector
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
+                           < vector&
+                           , dtl::is_version<OtherAllocator, 0>
+                           , dtl::is_different<OtherAllocator, allocator_type>
+                           >::type
+      operator=(BOOST_RV_REF_BEG vector<value_type, OtherAllocator> BOOST_RV_REF_END x)
+   {
+      this->priv_move_assign(boost::move(x));
+      return *this;
+   }
+
+   //! <b>Effects</b>: Copy assignment. All x's values are copied to *this.
+   //!
+   //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
+   //!
+   //! <b>Complexity</b>: Linear.
+   //!
+   //! <b>Note</b>: Non-standard extension to support static_vector
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
+                           < vector&
+                           , dtl::is_version<OtherAllocator, 0>
+                           , dtl::is_different<OtherAllocator, allocator_type>
+                           >::type
+      operator=(const vector<value_type, OtherAllocator> &x)
+   {
+      this->priv_copy_assign(x);
+      return *this;
+   }
+
+   #endif
+
+   //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
+   //!   T's constructor/assignment from dereferencing InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template <class InIt>
+   void assign(InIt first, InIt last
+      //Input iterators or version 0 allocator
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
+         < void
+         BOOST_MOVE_I dtl::is_convertible<InIt BOOST_MOVE_I size_type>
+         BOOST_MOVE_I dtl::and_
+            < dtl::is_different<alloc_version BOOST_MOVE_I version_0>
+            BOOST_MOVE_I dtl::is_not_input_iterator<InIt>
+            >
+         >::type * = 0)
+      )
+   {
+      //Overwrite all elements we can from [first, last)
+      iterator cur = this->begin();
+      const iterator end_it = this->end();
+      for ( ; first != last && cur != end_it; ++cur, ++first){
+         *cur = *first;
+      }
+
+      if (first == last){
+         //There are no more elements in the sequence, erase remaining
+         T* const end_pos = this->priv_raw_end();
+         const size_type n = static_cast<size_type>(end_pos - boost::movelib::iterator_to_raw_pointer(cur));
+         this->priv_destroy_last_n(n);
+      }
+      else{
+         //There are more elements in the range, insert the remaining ones
+         this->insert(this->cend(), first, last);
+      }
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's constructor from dereferencing iniializer_list iterator throws.
+   //!
+   BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<T> il)
+   {
+      this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
+   //!   T's constructor/assignment from dereferencing InpIt throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   template <class FwdIt>
+   void assign(FwdIt first, FwdIt last
+      //Forward iterators and version > 0 allocator
+      BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
+         < void
+         BOOST_MOVE_I dtl::is_same<alloc_version BOOST_MOVE_I version_0>
+         BOOST_MOVE_I dtl::is_convertible<FwdIt BOOST_MOVE_I size_type>
+         BOOST_MOVE_I dtl::is_input_iterator<FwdIt>
+         >::type * = 0)
+      )
+   {
+      //For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first
+      //so we can't do any backwards allocation
+      const size_type input_sz = static_cast<size_type>(boost::container::iterator_distance(first, last));
+      const size_type old_capacity = this->capacity();
+      if(input_sz > old_capacity){  //If input range is too big, we need to reallocate
+         size_type real_cap = 0;
+         pointer reuse(this->m_holder.start());
+         pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse));
+         if(!reuse){  //New allocation, just emplace new values
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_alloc;
+            #endif
+            pointer const old_p = this->m_holder.start();
+            if(old_p){
+               this->priv_destroy_all();
+               this->m_holder.deallocate(old_p, old_capacity);
+            }
+            this->m_holder.start(ret);
+            this->m_holder.capacity(real_cap);
+            this->m_holder.m_size = 0;
+            this->priv_uninitialized_construct_at_end(first, last);
+            return;
+         }
+         else{
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_expand_fwd;
+            #endif
+            this->m_holder.capacity(real_cap);
+            //Forward expansion, use assignment + back deletion/construction that comes later
+         }
+      }
+
+      boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size());
+      this->m_holder.m_size = input_sz;
+   }
+
+   //! <b>Effects</b>: Assigns the n copies of val to *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const value_type& val)
+   {  this->assign(cvalue_iterator(val, n), cvalue_iterator());   }
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->m_holder.alloc();  }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->m_holder.alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->m_holder.alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return iterator(this->m_holder.start()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_iterator(this->m_holder.start()); }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+   { return iterator(this->m_holder.start() + this->m_holder.m_size); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->cend(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->end());      }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crbegin(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->begin());       }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crend(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_iterator(this->m_holder.start()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_iterator(this->m_holder.start() + this->m_holder.m_size); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->end());}
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->begin()); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the vector contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return !this->m_holder.m_size; }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->m_holder.m_size; }
+
+   //! <b>Effects</b>: Returns the largest possible size of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return allocator_traits_type::max_size(this->m_holder.alloc()); }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy/move or value initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {  this->priv_resize(new_size, value_init);  }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy/move or default initialization throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void resize(size_type new_size, default_init_t)
+   {  this->priv_resize(new_size, default_init);  }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x)
+   {  this->priv_resize(new_size, x);  }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->m_holder.capacity(); }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
+   BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_cap)
+   {
+      if (this->capacity() < new_cap){
+         this->priv_reserve_no_capacity(new_cap, alloc_version());
+      }
+   }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the vector is unchanged
+   //!
+   //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
+   {  this->priv_shrink_to_fit(alloc_version());   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->m_holder.start();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->m_holder.start();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return this->m_holder.start()[this->m_holder.m_size - 1];
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   back()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return this->m_holder.start()[this->m_holder.m_size - 1];
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->m_holder.m_size > n);
+      return this->m_holder.start()[n];
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->m_holder.m_size > n);
+      return this->m_holder.start()[n];
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns an iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->m_holder.m_size >= n);
+      return iterator(this->m_holder.start()+n);
+   }
+
+   //! <b>Requires</b>: size() >= n.
+   //!
+   //! <b>Effects</b>: Returns a const_iterator to the nth element
+   //!   from the beginning of the container. Returns end()
+   //!   if n == size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->m_holder.m_size >= n);
+      return const_iterator(this->m_holder.start()+n);
+   }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //Range check assert done in priv_index_of
+      return this->priv_index_of(vector_iterator_get_ptr(p));
+   }
+
+   //! <b>Requires</b>: begin() <= p <= end().
+   //!
+   //! <b>Effects</b>: Returns the index of the element pointed by p
+   //!   and size() if p == end().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      //Range check assert done in priv_index_of
+      return this->priv_index_of(vector_iterator_get_ptr(p));
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference at(size_type n)
+   {
+      this->priv_throw_if_out_of_range(n);
+      return this->m_holder.start()[n];
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference at(size_type n) const
+   {
+      this->priv_throw_if_out_of_range(n);
+      return this->m_holder.start()[n];
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                 data access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+   //!   For a non-empty vector, data() == &front().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   T* data() BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_raw_begin(); }
+
+   //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+   //!   For a non-empty vector, data() == &front().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const T * data()  const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_raw_begin(); }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the end of the vector.
+   //!
+   //! <b>Returns</b>: A reference to the created object.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
+   //!   T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   template<class ...Args>
+   BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_FWD_REF(Args)...args)
+   {
+      if (BOOST_LIKELY(this->room_enough())){
+         //There is more memory, just construct a new object at the end
+         T* const p = this->priv_raw_end();
+         allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward<Args>(args)...);
+         ++this->m_holder.m_size;
+         return *p;
+      }
+      else{
+         typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type;
+         return *this->priv_forward_range_insert_no_capacity
+            (this->back_ptr(), 1, type(::boost::forward<Args>(args)...), alloc_version());
+      }
+   }
+
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... in the end of the vector.
+   //!
+   //! <b>Throws</b>: If the in-place constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   template<class ...Args>
+   BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_FWD_REF(Args)...args)
+   {
+      const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));
+      if (BOOST_LIKELY(is_room_enough)){
+         //There is more memory, just construct a new object at the end
+         allocator_traits_type::construct(this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<Args>(args)...);
+         ++this->m_holder.m_size;
+      }
+      return is_room_enough;
+   }
+
+   //! <b>Requires</b>: position must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Inserts an object of type T constructed with
+   //!   std::forward<Args>(args)... before position
+   //!
+   //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
+   //!   T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   template<class ...Args>
+   iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(position));
+      //Just call more general insert(pos, size, value) and return iterator
+      typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type;
+      return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1
+                                            , type(::boost::forward<Args>(args)...));
+   }
+
+   #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\
+   {\
+      if (BOOST_LIKELY(this->room_enough())){\
+         T* const p = this->priv_raw_end();\
+         allocator_traits_type::construct (this->m_holder.alloc()\
+            , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+         ++this->m_holder.m_size;\
+         return *p;\
+      }\
+      else{\
+         typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+         return *this->priv_forward_range_insert_no_capacity\
+            ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\
+      }\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_MOVE_UREF##N)\
+   {\
+      const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\
+      if (BOOST_LIKELY(is_room_enough)){\
+         allocator_traits_type::construct (this->m_holder.alloc()\
+            , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+         ++this->m_holder.m_size;\
+      }\
+      return is_room_enough;\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      BOOST_ASSERT(this->priv_in_range_or_end(pos));\
+      typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+      return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\
+   }\
+   //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE
+
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(const T &x);
+
+   //! <b>Effects</b>: Constructs a new element in the end of the vector
+   //!   and moves the resources of x to this new element.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or
+   //!   T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! <b>Requires</b>: position must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of x before position.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, const T &x);
+
+   //! <b>Requires</b>: position must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a new element before position with x's resources.
+   //!
+   //! <b>Throws</b>: If memory allocation throws.
+   //!
+   //! <b>Complexity</b>: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+   #endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert n copies of x before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor throws.
+   //!
+   //! <b>Complexity</b>: Linear to n.
+   iterator insert(const_iterator p, size_type n, const T& x)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      dtl::insert_n_copies_proxy<Allocator, T*> proxy(x);
+      return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy);
+   }
+
+   //! <b>Requires</b>: p must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
+   template <class InIt>
+   iterator insert(const_iterator pos, InIt first, InIt last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InIt, size_type>
+         , dtl::is_not_input_iterator<InIt>
+         >::type * = 0
+      #endif
+      )
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(pos));
+      const size_type n_pos = pos - this->cbegin();
+      iterator it(vector_iterator_get_ptr(pos));
+      for(;first != last; ++first){
+         it = this->emplace(it, *first);
+         ++it;
+      }
+      return iterator(this->m_holder.start() + n_pos);
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class FwdIt>
+   iterator insert(const_iterator pos, FwdIt first, FwdIt last
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<FwdIt, size_type>
+         , dtl::is_input_iterator<FwdIt>
+         >::type * = 0
+      )
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(pos));
+      dtl::insert_range_proxy<Allocator, FwdIt, T*> proxy(first);
+      return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy);
+   }
+   #endif
+
+   //! <b>Requires</b>: p must be a valid iterator of *this. num, must
+   //!   be equal to boost::container::iterator_distance(first, last)
+   //!
+   //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy/move constructor/assignment throws.
+   //!
+   //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
+   //!
+   //! <b>Note</b>: This function avoids a linear operation to calculate boost::container::iterator_distance[first, last)
+   //!   for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a
+   //!   a non-standard extension.
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class InIt>
+   iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(pos));
+      BOOST_ASSERT(dtl::is_input_iterator<InIt>::value ||
+                   num == static_cast<size_type>(boost::container::iterator_distance(first, last)));
+      (void)last;
+      dtl::insert_range_proxy<Allocator, InIt, T*> proxy(first);
+      return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy);
+   }
+   #endif
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: position must be a valid iterator of *this.
+   //!
+   //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before position.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or position if first == last.
+   //!
+   //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
+   iterator insert(const_iterator position, std::initializer_list<value_type> il)
+   {
+      //Assertion done in insert()
+      return this->insert(position, il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the last element from the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      //Destroy last element
+      this->priv_destroy_last();
+   }
+
+   //! <b>Effects</b>: Erases the element at position pos.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the elements between pos and the
+   //!   last element. Constant if pos is the last element.
+   iterator erase(const_iterator position)
+   {
+      BOOST_ASSERT(this->priv_in_range(position));
+      const pointer p = vector_iterator_get_ptr(position);
+      T *const pos_ptr = boost::movelib::to_raw_pointer(p);
+      T *const beg_ptr = this->priv_raw_begin();
+      T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
+      //Move elements forward and destroy last
+      this->priv_destroy_last(pos_ptr != new_end_ptr);
+      return iterator(p);
+   }
+
+   //! <b>Effects</b>: Erases the elements pointed by [first, last).
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the distance between first and last
+   //!   plus linear to the elements between pos and the last element.
+   iterator erase(const_iterator first, const_iterator last)
+   {
+      BOOST_ASSERT(first == last ||
+         (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
+      if (first != last){
+         T* const old_end_ptr = this->priv_raw_end();
+         T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
+         T* const last_ptr  = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
+         T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
+         this->priv_destroy_last_n(old_end_ptr - ptr);
+      }
+      return iterator(vector_iterator_get_ptr(first));
+   }
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE void swap(vector& x)
+      BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value
+                                    || allocator_traits_type::is_always_equal::value) &&
+                                    !dtl::is_version<Allocator, 0>::value))
+   {
+      this->priv_swap(x, dtl::bool_<dtl::is_version<Allocator, 0>::value>());
+   }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Swaps the contents of *this and x.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear
+   //!
+   //! <b>Note</b>: Non-standard extension to support static_vector
+   template<class OtherAllocator>
+   BOOST_CONTAINER_FORCEINLINE void swap(vector<T, OtherAllocator> & x
+            , typename dtl::enable_if_and
+                     < void
+                     , dtl::is_version<OtherAllocator, 0>
+                     , dtl::is_different<OtherAllocator, allocator_type>
+                     >::type * = 0
+            )
+   {  this->m_holder.deep_swap(x.m_holder); }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Erases all the elements of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {  this->priv_destroy_all();  }
+
+   //! <b>Effects</b>: Returns true if x and y are equal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y)
+   {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
+
+   //! <b>Effects</b>: Returns true if x and y are unequal
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y)
+   {  return !(x == y); }
+
+   //! <b>Effects</b>: Returns true if x is less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   friend bool operator<(const vector& x, const vector& y)
+   {
+      const_iterator first1(x.cbegin()), first2(y.cbegin());
+      const const_iterator last1(x.cend()), last2(y.cend());
+      for ( ; (first1 != last1) && (first2 != last2); ++first1, ++first2 ) {
+         if (*first1 < *first2) return true;
+         if (*first2 < *first1) return false;
+      }
+      return (first1 == last1) && (first2 != last2);
+   }
+
+   //! <b>Effects</b>: Returns true if x is greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y)
+   {  return y < x;  }
+
+   //! <b>Effects</b>: Returns true if x is equal or less than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y)
+   {  return !(y < x);  }
+
+   //! <b>Effects</b>: Returns true if x is equal or greater than y
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the container.
+   BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y)
+   {  return !(x < y);  }
+
+   //! <b>Effects</b>: x.swap(y)
+   //!
+   //! <b>Complexity</b>: Constant.
+   BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y)
+   {  x.swap(y);  }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory
+   //!   (memory expansion) that will not invalidate iterators.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   bool stable_reserve(size_type new_cap)
+   {
+      const size_type cp = this->capacity();
+      return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp));
+   }
+
+   //Absolutely experimental. This function might change, disappear or simply crash!
+   template<class BiDirPosConstIt, class BiDirValueIt>
+   BOOST_CONTAINER_FORCEINLINE void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
+   {
+      typedef vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t;
+      return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it));
+   }
+
+   template<class InputIt>
+   BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last)
+   {  this->merge(first, last, value_less_t());  }
+
+   template<class InputIt, class Compare>
+   BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last, Compare comp)
+   {
+      size_type const s = this->size();
+      size_type const c = this->capacity();
+      size_type n = 0;
+      size_type const free_cap = c - s;
+      //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer
+      if(!dtl::is_input_iterator<InputIt>::value &&
+         free_cap < (n = static_cast<size_type>(boost::container::iterator_distance(first, last)))){
+         this->priv_merge_in_new_buffer(first, n, comp, alloc_version());
+      }
+      else{
+         iterator pos(this->insert(this->cend(), first, last));
+         T *const raw_beg = this->priv_raw_begin();
+         T *const raw_end = this->priv_raw_end();
+         T *const raw_pos = raw_beg + s;
+         boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n);
+      }
+   }
+
+   template<class InputIt>
+   BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last)
+   {  this->merge_unique(first, last, value_less_t());  }
+
+   template<class InputIt, class Compare>
+   BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp)
+   {
+      size_type const old_size = this->size();
+      this->priv_set_difference_back(first, last, comp);
+      T *const raw_beg = this->priv_raw_begin();
+      T *const raw_end = this->priv_raw_end();
+      T *raw_pos = raw_beg + old_size;
+      boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size());
+   }
+
+   private:
+   template<class PositionValue>
+   void priv_insert_ordered_at(const size_type element_count, PositionValue position_value)
+   {
+      const size_type old_size_pos = this->size();
+      this->reserve(old_size_pos + element_count);
+      T* const begin_ptr = this->priv_raw_begin();
+      size_type insertions_left = element_count;
+      size_type prev_pos = old_size_pos;
+      size_type old_hole_size = element_count;
+
+      //Exception rollback. If any copy throws before the hole is filled, values
+      //already inserted/copied at the end of the buffer will be destroyed.
+      typename value_traits::ArrayDestructor past_hole_values_destroyer
+         (begin_ptr + old_size_pos + element_count, this->m_holder.alloc(), size_type(0u));
+      //Loop for each insertion backwards, first moving the elements after the insertion point,
+      //then inserting the element.
+      while(insertions_left){
+         --position_value;
+         size_type const pos = position_value.get_pos();
+         BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos && pos <= prev_pos);
+         //If needed shift the range after the insertion point and the previous insertion point.
+         //Function will take care if the shift crosses the size() boundary, using copy/move
+         //or uninitialized copy/move if necessary.
+         size_type new_hole_size = (pos != prev_pos)
+            ? priv_insert_ordered_at_shift_range(pos, prev_pos, this->size(), insertions_left)
+            : old_hole_size
+            ;
+         if(new_hole_size){
+            //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards
+            past_hole_values_destroyer.increment_size_backwards(prev_pos - pos);
+            //Insert the new value in the hole
+            allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, position_value.get_val());
+            if(--new_hole_size){
+               //The hole was reduced by the new insertion by one
+               past_hole_values_destroyer.increment_size_backwards(size_type(1u));
+            }
+            else{
+               //Hole was just filled, disable exception rollback and change vector size
+               past_hole_values_destroyer.release();
+               this->m_holder.m_size += element_count;
+            }
+         }
+         else{
+            if(old_hole_size){
+               //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size
+               past_hole_values_destroyer.release();
+               this->m_holder.m_size += element_count;
+            }
+            //Insert the new value in the already constructed range
+            begin_ptr[pos + insertions_left - 1] = position_value.get_val();
+         }
+         --insertions_left;
+         old_hole_size = new_hole_size;
+         prev_pos = pos;
+      }
+   }
+
+   template<class InputIt, class Compare>
+   void priv_set_difference_back(InputIt first1, InputIt last1, Compare comp)
+   {
+      T * old_first2 = this->priv_raw_begin();
+      T * first2 = old_first2;
+      T * last2  = this->priv_raw_end();
+
+      while (first1 != last1) {
+         if (first2 == last2){
+            this->insert(this->cend(), first1, last1);
+            return;
+         }
+
+         if (comp(*first1, *first2)) {
+            this->emplace_back(*first1);
+            T * const raw_begin = this->priv_raw_begin();
+            if(old_first2 != raw_begin)
+            {
+               //Reallocation happened, update range
+               first2 = raw_begin + (first2 - old_first2);
+               last2  = raw_begin + (last2 - old_first2);
+               old_first2 = raw_begin;
+            }
+            ++first1;
+         }
+         else {
+            if (!comp(*first2, *first1)) {
+               ++first1;
+            }
+            ++first2;
+         }
+      }
+   }
+
+   template<class FwdIt, class Compare>
+   BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0)
+   {
+      throw_bad_alloc();
+   }
+
+   template<class FwdIt, class Compare, class Version>
+   void priv_merge_in_new_buffer(FwdIt first, size_type n, Compare comp, Version)
+   {
+      size_type const new_size = this->size() + n;
+      size_type new_cap = new_size;
+      pointer p = pointer();
+      pointer const new_storage = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
+
+      BOOST_ASSERT((new_cap >= this->size() ) && (new_cap - this->size()) >= n);
+      allocator_type &a = this->m_holder.alloc();
+      typename value_traits::ArrayDeallocator new_buffer_deallocator(new_storage, a, new_cap);
+      typename value_traits::ArrayDestructor  new_values_destroyer(new_storage, a, 0u);
+      T* pbeg  = this->priv_raw_begin();
+      size_type const old_size = this->size();
+      T* const pend = pbeg + old_size;
+      T* d_first = boost::movelib::to_raw_pointer(new_storage);
+      size_type added = n;
+      //Merge in new buffer loop
+      while(1){
+         if(!n) {
+            ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pbeg, pend, d_first);
+            break;
+         } 
+         else if(pbeg == pend) {
+            ::boost::container::uninitialized_move_alloc_n(this->m_holder.alloc(), first, n, d_first);
+            break;
+         }
+         //maintain stability moving external values only if they are strictly less
+         else if(comp(*first, *pbeg)) {
+            allocator_traits_type::construct( this->m_holder.alloc(), d_first, *first );
+            new_values_destroyer.increment_size(1u);
+            ++first;
+            --n;
+            ++d_first;
+         }
+         else{
+            allocator_traits_type::construct( this->m_holder.alloc(), d_first, boost::move(*pbeg) );
+            new_values_destroyer.increment_size(1u);
+            ++pbeg;
+            ++d_first;
+         }
+      }
+
+      //Nothrow operations
+      pointer const old_p     = this->m_holder.start();
+      size_type const old_cap = this->m_holder.capacity();
+      boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
+      this->m_holder.deallocate(old_p, old_cap);
+      this->m_holder.m_size = old_size + added;
+      this->m_holder.start(new_storage);
+      this->m_holder.capacity(new_cap);
+      new_buffer_deallocator.release();
+      new_values_destroyer.release();
+   }
+
+   BOOST_CONTAINER_FORCEINLINE bool room_enough() const
+   {  return this->m_holder.m_size < this->m_holder.capacity();   }
+
+   BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const
+   {  return this->m_holder.start() + this->m_holder.m_size;  }
+
+   size_type priv_index_of(pointer p) const
+   {
+      BOOST_ASSERT(this->m_holder.start() <= p);
+      BOOST_ASSERT(p <= (this->m_holder.start()+this->size()));
+      return static_cast<size_type>(p - this->m_holder.start());
+   }
+
+   template<class OtherAllocator>
+   void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
+      , typename dtl::enable_if_c
+         < dtl::is_version<OtherAllocator, 0>::value >::type * = 0)
+   {
+      if(!dtl::is_same<OtherAllocator, allocator_type>::value &&
+          this->capacity() < x.size()){
+         throw_bad_alloc();
+      }
+      T* const this_start  = this->priv_raw_begin();
+      T* const other_start = x.priv_raw_begin();
+      const size_type this_sz  = m_holder.m_size;
+      const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
+      boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
+      this->m_holder.m_size = other_sz;
+   }
+
+   template<class OtherAllocator>
+   void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_version<OtherAllocator, 0>
+         , dtl::is_different<OtherAllocator, allocator_type>
+         >::type * = 0)
+   {
+      //for move assignment, no aliasing (&x != this) is assummed.
+      BOOST_ASSERT(this != &x);
+      allocator_type &this_alloc = this->m_holder.alloc();
+      allocator_type &x_alloc    = x.m_holder.alloc();
+      const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
+
+      const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc);
+      const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc,   propagate_alloc);
+      const bool are_both_propagable  = is_propagable_from_x && is_propagable_from_t;
+
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(are_both_propagable){
+         //Destroy objects but retain memory in case x reuses it in the future
+         this->clear();
+         this->m_holder.swap_resources(x.m_holder);
+      }
+      else if(is_propagable_from_x){
+         this->clear();
+         this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
+         this->m_holder.steal_resources(x.m_holder);
+      }
+      //Else do a one by one move
+      else{
+         this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
+                     , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end()  ))
+                     );
+      }
+      //Move allocator if needed
+      dtl::move_alloc(this_alloc, x_alloc, dtl::bool_<propagate_alloc>());
+   }
+
+   template<class OtherAllocator>
+   void priv_copy_assign(const vector<T, OtherAllocator> &x
+      , typename dtl::enable_if_c
+         < dtl::is_version<OtherAllocator, 0>::value >::type * = 0)
+   {
+      if(!dtl::is_same<OtherAllocator, allocator_type>::value &&
+         this->capacity() < x.size()){
+         throw_bad_alloc();
+      }
+      T* const this_start  = this->priv_raw_begin();
+      T* const other_start = x.priv_raw_begin();
+      const size_type this_sz  = m_holder.m_size;
+      const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
+      boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
+      this->m_holder.m_size = other_sz;
+   }
+
+   template<class OtherAllocator>
+   typename dtl::disable_if_or
+      < void
+      , dtl::is_version<OtherAllocator, 0>
+      , dtl::is_different<OtherAllocator, allocator_type>
+      >::type
+      priv_copy_assign(const vector<T, OtherAllocator> &x)
+   {
+      allocator_type &this_alloc     = this->m_holder.alloc();
+      const allocator_type &x_alloc  = x.m_holder.alloc();
+      dtl::bool_<allocator_traits_type::
+         propagate_on_container_copy_assignment::value> flag;
+      if(flag && this_alloc != x_alloc){
+         this->clear();
+         this->shrink_to_fit();
+      }
+      dtl::assign_alloc(this_alloc, x_alloc, flag);
+      this->assign( x.priv_raw_begin(), x.priv_raw_end() );
+   }
+
+   template<class Vector>  //Template it to avoid it in explicit instantiations
+   void priv_swap(Vector &x, dtl::true_type)   //version_0
+   {  this->m_holder.deep_swap(x.m_holder);  }
+
+   template<class Vector>  //Template it to avoid it in explicit instantiations
+   void priv_swap(Vector &x, dtl::false_type)  //version_N
+   {
+      const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
+      if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start()
+                            , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){
+         //Just swap internals
+         this->m_holder.swap_resources(x.m_holder);
+      }
+      else{
+         //Else swap element by element...
+         bool const t_smaller = this->size() < x.size();
+         vector &sml = t_smaller ? *this : x;
+         vector &big = t_smaller ? x : *this;
+
+         size_type const common_elements = sml.size();
+         for(size_type i = 0; i != common_elements; ++i){
+            boost::adl_move_swap(sml[i], big[i]);
+         }
+         //... and move-insert the remaining range
+         sml.insert( sml.cend()
+                   , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements)))
+                   , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end()))
+                   );
+         //Destroy remaining elements
+         big.erase(big.nth(common_elements), big.cend());
+      }
+      //And now swap the allocator
+      dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_<propagate_alloc>());
+   }
+
+   void priv_reserve_no_capacity(size_type, version_0)
+   {  throw_bad_alloc();  }
+
+   dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy()
+   {
+      return dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
+         (::boost::make_move_iterator((T *)0));
+   }
+
+   void priv_reserve_no_capacity(size_type new_cap, version_1)
+   {
+      //There is not enough memory, allocate a new buffer
+      //Pass the hint so that allocators can take advantage of this.
+      pointer const p = this->m_holder.allocate(new_cap);
+      //We will reuse insert code, so create a dummy input iterator
+      this->priv_forward_range_insert_new_allocation
+         ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
+   }
+
+   void priv_reserve_no_capacity(size_type new_cap, version_2)
+   {
+      //There is not enough memory, allocate a new
+      //buffer or expand the old one.
+      bool same_buffer_start;
+      size_type real_cap = 0;
+      pointer reuse(this->m_holder.start());
+      pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse));
+
+      //Check for forward expansion
+      same_buffer_start = reuse && this->m_holder.start() == ret;
+      if(same_buffer_start){
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_expand_fwd;
+         #endif
+         this->m_holder.capacity(real_cap);
+      }
+      else{ //If there is no forward expansion, move objects, we will reuse insertion code
+         T * const new_mem = boost::movelib::to_raw_pointer(ret);
+         T * const ins_pos = this->priv_raw_end();
+         if(reuse){   //Backwards (and possibly forward) expansion
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_expand_bwd;
+            #endif
+            this->priv_forward_range_insert_expand_backwards
+               ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
+         }
+         else{ //New buffer
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_alloc;
+            #endif
+            this->priv_forward_range_insert_new_allocation
+               ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
+         }
+      }
+   }
+
+   void priv_destroy_last(const bool moved = false) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      (void)moved;
+      const bool skip_destructor = value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved);
+      if(!skip_destructor){
+         value_type* const p = this->priv_raw_end() - 1;
+         allocator_traits_type::destroy(this->get_stored_allocator(), p);
+      }
+      --this->m_holder.m_size;
+   }
+
+   void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(n <= this->m_holder.m_size);
+      if(!value_traits::trivial_dctr){
+         T* const destroy_pos = this->priv_raw_begin() + (this->m_holder.m_size-n);
+         boost::container::destroy_alloc_n(this->get_stored_allocator(), destroy_pos, n);
+      }
+      this->m_holder.m_size -= n;
+   }
+
+   template<class InpIt>
+   void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
+   {
+      T* const old_end_pos = this->priv_raw_end();
+      T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos);
+      this->m_holder.m_size += new_end_pos - old_end_pos;
+   }
+
+   void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      boost::container::destroy_alloc_n
+         (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
+      this->m_holder.m_size = 0;
+   }
+
+   template<class U>
+   iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
+   {
+      BOOST_ASSERT(this->priv_in_range_or_end(p));
+      return this->priv_forward_range_insert
+         ( vector_iterator_get_ptr(p), 1, dtl::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x)));
+   }
+
+   dtl::insert_copy_proxy<Allocator, T*> priv_single_insert_proxy(const T &x)
+   {  return dtl::insert_copy_proxy<Allocator, T*> (x);  }
+
+   dtl::insert_move_proxy<Allocator, T*> priv_single_insert_proxy(BOOST_RV_REF(T) x)
+   {  return dtl::insert_move_proxy<Allocator, T*> (x);  }
+
+   template <class U>
+   void priv_push_back(BOOST_FWD_REF(U) u)
+   {
+      if (BOOST_LIKELY(this->room_enough())){
+         //There is more memory, just construct a new object at the end
+         allocator_traits_type::construct
+            ( this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<U>(u) );
+         ++this->m_holder.m_size;
+      }
+      else{
+         this->priv_forward_range_insert_no_capacity
+            ( this->back_ptr(), 1
+            , this->priv_single_insert_proxy(::boost::forward<U>(u)), alloc_version());
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x)
+   {  return dtl::insert_n_copies_proxy<Allocator, T*>(x);   }
+
+   BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t)
+   {  return dtl::insert_default_initialized_n_proxy<Allocator, T*>();  }
+
+   BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t)
+   {  return dtl::insert_value_initialized_n_proxy<Allocator, T*>(); }
+
+   template <class U>
+   void priv_resize(size_type new_size, const U& u)
+   {
+      const size_type sz = this->size();
+      if (new_size < sz){
+         //Destroy last elements
+         this->priv_destroy_last_n(sz - new_size);
+      }
+      else{
+         const size_type n = new_size - this->size();
+         this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version());
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   void priv_shrink_to_fit(version_1)
+   {
+      const size_type cp = this->m_holder.capacity();
+      if(cp){
+         const size_type sz = this->size();
+         if(!sz){
+            this->m_holder.deallocate(this->m_holder.m_start, cp);
+            this->m_holder.m_start     = pointer();
+            this->m_holder.m_capacity  = 0;
+         }
+         else if(sz < cp){
+            //Allocate a new buffer.
+            //Pass the hint so that allocators can take advantage of this.
+            pointer const p = this->m_holder.allocate(sz);
+
+            //We will reuse insert code, so create a dummy input iterator
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_alloc;
+            #endif
+            this->priv_forward_range_insert_new_allocation
+               ( boost::movelib::to_raw_pointer(p), sz
+               , this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy());
+         }
+      }
+   }
+
+   void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      const size_type cp = this->m_holder.capacity();
+      if(cp){
+         const size_type sz = this->size();
+         if(!sz){
+            this->m_holder.deallocate(this->m_holder.m_start, cp);
+            this->m_holder.m_start     = pointer();
+            this->m_holder.m_capacity  = 0;
+         }
+         else{
+            size_type received_size = sz;
+            pointer reuse(this->m_holder.start());
+            if(this->m_holder.allocation_command
+               (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){
+               this->m_holder.capacity(received_size);
+               #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+               ++this->num_shrink;
+               #endif
+            }
+         }
+      }
+   }
+
+   template <class InsertionProxy>
+   iterator priv_forward_range_insert_no_capacity
+      (const pointer &pos, const size_type, const InsertionProxy , version_0)
+   {
+      throw_bad_alloc();
+      return iterator(pos);
+   }
+
+   template <class InsertionProxy>
+   iterator priv_forward_range_insert_no_capacity
+      (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1)
+   {
+      //Check if we have enough memory or try to expand current memory
+      const size_type n_pos = pos - this->m_holder.start();
+      T *const raw_pos = boost::movelib::to_raw_pointer(pos);
+
+      const size_type new_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
+      //Pass the hint so that allocators can take advantage of this.
+      T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap));
+      #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+      ++this->num_alloc;
+      #endif
+      this->priv_forward_range_insert_new_allocation
+         ( new_buf, new_cap, raw_pos, n, insert_range_proxy);
+      return iterator(this->m_holder.start() + n_pos);
+   }
+
+   template <class InsertionProxy>
+   iterator priv_forward_range_insert_no_capacity
+      (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
+   {
+      //Check if we have enough memory or try to expand current memory
+      T *const raw_pos = boost::movelib::to_raw_pointer(pos);
+      const size_type n_pos = raw_pos - this->priv_raw_begin();
+
+      //There is not enough memory, allocate a new
+      //buffer or expand the old one.
+      size_type real_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
+      pointer reuse(this->m_holder.start());
+      pointer const ret (this->m_holder.allocation_command
+         (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse));
+
+      //Buffer reallocated
+      if(reuse){
+         //Forward expansion, delay insertion
+         if(this->m_holder.start() == ret){
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_expand_fwd;
+            #endif
+            this->m_holder.capacity(real_cap);
+            //Expand forward
+            this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
+         }
+         //Backwards (and possibly forward) expansion
+         else{
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_expand_bwd;
+            #endif
+            this->priv_forward_range_insert_expand_backwards
+               (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
+         }
+      }
+      //New buffer
+      else{
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_alloc;
+         #endif
+         this->priv_forward_range_insert_new_allocation
+            ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
+      }
+
+      return iterator(this->m_holder.start() + n_pos);
+   }
+
+   template <class InsertionProxy>
+   iterator priv_forward_range_insert
+      (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
+   {
+      BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size);
+      //Check if we have enough memory or try to expand current memory
+      const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
+
+      bool same_buffer_start = n <= remaining;
+      if (!same_buffer_start){
+         return priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
+      }
+      else{
+         //Expand forward
+         T *const raw_pos = boost::movelib::to_raw_pointer(pos);
+         const size_type n_pos = raw_pos - this->priv_raw_begin();
+         this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
+         return iterator(this->m_holder.start() + n_pos);
+      }
+   }
+
+   template <class InsertionProxy>
+   iterator priv_forward_range_insert_at_end
+      (const size_type n, const InsertionProxy insert_range_proxy, version_0)
+   {
+      //Check if we have enough memory or try to expand current memory
+      const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
+
+      if (n > remaining){
+         //This will trigger an error
+         throw_bad_alloc();
+      }
+      this->priv_forward_range_insert_at_end_expand_forward(n, insert_range_proxy);
+      return this->end();
+   }
+
+   template <class InsertionProxy, class AllocVersion>
+   BOOST_CONTAINER_FORCEINLINE iterator priv_forward_range_insert_at_end
+      (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion)
+   {
+      return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy);
+   }
+
+   //Takes the range pointed by [first_pos, last_pos) and shifts it to the right
+   //by 'shift_count'. 'limit_pos' marks the end of constructed elements.
+   //
+   //Precondition: first_pos <= last_pos <= limit_pos
+   //
+   //The shift operation might cross limit_pos so elements to moved beyond limit_pos
+   //are uninitialized_moved with an allocator. Other elements are moved.
+   //
+   //The shift operation might left uninitialized elements after limit_pos
+   //and the number of uninitialized elements is returned by the function.
+   //
+   //Old situation:
+   //       first_pos   last_pos         old_limit
+   //             |       |                  |
+   // ____________V_______V__________________V_____________
+   //|   prefix   | range |     suffix       |raw_mem      ~
+   //|____________|_______|__________________|_____________~
+   //
+   //New situation in Case A (hole_size == 0):
+   // range is moved through move assignments
+   //
+   //       first_pos   last_pos         limit_pos
+   //             |       |                  |
+   // ____________V_______V__________________V_____________
+   //|   prefix'  |       |  | range |suffix'|raw_mem      ~
+   //|________________+______|___^___|_______|_____________~
+   //                 |          |
+   //                 |_>_>_>_>_>^
+   //
+   //
+   //New situation in Case B (hole_size >= 0):
+   // range is moved through uninitialized moves
+   //
+   //       first_pos   last_pos         limit_pos
+   //             |       |                  |
+   // ____________V_______V__________________V________________
+   //|    prefix' |       |                  | [hole] | range |
+   //|_______________________________________|________|___^___|
+   //                 |                                   |
+   //                 |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^
+   //
+   //New situation in Case C (hole_size == 0):
+   // range is moved through move assignments and uninitialized moves
+   //
+   //       first_pos   last_pos         limit_pos
+   //             |       |                  |
+   // ____________V_______V__________________V___
+   //|   prefix'  |       |              | range |
+   //|___________________________________|___^___|
+   //                 |                      |
+   //                 |_>_>_>_>_>_>_>_>_>_>_>^
+   size_type priv_insert_ordered_at_shift_range
+      (size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
+   {
+      BOOST_ASSERT(first_pos <= last_pos);
+      BOOST_ASSERT(last_pos <= limit_pos);
+      //
+      T* const begin_ptr = this->priv_raw_begin();
+      T* const first_ptr = begin_ptr + first_pos;
+      T* const last_ptr  = begin_ptr + last_pos;
+
+      size_type hole_size = 0;
+      //Case A:
+      if((last_pos + shift_count) <= limit_pos){
+         //All move assigned
+         boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
+      }
+      //Case B:
+      else if((first_pos + shift_count) >= limit_pos){
+         //All uninitialized_moved
+         ::boost::container::uninitialized_move_alloc
+            (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
+         hole_size = first_pos + shift_count - limit_pos;
+      }
+      //Case C:
+      else{
+         //Some uninitialized_moved
+         T* const limit_ptr    = begin_ptr + limit_pos;
+         T* const boundary_ptr = limit_ptr - shift_count;
+         ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr);
+         //The rest is move assigned
+         boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr);
+      }
+      return hole_size;
+   }
+
+   private:
+   BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const
+   {  return boost::movelib::to_raw_pointer(m_holder.start());  }
+
+   BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const
+   {  return this->priv_raw_begin() + this->m_holder.m_size;  }
+
+   template <class InsertionProxy>
+   void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy)
+   {
+      T* const old_finish = this->priv_raw_end();
+      insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
+      this->m_holder.m_size += n;
+   }
+
+   template <class InsertionProxy>
+   void priv_forward_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
+   {
+      //n can't be 0, because there is nothing to do in that case
+      if(BOOST_UNLIKELY(!n)) return;
+      //There is enough memory
+      T* const old_finish = this->priv_raw_end();
+      const size_type elems_after = old_finish - pos;
+
+      if (!elems_after){
+         insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
+         this->m_holder.m_size += n;
+      }
+      else if (elems_after >= n){
+         //New elements can be just copied.
+         //Move to uninitialized memory last objects
+         ::boost::container::uninitialized_move_alloc
+            (this->m_holder.alloc(), old_finish - n, old_finish, old_finish);
+         this->m_holder.m_size += n;
+         //Copy previous to last objects to the initialized end
+         boost::container::move_backward(pos, old_finish - n, old_finish);
+         //Insert new objects in the pos
+         insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n);
+      }
+      else {
+         //The new elements don't fit in the [pos, end()) range.
+
+         //Copy old [pos, end()) elements to the uninitialized memory (a gap is created)
+         ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n);
+         BOOST_TRY{
+            //Copy first new elements in pos (gap is still there)
+            insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after);
+            //Copy to the beginning of the unallocated zone the last new elements (the gap is closed).
+            insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after);
+            this->m_holder.m_size += n;
+         }
+         BOOST_CATCH(...){
+            boost::container::destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after);
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+   }
+
+   template <class InsertionProxy>
+   void priv_forward_range_insert_new_allocation
+      (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
+   {
+      //n can be zero, if we want to reallocate!
+      T *new_finish = new_start;
+      T *old_finish;
+      //Anti-exception rollbacks
+      typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap);
+      typename value_traits::ArrayDestructor  new_values_destroyer(new_start, this->m_holder.alloc(), 0u);
+
+      //Initialize with [begin(), pos) old buffer
+      //the start of the new buffer
+      T * const old_buffer = this->priv_raw_begin();
+      if(old_buffer){
+         new_finish = ::boost::container::uninitialized_move_alloc
+            (this->m_holder.alloc(), this->priv_raw_begin(), pos, old_finish = new_finish);
+         new_values_destroyer.increment_size(new_finish - old_finish);
+      }
+      //Initialize new objects, starting from previous point
+      old_finish = new_finish;
+      insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
+      new_finish += n;
+      new_values_destroyer.increment_size(new_finish - old_finish);
+      //Initialize from the rest of the old buffer,
+      //starting from previous point
+      if(old_buffer){
+         new_finish = ::boost::container::uninitialized_move_alloc
+            (this->m_holder.alloc(), pos, old_buffer + this->m_holder.m_size, new_finish);
+         //Destroy and deallocate old elements
+         //If there is allocated memory, destroy and deallocate
+         if(!value_traits::trivial_dctr_after_move)
+            boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size);
+         this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
+      }
+      this->m_holder.start(new_start);
+      this->m_holder.m_size = size_type(new_finish - new_start);
+      this->m_holder.capacity(new_cap);
+      //All construction successful, disable rollbacks
+      new_values_destroyer.release();
+      new_buffer_deallocator.release();
+   }
+
+   template <class InsertionProxy>
+   void priv_forward_range_insert_expand_backwards
+         (T* const new_start, const size_type new_capacity,
+          T* const pos, const size_type n, InsertionProxy insert_range_proxy)
+   {
+      //n can be zero to just expand capacity
+      //Backup old data
+      T* const old_start  = this->priv_raw_begin();
+      const size_type old_size = this->m_holder.m_size;
+      T* const old_finish = old_start + old_size;
+
+      //We can have 8 possibilities:
+      const size_type elemsbefore = static_cast<size_type>(pos - old_start);
+      const size_type s_before    = static_cast<size_type>(old_start - new_start);
+      const size_type before_plus_new = elemsbefore + n;
+
+      //Update the vector buffer information to a safe state
+      this->m_holder.start(new_start);
+      this->m_holder.capacity(new_capacity);
+      this->m_holder.m_size = 0;
+
+      //If anything goes wrong, this object will destroy
+      //all the old objects to fulfill previous vector state
+      typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size);
+      //Check if s_before is big enough to hold the beginning of old data + new data
+      if(s_before >= before_plus_new){
+         //Copy first old values before pos, after that the new objects
+         T *const new_elem_pos =
+            ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start);
+         this->m_holder.m_size = elemsbefore;
+         insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n);
+         this->m_holder.m_size = before_plus_new;
+         const size_type new_size = old_size + n;
+         //Check if s_before is so big that even copying the old data + new data
+         //there is a gap between the new data and the old data
+         if(s_before >= new_size){
+            //Old situation:
+            // _________________________________________________________
+            //|            raw_mem                | old_begin | old_end |
+            //| __________________________________|___________|_________|
+            //
+            //New situation:
+            // _________________________________________________________
+            //| old_begin |    new   | old_end |         raw_mem        |
+            //|___________|__________|_________|________________________|
+            //
+            //Now initialize the rest of memory with the last old values
+            if(before_plus_new != new_size){ //Special case to avoid operations in back insertion
+               ::boost::container::uninitialized_move_alloc
+                  (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new);
+               //All new elements correctly constructed, avoid new element destruction
+               this->m_holder.m_size = new_size;
+            }
+            //Old values destroyed automatically with "old_values_destroyer"
+            //when "old_values_destroyer" goes out of scope unless the have trivial
+            //destructor after move.
+            if(value_traits::trivial_dctr_after_move)
+               old_values_destroyer.release();
+         }
+         //s_before is so big that divides old_end
+         else{
+            //Old situation:
+            // __________________________________________________
+            //|            raw_mem         | old_begin | old_end |
+            //| ___________________________|___________|_________|
+            //
+            //New situation:
+            // __________________________________________________
+            //| old_begin |   new    | old_end |  raw_mem        |
+            //|___________|__________|_________|_________________|
+            //
+            //Now initialize the rest of memory with the last old values
+            //All new elements correctly constructed, avoid new element destruction
+            const size_type raw_gap = s_before - before_plus_new;
+            if(!value_traits::trivial_dctr){
+               //Now initialize the rest of s_before memory with the
+               //first of elements after new values
+               ::boost::container::uninitialized_move_alloc_n
+                  (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new);
+               //Now we have a contiguous buffer so program trailing element destruction
+               //and update size to the final size.
+               old_values_destroyer.shrink_forward(new_size-s_before);
+               this->m_holder.m_size = new_size;
+               //Now move remaining last objects in the old buffer begin
+               T * const remaining_pos = pos + raw_gap;
+               if(remaining_pos != old_start){  //Make sure data has to be moved
+                  ::boost::container::move(remaining_pos, old_finish, old_start);
+               }
+               //Once moved, avoid calling the destructors if trivial after move
+               if(value_traits::trivial_dctr_after_move){
+                  old_values_destroyer.release();
+               }
+            }
+            else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy
+               ::boost::container::uninitialized_move_alloc_n
+                  (this->m_holder.alloc(), pos, static_cast<size_type>(old_finish - pos), new_start + before_plus_new);
+               this->m_holder.m_size = new_size;
+               old_values_destroyer.release();
+            }
+         }
+      }
+      else{
+         //Check if we have to do the insertion in two phases
+         //since maybe s_before is not big enough and
+         //the buffer was expanded both sides
+         //
+         //Old situation:
+         // _________________________________________________
+         //| raw_mem | old_begin + old_end |  raw_mem        |
+         //|_________|_____________________|_________________|
+         //
+         //New situation with do_after:
+         // _________________________________________________
+         //|     old_begin + new + old_end     |  raw_mem    |
+         //|___________________________________|_____________|
+         //
+         //New without do_after:
+         // _________________________________________________
+         //| old_begin + new + old_end  |  raw_mem           |
+         //|____________________________|____________________|
+         //
+         const bool do_after = n > s_before;
+
+         //Now we can have two situations: the raw_mem of the
+         //beginning divides the old_begin, or the new elements:
+         if (s_before <= elemsbefore) {
+            //The raw memory divides the old_begin group:
+            //
+            //If we need two phase construction (do_after)
+            //new group is divided in new = new_beg + new_end groups
+            //In this phase only new_beg will be inserted
+            //
+            //Old situation:
+            // _________________________________________________
+            //| raw_mem | old_begin | old_end |  raw_mem        |
+            //|_________|___________|_________|_________________|
+            //
+            //New situation with do_after(1):
+            //This is not definitive situation, the second phase
+            //will include
+            // _________________________________________________
+            //| old_begin | new_beg | old_end |  raw_mem        |
+            //|___________|_________|_________|_________________|
+            //
+            //New situation without do_after:
+            // _________________________________________________
+            //| old_begin | new | old_end |  raw_mem            |
+            //|___________|_____|_________|_____________________|
+            //
+            //Copy the first part of old_begin to raw_mem
+            ::boost::container::uninitialized_move_alloc_n
+               (this->m_holder.alloc(), old_start, s_before, new_start);
+            //The buffer is all constructed until old_end,
+            //so program trailing destruction and assign final size
+            //if !do_after, s_before+n otherwise.
+            size_type new_1st_range;
+            if(do_after){
+               new_1st_range = s_before;
+               //release destroyer and update size
+               old_values_destroyer.release();
+            }
+            else{
+               new_1st_range = n;
+               if(value_traits::trivial_dctr_after_move)
+                  old_values_destroyer.release();
+               else{
+                  old_values_destroyer.shrink_forward(old_size - (s_before - n));
+               }
+            }
+            this->m_holder.m_size = old_size + new_1st_range;
+            //Now copy the second part of old_begin overwriting itself
+            T *const next = ::boost::container::move(old_start + s_before, pos, old_start);
+            //Now copy the new_beg elements
+            insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range);
+
+            //If there is no after work and the last old part needs to be moved to front, do it
+            if(!do_after && (n != s_before)){
+               //Now displace old_end elements
+               ::boost::container::move(pos, old_finish, next + new_1st_range);
+            }
+         }
+         else {
+            //If we have to expand both sides,
+            //we will play if the first new values so
+            //calculate the upper bound of new values
+
+            //The raw memory divides the new elements
+            //
+            //If we need two phase construction (do_after)
+            //new group is divided in new = new_beg + new_end groups
+            //In this phase only new_beg will be inserted
+            //
+            //Old situation:
+            // _______________________________________________________
+            //|   raw_mem     | old_begin | old_end |  raw_mem        |
+            //|_______________|___________|_________|_________________|
+            //
+            //New situation with do_after():
+            // ____________________________________________________
+            //| old_begin |    new_beg    | old_end |  raw_mem     |
+            //|___________|_______________|_________|______________|
+            //
+            //New situation without do_after:
+            // ______________________________________________________
+            //| old_begin | new | old_end |  raw_mem                 |
+            //|___________|_____|_________|__________________________|
+            //
+            //First copy whole old_begin and part of new to raw_mem
+            T * const new_pos = ::boost::container::uninitialized_move_alloc
+               (this->m_holder.alloc(), old_start, pos, new_start);
+            this->m_holder.m_size = elemsbefore;
+            const size_type mid_n = s_before - elemsbefore;
+            insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n);
+            //The buffer is all constructed until old_end,
+            //release destroyer
+            this->m_holder.m_size = old_size + s_before;
+            old_values_destroyer.release();
+
+            if(do_after){
+               //Copy new_beg part
+               insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore);
+            }
+            else{
+               //Copy all new elements
+               const size_type rest_new = n - mid_n;
+               insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new);
+               T* const move_start = old_start + rest_new;
+               //Displace old_end, but make sure data has to be moved
+               T* const move_end = move_start != pos ? ::boost::container::move(pos, old_finish, move_start)
+                                                     : old_finish;
+               //Destroy remaining moved elements from old_end except if they
+               //have trivial destructor after being moved
+               size_type n_destroy = s_before - n;
+               if(!value_traits::trivial_dctr_after_move)
+                  boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
+               this->m_holder.m_size -= n_destroy;
+            }
+         }
+
+         //This is only executed if two phase construction is needed
+         if(do_after){
+            //The raw memory divides the new elements
+            //
+            //Old situation:
+            // ______________________________________________________
+            //|   raw_mem    | old_begin |  old_end   |  raw_mem     |
+            //|______________|___________|____________|______________|
+            //
+            //New situation with do_after(1):
+            // _______________________________________________________
+            //| old_begin   +   new_beg  | new_end |old_end | raw_mem |
+            //|__________________________|_________|________|_________|
+            //
+            //New situation with do_after(2):
+            // ______________________________________________________
+            //| old_begin      +       new            | old_end |raw |
+            //|_______________________________________|_________|____|
+            //
+            const size_type n_after    = n - s_before;
+            const size_type elemsafter = old_size - elemsbefore;
+
+            //We can have two situations:
+            if (elemsafter >= n_after){
+               //The raw_mem from end will divide displaced old_end
+               //
+               //Old situation:
+               // ______________________________________________________
+               //|   raw_mem    | old_begin |  old_end   |  raw_mem     |
+               //|______________|___________|____________|______________|
+               //
+               //New situation with do_after(1):
+               // _______________________________________________________
+               //| old_begin   +   new_beg  | new_end |old_end | raw_mem |
+               //|__________________________|_________|________|_________|
+               //
+               //First copy the part of old_end raw_mem
+               T* finish_n = old_finish - n_after;
+               ::boost::container::uninitialized_move_alloc
+                  (this->m_holder.alloc(), finish_n, old_finish, old_finish);
+               this->m_holder.m_size += n_after;
+               //Displace the rest of old_end to the new position
+               boost::container::move_backward(pos, finish_n, old_finish);
+               //Now overwrite with new_end
+               //The new_end part is [first + (n - n_after), last)
+               insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after);
+            }
+            else {
+               //The raw_mem from end will divide new_end part
+               //
+               //Old situation:
+               // _____________________________________________________________
+               //|   raw_mem    | old_begin |  old_end   |  raw_mem            |
+               //|______________|___________|____________|_____________________|
+               //
+               //New situation with do_after(2):
+               // _____________________________________________________________
+               //| old_begin   +   new_beg  |     new_end   |old_end | raw_mem |
+               //|__________________________|_______________|________|_________|
+               //
+
+               const size_type mid_last_dist = n_after - elemsafter;
+               //First initialize data in raw memory
+
+               //Copy to the old_end part to the uninitialized zone leaving a gap.
+               ::boost::container::uninitialized_move_alloc
+                  (this->m_holder.alloc(), pos, old_finish, old_finish + mid_last_dist);
+
+               typename value_traits::ArrayDestructor old_end_destroyer
+                  (old_finish + mid_last_dist, this->m_holder.alloc(), old_finish - pos);
+
+               //Copy the first part to the already constructed old_end zone
+               insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter);
+               //Copy the rest to the uninitialized zone filling the gap
+               insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist);
+               this->m_holder.m_size += n_after;
+               old_end_destroyer.release();
+            }
+         }
+      }
+   }
+
+   void priv_throw_if_out_of_range(size_type n) const
+   {
+      //If n is out of range, throw an out_of_range exception
+      if (n >= this->size()){
+         throw_out_of_range("vector::at out of range");
+      }
+   }
+
+   BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos < this->end());
+   }
+
+   BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
+   {
+      return (this->begin() <= pos) && (pos <= this->end());
+   }
+
+   #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+   public:
+   unsigned int num_expand_fwd;
+   unsigned int num_expand_bwd;
+   unsigned int num_shrink;
+   unsigned int num_alloc;
+   void reset_alloc_stats()
+   {  num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0;   }
+   #endif
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+vector(InputIterator, InputIterator) ->
+   vector<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+vector(InputIterator, InputIterator, Allocator const&) ->
+   vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
+
+#endif
+
+
+}} //namespace boost::container
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //   #ifndef  BOOST_CONTAINER_CONTAINER_VECTOR_HPP