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
