Squashed 'third_party/boostorg/container/' content from commit 1ad6431

Change-Id: I7d095db3455264c03446268e5675b926bebedb0a
git-subtree-dir: third_party/boostorg/container
git-subtree-split: 1ad64316a432a7f021b4956acf88abc6aaa8a77e
diff --git a/include/boost/container/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