diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp
new file mode 100644
index 0000000..6c0cc96
--- /dev/null
+++ b/include/boost/container/string.hpp
@@ -0,0 +1,3459 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_STRING_HPP
+#define BOOST_CONTAINER_STRING_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/min_max.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/next_capacity.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/minimal_char_traits_header.hpp>
+#include <boost/container/detail/algorithm.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/traits.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/functional/hash.hpp>
+
+#include <algorithm>
+#include <iosfwd>
+#include <istream>
+#include <ostream>
+#include <ios>
+#include <locale>
+#include <cstddef>
+#include <climits>
+
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>   //for std::initializer_list
+#endif
+
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace dtl {
+// ------------------------------------------------------------
+// Class basic_string_base.
+
+// basic_string_base is a helper class that makes it it easier to write
+// an exception-safe version of basic_string.  The constructor allocates,
+// but does not initialize, a block of memory.  The destructor
+// deallocates, but does not destroy elements within, a block of
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using string_base's
+// allocator and whose size is this->m_storage.
+template <class Allocator>
+class basic_string_base
+{
+   basic_string_base & operator=(const basic_string_base &);
+   basic_string_base(const basic_string_base &);
+
+   typedef allocator_traits<Allocator> allocator_traits_type;
+ public:
+   typedef Allocator                                   allocator_type;
+   typedef allocator_type                              stored_allocator_type;
+   typedef typename allocator_traits_type::pointer     pointer;
+   typedef typename allocator_traits_type::value_type  value_type;
+   typedef typename allocator_traits_type::size_type   size_type;
+   typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
+
+   basic_string_base()
+      : members_()
+   {  init(); }
+
+   explicit basic_string_base(const allocator_type& a)
+      : members_(a)
+   {  init(); }
+
+   explicit basic_string_base(BOOST_RV_REF(allocator_type) a)
+      :  members_(boost::move(a))
+   {  this->init();  }
+
+   basic_string_base(const allocator_type& a, size_type n)
+      : members_(a)
+   {
+      this->init();
+      this->allocate_initial_block(n);
+   }
+
+   explicit basic_string_base(size_type n)
+      : members_()
+   {
+      this->init();
+      this->allocate_initial_block(n);
+   }
+
+   ~basic_string_base()
+   {
+      if(!this->is_short()){
+         this->deallocate(this->priv_long_addr(), this->priv_long_storage());
+      }
+   }
+
+   private:
+
+   //This is the structure controlling a long string
+   struct long_t
+   {
+      size_type      is_short  : 1;
+      size_type      length    : (sizeof(size_type)*CHAR_BIT - 1);
+      size_type      storage;
+      pointer        start;
+
+      long_t()
+      {}
+
+      long_t(const long_t &other)
+      {
+         this->is_short = false;
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+      }
+
+      long_t &operator= (const long_t &other)
+      {
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+         return *this;
+      }
+   };
+
+   //This type is the first part of the structure controlling a short string
+   //The "data" member stores
+   struct short_header
+   {
+      unsigned char  is_short  : 1;
+      unsigned char  length    : (CHAR_BIT - 1);
+   };
+
+   //This type has the same alignment and size as long_t but it's POD
+   //so, unlike long_t, it can be placed in a union
+
+   typedef typename dtl::aligned_storage
+      <sizeof(long_t), dtl::alignment_of<long_t>::value>::type   long_raw_t;
+
+   protected:
+   static const size_type  MinInternalBufferChars = 8;
+   static const size_type  AlignmentOfValueType =
+      alignment_of<value_type>::value;
+   static const size_type  ShortDataOffset = ((sizeof(short_header)-1)/AlignmentOfValueType+1)*AlignmentOfValueType;
+   static const size_type  ZeroCostInternalBufferChars =
+      (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
+   static const size_type  UnalignedFinalInternalBufferChars =
+      (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
+                ZeroCostInternalBufferChars : MinInternalBufferChars;
+
+   struct short_t
+   {
+      short_header   h;
+      value_type     data[UnalignedFinalInternalBufferChars];
+   };
+
+   union repr_t
+   {
+      long_raw_t  r;
+      short_t     s;
+
+      const short_t &short_repr() const
+      {  return s;  }
+
+      const long_t &long_repr() const
+      {  return *static_cast<const long_t*>(static_cast<const void*>(r.data));  }
+
+      short_t &short_repr()
+      {  return s;  }
+
+      long_t &long_repr()
+      {  return *static_cast<long_t*>(static_cast<void*>(&r));  }
+   };
+
+   struct members_holder
+      :  public Allocator
+   {
+      members_holder()
+         : Allocator()
+      {}
+
+      template<class AllocatorConvertible>
+      explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
+         :  Allocator(boost::forward<AllocatorConvertible>(a))
+      {}
+
+      repr_t m_repr;
+   } members_;
+
+   const Allocator &alloc() const
+   {  return members_;  }
+
+   Allocator &alloc()
+   {  return members_;  }
+
+   static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
+
+   private:
+
+   static const size_type MinAllocation = InternalBufferChars*2;
+
+   protected:
+   bool is_short() const
+   {
+      //Access and copy (to avoid UB) the first byte of the union to know if the
+      //active representation is short or long
+      short_header hdr;
+      BOOST_STATIC_ASSERT((sizeof(short_header) == 1));
+      *(unsigned char*)&hdr = *(unsigned char*)&this->members_.m_repr;
+      return hdr.is_short != 0;
+   }
+
+   void is_short(bool yes)
+   {
+      const bool was_short = this->is_short();
+      if(yes && !was_short){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
+            );
+         this->members_.m_repr.s.h.is_short = true;
+      }
+      else if(!yes && was_short){
+         allocator_traits_type::construct
+            ( this->alloc()
+            , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
+            );
+         this->members_.m_repr.s.h.is_short = false;
+      }
+   }
+
+   private:
+   void init()
+   {
+      this->members_.m_repr.s.h.is_short = 1;
+      this->members_.m_repr.s.h.length   = 0;
+   }
+
+   protected:
+
+   typedef dtl::integral_constant<unsigned,
+      boost::container::dtl::version<Allocator>::value> alloc_version;
+
+   pointer allocation_command(allocation_type command,
+                         size_type limit_size,
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
+   {
+      if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
+         reuse = 0;
+         command &= ~(expand_fwd | expand_bwd);
+      }
+      return dtl::allocator_version_traits<Allocator>::allocation_command
+         (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
+   }
+
+   size_type next_capacity(size_type additional_objects) const
+   {
+      return growth_factor_100()
+            ( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc()));
+   }
+
+   void deallocate(pointer p, size_type n)
+   {
+      if (p && (n > InternalBufferChars))
+         this->alloc().deallocate(p, n);
+   }
+
+   void construct(pointer p, const value_type &value = value_type())
+   {
+      allocator_traits_type::construct
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(p)
+         , value
+         );
+   }
+
+   void destroy(pointer p, size_type n)
+   {
+      value_type *raw_p = boost::movelib::to_raw_pointer(p);
+      for(; n--; ++raw_p){
+         allocator_traits_type::destroy( this->alloc(), raw_p);
+      }
+   }
+
+   void destroy(pointer p)
+   {
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , boost::movelib::to_raw_pointer(p)
+         );
+   }
+
+   void allocate_initial_block(size_type n)
+   {
+      if (n <= this->max_size()) {
+         if(n > InternalBufferChars){
+            size_type new_cap = this->next_capacity(n);
+            pointer reuse = 0;
+            pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
+            this->is_short(false);
+            this->priv_long_addr(p);
+            this->priv_long_size(0);
+            this->priv_storage(new_cap);
+         }
+      }
+      else{
+         throw_length_error("basic_string::allocate_initial_block max_size() exceeded");
+      }
+   }
+
+   void deallocate_block()
+   {  this->deallocate(this->priv_addr(), this->priv_storage());  }
+
+   size_type max_size() const
+   {  return allocator_traits_type::max_size(this->alloc()) - 1; }
+
+   protected:
+   size_type priv_capacity() const
+   { return this->priv_storage() - 1; }
+
+   pointer priv_short_addr() const
+   {  return pointer_traits::pointer_to(const_cast<value_type&>(this->members_.m_repr.short_repr().data[0]));  }
+
+   pointer priv_long_addr() const
+   {  return this->members_.m_repr.long_repr().start;  }
+
+   pointer priv_addr() const
+   {
+      return this->is_short()
+         ? priv_short_addr()
+         : priv_long_addr()
+         ;
+   }
+
+   pointer priv_end_addr() const
+   {
+      return this->is_short()
+         ? this->priv_short_addr() + this->priv_short_size()
+         : this->priv_long_addr()  + this->priv_long_size()
+         ;
+   }
+
+   void priv_long_addr(pointer addr)
+   {  this->members_.m_repr.long_repr().start = addr;  }
+
+   size_type priv_storage() const
+   {  return this->is_short() ? priv_short_storage() : priv_long_storage();  }
+
+   size_type priv_short_storage() const
+   {  return InternalBufferChars;  }
+
+   size_type priv_long_storage() const
+   {  return this->members_.m_repr.long_repr().storage;  }
+
+   void priv_storage(size_type storage)
+   {
+      if(!this->is_short())
+         this->priv_long_storage(storage);
+   }
+
+   void priv_long_storage(size_type storage)
+   {
+      this->members_.m_repr.long_repr().storage = storage;
+   }
+
+   size_type priv_size() const
+   {  return this->is_short() ? this->priv_short_size() : this->priv_long_size();  }
+
+   size_type priv_short_size() const
+   {  return this->members_.m_repr.short_repr().h.length;  }
+
+   size_type priv_long_size() const
+   {  return this->members_.m_repr.long_repr().length;  }
+
+   void priv_size(size_type sz)
+   {
+      if(this->is_short())
+         this->priv_short_size(sz);
+      else
+         this->priv_long_size(sz);
+   }
+
+   void priv_short_size(size_type sz)
+   {
+      this->members_.m_repr.s.h.length = (unsigned char)sz;
+   }
+
+   void priv_long_size(size_type sz)
+   {
+      this->members_.m_repr.long_repr().length = sz;
+   }
+
+   void swap_data(basic_string_base& other)
+   {
+      if(this->is_short()){
+         if(other.is_short()){
+            repr_t tmp(this->members_.m_repr);
+            this->members_.m_repr = other.members_.m_repr;
+            other.members_.m_repr = tmp;
+         }
+         else{
+            short_t short_backup(this->members_.m_repr.short_repr());
+            this->members_.m_repr.short_repr().~short_t();
+            ::new(&this->members_.m_repr.long_repr()) long_t(other.members_.m_repr.long_repr());
+            other.members_.m_repr.long_repr().~long_t();
+            ::new(&other.members_.m_repr.short_repr()) short_t(short_backup);
+         }
+      }
+      else{
+         if(other.is_short()){
+            short_t short_backup(other.members_.m_repr.short_repr());
+            other.members_.m_repr.short_repr().~short_t();
+            ::new(&other.members_.m_repr.long_repr()) long_t(this->members_.m_repr.long_repr());
+            this->members_.m_repr.long_repr().~long_t();
+            ::new(&this->members_.m_repr.short_repr()) short_t(short_backup);
+         }
+         else{
+            boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+         }
+      }
+   }
+};
+
+}  //namespace dtl {
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! The basic_string class represents a Sequence of characters. It contains all the
+//! usual operations of a Sequence, and, additionally, it contains standard string
+//! operations such as search and concatenation.
+//!
+//! The basic_string class is parameterized by character type, and by that type's
+//! Character Traits.
+//!
+//! This class has performance characteristics very much like vector<>, meaning,
+//! for example, that it does not perform reference-count or copy-on-write, and that
+//! concatenation of two strings is an O(N) operation.
+//!
+//! Some of basic_string's member functions use an unusual method of specifying positions
+//! and ranges. In addition to the conventional method using iterators, many of
+//! basic_string's member functions use a single value pos of type size_type to represent a
+//! position (in which case the position is begin() + pos, and many of basic_string's
+//! member functions use two values, pos and n, to represent a range. In that case pos is
+//! the beginning of the range and n is its size. That is, the range is
+//! [begin() + pos, begin() + pos + n).
+//!
+//! Note that the C++ standard does not specify the complexity of basic_string operations.
+//! In this implementation, basic_string has performance characteristics very similar to
+//! those of vector: access to a single character is O(1), while copy and concatenation
+//! are O(N).
+//!
+//! In this implementation, begin(),
+//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
+//! In this implementation, iterators are only invalidated by member functions that
+//! explicitly change the string's contents.
+//!
+//! \tparam CharT The type of character it contains.
+//! \tparam Traits The Character Traits type, which encapsulates basic character operations
+//! \tparam Allocator The allocator, used for internal memory management.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> >
+#else
+template <class CharT, class Traits, class Allocator>
+#endif
+class basic_string
+   :  private dtl::basic_string_base<Allocator>
+{
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   typedef allocator_traits<Allocator> allocator_traits_type;
+   BOOST_COPYABLE_AND_MOVABLE(basic_string)
+   typedef dtl::basic_string_base<Allocator> base_t;
+   static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
+
+   protected:
+   // Allocator helper class to use a char_traits as a function object.
+
+   template <class Tr>
+   struct Eq_traits
+   {
+      //Compatibility with std::binary_function
+      typedef typename Tr::char_type   first_argument_type;
+      typedef typename Tr::char_type   second_argument_type;
+      typedef bool   result_type;
+
+      bool operator()(const first_argument_type& x, const second_argument_type& y) const
+         { return Tr::eq(x, y); }
+   };
+
+   template <class Tr>
+   struct Not_within_traits
+   {
+      typedef typename Tr::char_type   argument_type;
+      typedef bool                     result_type;
+
+      typedef const typename Tr::char_type* Pointer;
+      const Pointer m_first;
+      const Pointer m_last;
+
+      Not_within_traits(Pointer f, Pointer l)
+         : m_first(f), m_last(l) {}
+
+      bool operator()(const typename Tr::char_type& x) const
+      {
+         return boost::container::find_if(m_first, m_last,
+                        boost::container::bind1st(Eq_traits<Tr>(), x)) == m_last;
+      }
+   };
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:
+   //////////////////////////////////////////////
+   //
+   //                    types
+   //
+   //////////////////////////////////////////////
+   typedef Traits                                                                      traits_type;
+   typedef CharT                                                                       value_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
+   typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
+   typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
+   typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
+   typedef Allocator                                                                   allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(allocator_type)                                      stored_allocator_type;
+   typedef BOOST_CONTAINER_IMPDEF(pointer)                                             iterator;
+   typedef BOOST_CONTAINER_IMPDEF(const_pointer)                                       const_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
+   typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
+   static const size_type npos = size_type(-1);
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   typedef constant_iterator<CharT, difference_type> cvalue_iterator;
+   typedef typename base_t::alloc_version  alloc_version;
+   typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   public:                         // Constructor, destructor, assignment.
+   //////////////////////////////////////////////
+   //
+   //          construct/copy/destroy
+   //
+   //////////////////////////////////////////////
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   struct reserve_t {};
+
+   basic_string(reserve_t, size_type n,
+                const allocator_type& a = allocator_type())
+      //Select allocator as in copy constructor as reserve_t-based constructors
+      //are two step copies optimized for capacity
+      : base_t( allocator_traits_type::select_on_container_copy_construction(a)
+              , n + 1)
+   { this->priv_terminate_string(); }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Effects</b>: Default constructs a basic_string.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   basic_string() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
+      : base_t()
+   { this->priv_terminate_string(); }
+
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
+   //!
+   //! <b>Throws</b>: Nothing
+   explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
+      : base_t(a)
+   { this->priv_terminate_string(); }
+
+   //! <b>Effects</b>: Copy constructs a basic_string.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
+   basic_string(const basic_string& s)
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
+   {
+      this->priv_terminate_string();
+      this->assign(s.begin(), s.end());
+   }
+
+   //! <b>Effects</b>: Same as basic_string(sv.data(), sv.size(), a).
+   //!
+   //! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
+   template<template <class, class> class BasicStringView>
+   explicit basic_string(BasicStringView<CharT, Traits> sv, const Allocator& a = Allocator())
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(a))
+   {
+      this->priv_terminate_string();
+      this->assign(sv);
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   basic_string(BOOST_RV_REF(basic_string) s) BOOST_NOEXCEPT_OR_NOTHROW
+      : base_t(boost::move(s.alloc()))
+   {
+      if(s.alloc() == this->alloc()){
+         this->swap_data(s);
+      }
+      else{
+         this->assign(s.begin(), s.end());
+      }
+   }
+
+   //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Throws</b>: If allocation throws.
+   basic_string(const basic_string& s, const allocator_type &a)
+      :  base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s.begin(), s.end());
+   }
+
+   //! <b>Effects</b>: Move constructor using the specified allocator.
+   //!                 Moves s's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocation throws.
+   //!
+   //! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
+   basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      if(a == this->alloc()){
+         this->swap_data(s);
+      }
+      else{
+         this->assign(s.begin(), s.end());
+      }
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by a specific number of characters of the s string.
+   basic_string(const basic_string& s, size_type pos, size_type n = npos)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      if (pos > s.size())
+         throw_out_of_range("basic_string::basic_string out of range position");
+      else
+         this->assign
+            (s.begin() + pos, s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s string.
+   basic_string(const basic_string& s, size_type pos, size_type n, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      if (pos > s.size())
+         throw_out_of_range("basic_string::basic_string out of range position");
+      else
+         this->assign
+            (s.begin() + pos, s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking a default-constructed allocator,
+   //!   and is initialized by a specific number of characters of the s c-string.
+   basic_string(const CharT* s, size_type n)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + n);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s c-string.
+   basic_string(const CharT* s, size_type n, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + n);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by the null-terminated s c-string.
+   basic_string(const CharT* s)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + Traits::length(s));
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by the null-terminated s c-string.
+   basic_string(const CharT* s, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(s, s + Traits::length(s));
+   }
+
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by n copies of c.
+   basic_string(size_type n, CharT c)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(n, c);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by n copies of c.
+   basic_string(size_type n, CharT c, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(n, c);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and is initialized by n default-initialized characters.
+   basic_string(size_type n, default_init_t)
+      : base_t(n + 1)
+   {
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by n default-initialized characters.
+   basic_string(size_type n, default_init_t, const allocator_type& a)
+      : base_t(a, n + 1)
+   {
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
+   //!   and a range of iterators.
+   template <class InputIterator>
+   basic_string(InputIterator f, InputIterator l)
+      : base_t()
+   {
+      this->priv_terminate_string();
+      this->assign(f, l);
+   }
+
+   //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+   //!   and a range of iterators.
+   template <class InputIterator>
+   basic_string(InputIterator f, InputIterator l, const allocator_type& a)
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(f, l);
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Same as basic_string(il.begin(), il.end(), a).
+   //!
+   basic_string(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+      : base_t(a)
+   {
+      this->priv_terminate_string();
+      this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   ~basic_string() BOOST_NOEXCEPT_OR_NOTHROW
+   {}
+
+   //! <b>Effects</b>: Copy constructs a string.
+   //!
+   //! <b>Postcondition</b>: x == *this.
+   //!
+   //! <b>Complexity</b>: Linear to the elements x contains.
+   basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         dtl::bool_<allocator_traits_type::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            if(!this->is_short()){
+               this->deallocate_block();
+               this->is_short(true);
+               Traits::assign(*this->priv_addr(), CharT(0));
+               this->priv_short_size(0);
+            }
+         }
+         dtl::assign_alloc(this->alloc(), x.alloc(), flag);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+   //!
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and allocation throws
+   //!
+   //! <b>Complexity</b>: Constant if allocator_traits_type::
+   //!   propagate_on_container_move_assignment is true or
+   //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
+   basic_string& operator=(BOOST_RV_REF(basic_string) x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+                                  || allocator_traits_type::is_always_equal::value)
+   {
+      //for move constructor, no aliasing (&x != this) is assummed.
+      BOOST_ASSERT(this != &x);
+      allocator_type &this_alloc = this->alloc();
+      allocator_type &x_alloc    = x.alloc();
+      const bool propagate_alloc = allocator_traits_type::
+            propagate_on_container_move_assignment::value;
+      dtl::bool_<propagate_alloc> flag;
+      const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+      //Resources can be transferred if both allocators are
+      //going to be equal after this function (either propagated or already equal)
+      if(propagate_alloc || allocators_equal){
+         //Destroy objects but retain memory in case x reuses it in the future
+         this->clear();
+         //Move allocator if needed
+         dtl::move_alloc(this_alloc, x_alloc, flag);
+         //Nothrow swap
+         this->swap_data(x);
+      }
+      //Else do a one by one move
+      else{
+         this->assign( x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! <b>Effects</b>: Assignment from a null-terminated c-string.
+   //!
+   basic_string& operator=(const CharT* s)
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! <b>Effects</b>: Returns *this = basic_string(1, c).
+   //!
+   basic_string& operator=(CharT c)
+   { return this->assign(static_cast<size_type>(1), c); }
+
+   //! <b>Effects</b>: Equivalent to return assign(sv).
+   //!
+   template<template <class, class> class BasicStringView>
+   basic_string& operator=(BasicStringView<CharT, Traits> sv)
+   { return this->assign(sv.data(), sv.size()); }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns *this = basic_string(il);
+   //!
+   basic_string& operator=(std::initializer_list<CharT> il)
+   {
+      return this->assign(il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Returns a copy of the internal allocator.
+   //!
+   //! <b>Throws</b>: If allocator's copy constructor throws.
+   //!
+   //! <b>Complexity</b>: Constant.
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->alloc(); }
+
+   //! <b>Effects</b>: Returns a reference to the internal allocator.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Constant.
+   //!
+   //! <b>Note</b>: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->alloc(); }
+
+   //////////////////////////////////////////////
+   //
+   //                iterators
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns an iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rbegin()  BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->priv_end_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crbegin(); }
+
+   //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reverse_iterator rend()  BOOST_NOEXCEPT_OR_NOTHROW
+   { return reverse_iterator(this->priv_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->crend(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_addr(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_end_addr(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->priv_end_addr()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return const_reverse_iterator(this->priv_addr()); }
+
+   //////////////////////////////////////////////
+   //
+   //                capacity
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Returns true if the vector contains no elements.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return !this->priv_size(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type size() const    BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_size(); }
+
+   //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type length() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->size(); }
+
+   //! <b>Effects</b>: Returns the largest possible size of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return base_t::max_size(); }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n, CharT c)
+   {
+      if (n <= this->size())
+         this->erase(this->begin() + n, this->end());
+      else
+         this->append(n - this->size(), c);
+   }
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are value initialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   void resize(size_type n)
+   { resize(n, CharT()); }
+
+
+   //! <b>Effects</b>: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are uninitialized.
+   //!
+   //! <b>Throws</b>: If memory allocation throws
+   //!
+   //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+   //!
+   //! <b>Note</b>: Non-standard extension
+   void resize(size_type n, default_init_t)
+   {
+      if (n <= this->size())
+         this->erase(this->begin() + n, this->end());
+      else{
+         this->priv_reserve(n, false);
+         this->priv_size(n);
+         this->priv_terminate_string();
+      }
+   }
+
+   //! <b>Effects</b>: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->priv_capacity(); }
+
+   //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //!
+   //! <b>Throws</b>: If memory allocation allocation throws
+   void reserve(size_type res_arg)
+   {  this->priv_reserve(res_arg);  }
+
+   //! <b>Effects</b>: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the string is unchanged
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Complexity</b>: Linear to size().
+   void shrink_to_fit()
+   {
+      //Check if shrinking is possible
+      if(this->priv_storage() > InternalBufferChars){
+         //Check if we should pass from dynamically allocated buffer
+         //to the internal storage
+         if(this->priv_size() < InternalBufferChars){
+            //Dynamically allocated buffer attributes
+            pointer   long_addr    = this->priv_long_addr();
+            size_type long_storage = this->priv_long_storage();
+            size_type long_size    = this->priv_long_size();
+            //Shrink from allocated buffer to the internal one, including trailing null
+            Traits::copy( boost::movelib::to_raw_pointer(this->priv_short_addr())
+                        , boost::movelib::to_raw_pointer(long_addr)
+                        , long_size+1);
+            this->is_short(true);
+            this->alloc().deallocate(long_addr, long_storage);
+         }
+         else{
+            //Shrinking in dynamic buffer
+            this->priv_shrink_to_fit_dynamic_buffer(alloc_version());
+         }
+      }
+   }
+
+   //////////////////////////////////////////////
+   //
+   //               element access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         front() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->priv_addr();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the first
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   front() const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *this->priv_addr();
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference         back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(this->priv_addr() + (this->size() - 1u) );
+   }
+
+   //! <b>Requires</b>: !empty()
+   //!
+   //! <b>Effects</b>: Returns a const reference to the last
+   //!   element of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference   back()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      return *(this->priv_addr() + (this->size() - 1u) );
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(this->size() > n);
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   reference at(size_type n)
+   {
+      if (n >= this->size())
+         throw_out_of_range("basic_string::at invalid subscript");
+      return *(this->priv_addr() + n);
+   }
+
+   //! <b>Requires</b>: size() > n.
+   //!
+   //! <b>Effects</b>: Returns a const reference to the nth element
+   //!   from the beginning of the container.
+   //!
+   //! <b>Throws</b>: std::range_error if n >= size()
+   //!
+   //! <b>Complexity</b>: Constant.
+   const_reference at(size_type n) const {
+      if (n >= this->size())
+         throw_out_of_range("basic_string::at invalid subscript");
+      return *(this->priv_addr() + n);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                modifiers
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Calls append(str.data, str.size()).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(const basic_string& s)
+   {  return this->append(s); }
+
+   //! <b>Effects</b>: Same as `return append(sv)`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& operator+=(BasicStringView<CharT, Traits> sv)
+   {
+      return this->append(sv);
+   }
+
+   //! <b>Effects</b>: Calls append(s).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(const CharT* s)
+   {  return this->append(s); }
+
+   //! <b>Effects</b>: Calls append(1, c).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& operator+=(CharT c)
+   {  this->push_back(c); return *this;   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns append(il)
+   //!
+   basic_string& operator+=(std::initializer_list<CharT> il)
+   {
+      return this->append(il);
+   }
+   #endif
+
+   //! <b>Effects</b>: Calls append(str.data(), str.size()).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const basic_string& s)
+   {  return this->append(s.begin(), s.end());  }
+
+   //! <b>Effects</b>: Same as return append(sv.data(), sv.size()).
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& append(BasicStringView<CharT, Traits> sv)
+   {  return this->append(sv.data(), sv.size());  }
+
+   //! <b>Requires</b>: pos <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to append
+   //! as the smaller of n and str.size() - pos and calls append(str.data() + pos, rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws and out_of_range if pos > str.size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const basic_string& s, size_type pos, size_type n = npos)
+   {
+      if (pos > s.size())
+         throw_out_of_range("basic_string::append out of range position");
+      return this->append(s.begin() + pos,
+                          s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Effects</b>: The function replaces the string controlled by *this with
+   //!   a string of length size() + n whose irst size() elements are a copy of the
+   //!   original string controlled by *this and whose remaining
+   //!   elements are a copy of the initial n elements of s.
+   //!
+   //! <b>Throws</b>: If memory allocation throws length_error if size() + n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const CharT* s, size_type n)
+   {  return this->append(s, s + n);  }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls append(s, traits::length(s)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(const CharT* s)
+   {  return this->append(s, s + Traits::length(s));  }
+
+   //! <b>Effects</b>: Equivalent to append(basic_string(n, c)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& append(size_type n, CharT c)
+   {  return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! <b>Requires</b>: [first,last) is a valid range.
+   //!
+   //! <b>Effects</b>: Equivalent to append(basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& append(InputIter first, InputIter last)
+   {  this->insert(this->end(), first, last);   return *this;  }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns append(il.begin(), il.size()).
+   //!
+   basic_string& append(std::initializer_list<CharT> il)
+   {
+      return this->append(il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c).
+   //!
+   void push_back(CharT c)
+   {
+      const size_type old_size = this->priv_size();
+      if (old_size < this->capacity()){
+         const pointer addr = this->priv_addr();
+         this->priv_construct_null(addr + old_size + 1);
+         Traits::assign(addr[old_size], c);
+         this->priv_size(old_size+1);
+      }
+      else{
+         //No enough memory, insert a new object at the end
+         this->append(size_type(1), c);
+      }
+   }
+
+   //! <b>Effects</b>: Equivalent to assign(str, 0, npos).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const basic_string& s)
+   {  return this->operator=(s); }
+
+   //! <b>Effects</b>: Equivalent to return assign(sv.data(), sv.size()).
+   //!
+   //! <b>Returns</b>: *this
+   template<template <class, class> class BasicStringView>
+   basic_string& assign(BasicStringView<CharT, Traits> sv)
+   {  return this->operator=(sv); }
+
+   //! <b>Effects</b>: The function replaces the string controlled by *this
+   //!    with a string of length str.size() whose elements are a copy of the string
+   //!   controlled by str. Leaves str in a valid but unspecified state.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_NOEXCEPT_OR_NOTHROW
+   {  return this->swap_data(ms), *this;  }
+
+   //! <b>Requires</b>: pos <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to assign as
+   //!   the smaller of n and str.size() - pos and calls assign(str.data() + pos rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const basic_string& s, size_type pos, size_type n)
+   {
+      if (pos > s.size())
+         throw_out_of_range("basic_string::assign out of range position");
+      return this->assign(s.begin() + pos,
+                          s.begin() + pos + dtl::min_value(n, s.size() - pos));
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Effects</b>: Replaces the string controlled by *this with a string of
+   //! length n whose elements are a copy of those pointed to by s.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or length_error if n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const CharT* s, size_type n)
+   {  return this->assign(s, s + n);   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls assign(s, traits::length(s)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(const CharT* s)
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(n, c)).
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& assign(size_type n, CharT c)
+   {  return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
+    //!
+    //! <b>Returns</b>: *this
+    basic_string& assign(const CharT* first, const CharT* last)
+    {
+       size_type n = static_cast<size_type>(last - first);
+       this->reserve(n);
+       CharT* ptr = boost::movelib::to_raw_pointer(this->priv_addr());
+       Traits::copy(ptr, first, n);
+       this->priv_construct_null(ptr + n);
+       this->priv_size(n);
+       return *this;
+    }
+
+   //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& assign(InputIter first, InputIter last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_convertible<InputIter, size_type>::type * = 0
+      #endif
+      )
+   {
+      size_type cur = 0;
+      const pointer addr = this->priv_addr();
+      CharT *ptr = boost::movelib::to_raw_pointer(addr);
+      const size_type old_size = this->priv_size();
+      while (first != last && cur != old_size) {
+         Traits::assign(*ptr, *first);
+         ++first;
+         ++cur;
+         ++ptr;
+      }
+      if (first == last)
+         this->erase(addr + cur, addr + old_size);
+      else
+         this->append(first, last);
+      return *this;
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: Returns assign(il.begin(), il.size()).
+   //!
+   basic_string& assign(std::initializer_list<CharT> il)
+   {
+      return this->assign(il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Requires</b>: pos <= size().
+   //!
+   //! <b>Effects</b>: Calls insert(pos, str.data(), str.size()).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const basic_string& s)
+   {
+      const size_type sz = this->size();
+      if (pos > sz)
+         throw_out_of_range("basic_string::insert out of range position");
+      if (sz > this->max_size() - s.size())
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s.begin(), s.end());
+      return *this;
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to insert as
+   //!   the smaller of n and str.size() - pos2 and calls insert(pos1, str.data() + pos2, rlen).
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n = npos)
+   {
+      const size_type sz = this->size();
+      const size_type str_size = s.size();
+      if (pos1 > sz || pos2 > str_size)
+         throw_out_of_range("basic_string::insert out of range position");
+      size_type len = dtl::min_value(n, str_size - pos2);
+      if (sz > this->max_size() - len)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      const CharT *beg_ptr = boost::movelib::to_raw_pointer(s.begin()) + pos2;
+      const CharT *end_ptr = beg_ptr + len;
+      this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
+      return *this;
+   }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT and pos <= size().
+   //!
+   //! <b>Effects</b>: Replaces the string controlled by *this with a string of length size() + n
+   //!   whose first pos elements are a copy of the initial elements of the original string
+   //!   controlled by *this and whose next n elements are a copy of the elements in s and whose
+   //!   remaining elements are a copy of the remaining elements of the original string controlled by *this.
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size() or
+   //!   length_error if size() + n > max_size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const CharT* s, size_type n)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      if (this->size() > this->max_size() - n)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s, s + n);
+      return *this;
+   }
+
+   //! <b>Requires</b>: pos <= size() and s points to an array of at least traits::length(s) + 1 elements of CharT
+   //!
+   //! <b>Effects</b>: Calls insert(pos, s, traits::length(s)).
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - Traits::length(s)
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, const CharT* s)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      size_type len = Traits::length(s);
+      if (this->size() > this->max_size() - len)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(this->priv_addr() + pos, s, s + len);
+      return *this;
+   }
+
+   //! <b>Effects</b>: Equivalent to insert(pos, basic_string(n, c)).
+   //!
+   //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - n
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& insert(size_type pos, size_type n, CharT c)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::insert out of range position");
+      if (this->size() > this->max_size() - n)
+         throw_length_error("basic_string::insert max_size() exceeded");
+      this->insert(const_iterator(this->priv_addr() + pos), n, c);
+      return *this;
+   }
+
+   //! <b>Effects</b>: Same as `return insert(pos, sv.data(), sv.size())`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& insert(size_type pos, BasicStringView<CharT, Traits> sv)
+   {  return this->insert(pos, sv.data(), sv.size());  }
+
+   //! <b>Requires</b>: p is a valid iterator on *this.
+   //!
+   //! <b>Effects</b>: inserts a copy of c before the character referred to by p.
+   //!
+   //! <b>Returns</b>: An iterator which refers to the copy of the inserted character.
+   iterator insert(const_iterator p, CharT c)
+   {
+      size_type new_offset = p - this->priv_addr();
+      this->insert(p, cvalue_iterator(c, 1), cvalue_iterator());
+      return this->priv_addr() + new_offset;
+   }
+
+   //! <b>Requires</b>: p is a valid iterator on *this.
+   //!
+   //! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+   iterator insert(const_iterator p, size_type n, CharT c)
+   {  return this->insert(p, cvalue_iterator(c, n), cvalue_iterator());  }
+
+   //! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
+   //!
+   //! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
+   //!
+   //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+   template <class InputIter>
+   iterator insert(const_iterator p, InputIter first, InputIter last
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InputIter, size_type>
+         , dtl::is_not_input_iterator<InputIter>
+         >::type * = 0
+      #endif
+      )
+   {
+      const size_type n_pos = p - this->cbegin();
+      for ( ; first != last; ++first, ++p) {
+         p = this->insert(p, *first);
+      }
+      return this->begin() + n_pos;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class ForwardIter>
+   iterator insert(const_iterator p, ForwardIter first, ForwardIter last
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<ForwardIter, size_type>
+         , dtl::is_input_iterator<ForwardIter>
+         >::type * = 0
+      )
+   {
+      const size_type n_pos = p - this->cbegin();
+      if (first != last) {
+         const size_type n = boost::container::iterator_distance(first, last);
+         const size_type old_size = this->priv_size();
+         const size_type remaining = this->capacity() - old_size;
+         const pointer old_start = this->priv_addr();
+         bool enough_capacity = false;
+         size_type new_cap = 0;
+
+         //Check if we have enough capacity
+         pointer hint = pointer();
+         pointer allocation_ret = pointer();
+         if (remaining >= n){
+            enough_capacity = true;
+         }
+         else {
+            //Otherwise expand current buffer or allocate new storage
+            new_cap  = this->next_capacity(n);
+            hint = old_start;
+            allocation_ret = this->allocation_command
+                  (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
+
+            //Check forward expansion
+            if(old_start == allocation_ret){
+               enough_capacity = true;
+               this->priv_storage(new_cap);
+            }
+         }
+
+         //Reuse same buffer
+         if(enough_capacity){
+            const size_type elems_after = old_size - (p - old_start);
+            const size_type old_length = old_size;
+            if (elems_after >= n) {
+               const pointer pointer_past_last = old_start + old_size + 1;
+               priv_uninitialized_copy(old_start + (old_size - n + 1),
+                                       pointer_past_last, pointer_past_last);
+
+               this->priv_size(old_size+n);
+               Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
+                           boost::movelib::to_raw_pointer(p),
+                           (elems_after - n) + 1);
+               this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
+            }
+            else {
+               ForwardIter mid = first;
+               boost::container::iterator_advance(mid, elems_after + 1);
+
+               priv_uninitialized_copy(mid, last, old_start + old_size + 1);
+               const size_type newer_size = old_size + (n - elems_after);
+               this->priv_size(newer_size);
+               priv_uninitialized_copy
+                  (p, const_iterator(old_start + old_length + 1),
+                  old_start + newer_size);
+               this->priv_size(newer_size + elems_after);
+               this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
+            }
+         }
+         else{
+            pointer new_start = allocation_ret;
+            if(!hint){
+               //Copy data to new buffer
+               size_type new_length = 0;
+               //This can't throw, since characters are POD
+               new_length += priv_uninitialized_copy
+                              (const_iterator(old_start), p, new_start);
+               new_length += priv_uninitialized_copy
+                              (first, last, new_start + new_length);
+               new_length += priv_uninitialized_copy
+                              (p, const_iterator(old_start + old_size),
+                              new_start + new_length);
+               this->priv_construct_null(new_start + new_length);
+
+               this->deallocate_block();
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(new_length);
+               this->priv_long_storage(new_cap);
+            }
+            else{
+               //value_type is POD, so backwards expansion is much easier
+               //than with vector<T>
+               value_type * const oldbuf     = boost::movelib::to_raw_pointer(old_start);
+               value_type * const newbuf     = boost::movelib::to_raw_pointer(new_start);
+               const value_type *const pos   = boost::movelib::to_raw_pointer(p);
+               const size_type before  = pos - oldbuf;
+
+               //First move old data
+               Traits::move(newbuf, oldbuf, before);
+               Traits::move(newbuf + before + n, pos, old_size - before);
+               //Now initialize the new data
+               priv_uninitialized_copy(first, last, new_start + before);
+               this->priv_construct_null(new_start + (old_size + n));
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(old_size + n);
+               this->priv_long_storage(new_cap);
+            }
+         }
+      }
+      return this->begin() + n_pos;
+   }
+   #endif
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Effects</b>: As if by insert(p, il.begin(), il.end()).
+   //!
+   //! <b>Returns</b>: An iterator which refers to the copy of the first inserted
+   //!   character, or p if i1 is empty.
+   iterator insert(const_iterator p, std::initializer_list<CharT> il)
+   {
+      return this->insert(p, il.begin(), il.end());
+   }
+   #endif
+
+   //! <b>Effects</b>: Removes the last element from the container.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Constant time.
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      BOOST_ASSERT(!this->empty());
+      iterator p = this->end();
+      this->erase(--p);
+   }
+
+   //! <b>Requires</b>: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
+   //!   The function then replaces the string controlled by *this with a string of length size() - xlen
+   //!   whose first pos elements are a copy of the initial elements of the original string controlled by *this,
+   //!   and whose remaining elements are a copy of the elements of the original string controlled by *this
+   //!   beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& erase(size_type pos = 0, size_type n = npos)
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::erase out of range position");
+      const pointer addr = this->priv_addr();
+      erase(addr + pos, addr + pos + dtl::min_value(n, this->size() - pos));
+      return *this;
+   }
+
+   //! <b>Effects</b>: Removes the character referred to by p.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
+   //!    erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      // The move includes the terminating null.
+      CharT * const ptr = const_cast<CharT*>(boost::movelib::to_raw_pointer(p));
+      const size_type old_size = this->priv_size();
+      Traits::move(ptr,
+                   boost::movelib::to_raw_pointer(p + 1),
+                   old_size - (p - this->priv_addr()));
+      this->priv_size(old_size-1);
+      return iterator(ptr);
+   }
+
+   //! <b>Requires</b>: first and last are valid iterators on *this, defining a range [first,last).
+   //!
+   //! <b>Effects</b>: Removes the characters in the range [first,last).
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
+   //!   the other elements being erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      CharT * f = const_cast<CharT*>(boost::movelib::to_raw_pointer(first));
+      if (first != last) { // The move includes the terminating null.
+         const size_type num_erased = last - first;
+         const size_type old_size = this->priv_size();
+         Traits::move(f,
+                      boost::movelib::to_raw_pointer(last),
+                      (old_size + 1)-(last - this->priv_addr()));
+         const size_type new_length = old_size - num_erased;
+         this->priv_size(new_length);
+      }
+      return iterator(f);
+   }
+
+   //! <b>Effects</b>: Erases all the elements of the vector.
+   //!
+   //! <b>Throws</b>: Nothing.
+   //!
+   //! <b>Complexity</b>: Linear to the number of elements in the vector.
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
+   {
+      if (!this->empty()) {
+         Traits::assign(*this->priv_addr(), CharT(0));
+         this->priv_size(0);
+      }
+   }
+
+   //! <b>Requires</b>: pos1 <= size().
+   //!
+   //! <b>Effects</b>: Calls replace(pos1, n1, str.data(), str.size()).
+   //!
+   //! <b>Throws</b>: if memory allocation throws or out_of_range if pos1 > size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, const basic_string& str)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      if (this->size() - len >= this->max_size() - str.size())
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr = this->priv_addr();
+      return this->replace( const_iterator(addr + pos1)
+                          , const_iterator(addr + pos1 + len)
+                          , str.begin(), str.end());
+   }
+
+   //! <b>Effects</b>: Calls `return replace(pos1, n1, sv.data(), sv.size());`.
+   //!
+   template<template<class, class> class BasicStringView>
+   basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv)
+   {
+      return this->replace(pos1, n1, sv.data(), sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size().
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to be
+   //!   inserted as the smaller of n2 and str.size() - pos2 and calls
+   //!   replace(pos1, n1, str.data() + pos2, rlen).
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1,
+                         const basic_string& str, size_type pos2, size_type n2 = npos)
+   {
+      if (pos2 > str.size())
+         throw_out_of_range("basic_string::replace out of range position");
+      return this->replace(pos1, n1, str.data()+pos2, dtl::min_value(n2, str.size() - pos2));
+   }
+
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size().
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to be inserted as the
+   //!   smaller of n2 and sv.size() - pos2 and calls `replace(pos1, n1, sv.data() + pos2, rlen)`.
+   //!
+   //! <b>Returns</b>: *this.
+   template<template<class, class> class BasicStringView>
+   basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv,
+                         size_type pos2, size_type n2 = npos)
+   {
+      if (pos2 > sv.size())
+         throw_out_of_range("basic_string::replace out of range position");
+      return this->replace(pos1, n1, sv.data()+pos2, dtl::min_value(n2, sv.size() - pos2));
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the
+   //!   smaller of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error.
+   //!   Otherwise, the function replaces the string controlled by *this with a string of
+   //!   length size() - xlen + n2 whose first pos1 elements are a copy of the initial elements
+   //!   of the original string controlled by *this, whose next n2 elements are a copy of the
+   //!   initial n2 elements of s, and whose remaining elements are a copy of the elements of
+   //!   the original string controlled by *this beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      const size_type max_size = this->max_size();
+      if (n2 > max_size || (this->size() - len) >= (max_size - n2))
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr = this->priv_addr() + pos1;
+      return this->replace(addr, addr + len, s, s + n2);
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller
+   //! of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error. Otherwise,
+   //! the function replaces the string controlled by *this with a string of length size() - xlen + n2
+   //! whose first pos1 elements are a copy of the initial elements of the original string controlled
+   //! by *this, whose next n2 elements are a copy of the initial n2 elements of s, and whose
+   //! remaining elements are a copy of the elements of the original string controlled by *this
+   //! beginning at position pos + xlen.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos, size_type n1, const CharT* s)
+   {
+      return this->replace(pos, n1, s, Traits::length(s));
+   }
+
+   //! <b>Requires</b>: pos1 <= size().
+   //!
+   //! <b>Effects</b>: Equivalent to replace(pos1, n1, basic_string(n2, c)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+   //!   if the length of the  resulting string would exceed max_size()
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(size_type pos1, size_type n1, size_type n2, CharT c)
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::replace out of range position");
+      const size_type len = dtl::min_value(n1, this->size() - pos1);
+      if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2)
+         throw_length_error("basic_string::replace max_size() exceeded");
+      const pointer addr    = this->priv_addr();
+      return this->replace(addr + pos1, addr + pos1 + len, n2, c);
+   }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, str).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str)
+   { return this->replace(i1, i2, str.data(), str.data()+str.size()); }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and
+   //!   s points to an array of at least n elements
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, n).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n)
+   { return this->replace(i1, i2, s, s + n); }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and s points to an
+   //!   array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, traits::length(s)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s)
+   {  return this->replace(i1, i2, s, s + Traits::length(s));   }
+
+   //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(n, c)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, size_type n, CharT c)
+   {
+      const size_type len = static_cast<size_type>(i2 - i1);
+      if (len >= n) {
+         Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), n, c);
+         erase(i1 + n, i2);
+      }
+      else {
+         Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), len, c);
+         insert(i2, n - len, c);
+      }
+      return *this;
+   }
+
+   //! <b>Requires</b>: [begin(),i1), [i1,i2) and [j1,j2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(j1, j2)).
+   //!
+   //! <b>Throws</b>: if memory allocation throws
+   //!
+   //! <b>Returns</b>: *this
+   template <class InputIter>
+   basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2
+      #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<InputIter, size_type>
+         , dtl::is_input_iterator<InputIter>
+         >::type * = 0
+      #endif
+      )
+   {
+      for ( ; i1 != i2 && j1 != j2; ++i1, ++j1){
+         Traits::assign(*const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), *j1);
+      }
+
+      if (j1 == j2)
+         this->erase(i1, i2);
+      else
+         this->insert(i2, j1, j2);
+      return *this;
+   }
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   template <class ForwardIter>
+   basic_string& replace(const_iterator i1, const_iterator i2, ForwardIter j1, ForwardIter j2
+      , typename dtl::disable_if_or
+         < void
+         , dtl::is_convertible<ForwardIter, size_type>
+         , dtl::is_not_input_iterator<ForwardIter>
+         >::type * = 0
+      )
+   {
+      difference_type n = boost::container::iterator_distance(j1, j2);
+      const difference_type len = i2 - i1;
+      if (len >= n) {
+         this->priv_copy(j1, j2, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
+         this->erase(i1 + n, i2);
+      }
+      else {
+         ForwardIter m = j1;
+         boost::container::iterator_advance(m, len);
+         this->priv_copy(j1, m, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
+         this->insert(i2, m, j2);
+      }
+      return *this;
+   }
+   #endif
+
+   //! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls `replace(i1 - begin(), i2 - i1, sv).`.
+   //!
+   //! <b>Returns</b>: *this.
+   template<template <class, class> class BasicStringView>
+   basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv)
+   {
+      return this->replace( static_cast<size_type>(i1 - this->cbegin())
+                          , static_cast<size_type>(i2 - i1), sv);
+   }
+
+   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+   //! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
+   //!
+   //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
+   //!
+   //! <b>Returns</b>: *this.
+   basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
+   {
+      return this->replace( static_cast<size_type>(i1 - this->cbegin())
+                          , static_cast<size_type>(i2 - i1)
+                          , il.begin(), il.size());
+   }
+   #endif
+
+   //! <b>Requires</b>: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as the
+   //!   smaller of n and size() - pos. s shall designate an array of at least rlen elements.
+   //!   The function then replaces the string designated by s with a string of length rlen
+   //!   whose elements are a copy of the string controlled by *this beginning at position pos.
+   //!   The function does not append a null object to the string designated by s.
+   //!
+   //! <b>Throws</b>: if memory allocation throws, out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: rlen
+   size_type copy(CharT* s, size_type n, size_type pos = 0) const
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::copy out of range position");
+      const size_type len = dtl::min_value(n, this->size() - pos);
+      Traits::copy(s, boost::movelib::to_raw_pointer(this->priv_addr() + pos), len);
+      return len;
+   }
+
+   //! <b>Effects</b>: *this contains the same sequence of characters that was in s,
+   //!   s contains the same sequence of characters that was in *this.
+   //!
+   //! <b>Throws</b>: Nothing
+   void swap(basic_string& x)
+      BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+                               || allocator_traits_type::is_always_equal::value)
+   {
+      this->base_t::swap_data(x);
+      dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+      dtl::swap_alloc(this->alloc(), x.alloc(), flag);
+   }
+
+   //////////////////////////////////////////////
+   //
+   //                 data access
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+   //!
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+   //!
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   const CharT* data()  const BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! <b>Complexity</b>: constant time.
+   CharT* data()  BOOST_NOEXCEPT_OR_NOTHROW
+   {  return boost::movelib::to_raw_pointer(this->priv_addr()); }
+
+   #ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
+   //! <b>Returns</b>: a string_view to the characters in the string.
+   //!
+   //! <b>Complexity</b>: constant time.
+   template<template <class, class> class BasicStringView>
+   operator BasicStringView<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return this->to_view< BasicStringView<CharT, Traits> >(); }
+   #endif
+
+   //! <b>Returns</b>: a string_view to the characters in the string.
+   //!
+   //! <b>Complexity</b>: constant time.
+   //!
+   //! <b>Note</b>: This function is available to write portable code for compilers
+   //!   that don't support templated conversion operators.
+   template<class BasicStringView>
+   BasicStringView to_view() const BOOST_NOEXCEPT_OR_NOTHROW
+   { return BasicStringView(this->data(), this->size()); }
+
+   //////////////////////////////////////////////
+   //
+   //             string operations
+   //
+   //////////////////////////////////////////////
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
+   //!   of the following conditions hold:
+   //!   1) pos <= xpos and xpos + str.size() <= size();
+   //!   2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find(const basic_string& s, size_type pos = 0) const
+   { return find(s.c_str(), pos, s.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
+   //!   of the following conditions hold:
+   //!   1) pos <= xpos and xpos + sv.size() <= size();
+   //!   2) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+   { return find(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(s,n),pos).
+   size_type find(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos + n > this->size())
+         return npos;
+      else {
+         const pointer addr = this->priv_addr();
+         pointer finish = addr + this->priv_size();
+         const const_iterator result =
+            boost::container::search(boost::movelib::to_raw_pointer(addr + pos),
+                   boost::movelib::to_raw_pointer(finish),
+                   s, s + n, Eq_traits<Traits>());
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string(s), pos).
+   size_type find(const CharT* s, size_type pos = 0) const
+   { return this->find(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
+   size_type find(CharT c, size_type pos = 0) const
+   {
+      const size_type sz = this->size();
+      if (pos >= sz)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         pointer finish = addr + sz;
+         const const_iterator result =
+            boost::container::find_if(addr + pos, finish,
+                  boost::container::bind2nd(Eq_traits<Traits>(), c));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such
+   //!   that both of the following conditions obtain:
+   //!   a) xpos <= pos and xpos + str.size() <= size();
+   //!   b) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type rfind(const basic_string& str, size_type pos = npos) const
+      { return rfind(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such
+   //!   that both of the following conditions obtain:
+   //!   a) xpos <= pos and xpos + sv.size() <= size();
+   //!   b) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type rfind(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return rfind(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string(s, n), pos).
+   size_type rfind(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (n > len)
+         return npos;
+      else if (n == 0)
+         return dtl::min_value(len, pos);
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - n, pos) + n;
+         const const_iterator result = find_end(begin(), last,
+                                                s, s + n,
+                                                Eq_traits<Traits>());
+         return result != last ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: pos <= size() and s points to an array of at least
+   //!   traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string(s), pos).
+   size_type rfind(const CharT* s, size_type pos = npos) const
+      { return rfind(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: rfind(basic_string<CharT,traits,Allocator>(1,c),pos).
+   size_type rfind(CharT c, size_type pos = npos) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                  boost::container::bind2nd(Eq_traits<Traits>(), c));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
+   //!   following conditions obtain: a) pos <= xpos and xpos < size();
+   //!   b) traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_of(const basic_string& str, size_type pos = 0) const
+      { return this->find_first_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
+   //!   following conditions obtain: a) pos <= xpos and xpos < size();
+   //!   b) traits::eq(at(xpos), sv.at(I)) for some element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+      { return this->find_first_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
+   size_type find_first_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type sz = this->size();
+      if (pos >= sz)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         pointer finish = addr + sz;
+         const_iterator result = boost::container::find_first_of
+            (addr + pos, finish, s, s + n, Eq_traits<Traits>());
+         return result != finish ? result - this->begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string(s), pos).
+   size_type find_first_of(const CharT* s, size_type pos = 0) const
+      { return this->find_first_of(s, pos, Traits::length(s)); }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos).
+   size_type find_first_of(CharT c, size_type pos = 0) const
+    { return this->find(c, pos); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
+   //!   the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+   //!   traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_of(const basic_string& str, size_type pos = npos) const
+      { return this->find_last_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
+   //!   the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+   //!   traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return this->find_last_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string(s, n), pos).
+   size_type find_last_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const pointer addr    = this->priv_addr();
+         const const_iterator last = addr + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_first_of(const_reverse_iterator(last), rend(),
+                               s, s + n, Eq_traits<Traits>());
+         return rresult != rend() ? (rresult.base() - 1) - addr : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string<CharT,traits,Allocator>(1,c),pos).
+   size_type find_last_of(const CharT* s, size_type pos = npos) const
+      { return find_last_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_of(basic_string(s), pos).
+   size_type find_last_of(CharT c, size_type pos = npos) const
+      {  return rfind(c, pos);   }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
+   //!   both of the following conditions obtain:
+   //!   a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), str.at(I)) for no
+   //!   element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
+      { return find_first_not_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
+   //!   both of the following conditions obtain:
+   //!   a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), sv.at(I)) for no
+   //!   element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_first_not_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
+      { return find_first_not_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(s, n), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos > this->size())
+         return npos;
+      else {
+         const pointer addr   = this->priv_addr();
+         const pointer finish = addr + this->priv_size();
+         const const_iterator result = boost::container::find_if
+            (addr + pos, finish, Not_within_traits<Traits>(s, s + n));
+         return result != finish ? result - addr : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(s), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos = 0) const
+      { return find_first_not_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_first_not_of(basic_string(1, c), pos).
+   size_type find_first_not_of(CharT c, size_type pos = 0) const
+   {
+      if (pos > this->size())
+         return npos;
+      else {
+         const pointer addr   = this->priv_addr();
+         const pointer finish = addr + this->priv_size();
+         const const_iterator result
+            = boost::container::find_if(addr + pos, finish,
+                     boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that
+   //!   both of the following conditions obtain: a) xpos <= pos and xpos < size();
+   //!   b) traits::eq(at(xpos), str.at(I)) for no element I of the string controlled by str.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
+      { return find_last_not_of(str.c_str(), pos, str.size()); }
+
+   //! <b>Effects</b>: Determines the highest position xpos, if possible, such that
+   //!   both of the following conditions obtain: a) xpos <= pos and xpos < size();
+   //!   b) traits::eq(at(xpos), sv.at(I)) for no element I of the string controlled by sv.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   template<template <class, class> class BasicStringView>
+   size_type find_last_not_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
+      { return find_last_not_of(sv.data(), pos, sv.size()); }
+
+   //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(s, n), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                    Not_within_traits<Traits>(s, s + n));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(s), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos = npos) const
+      { return find_last_not_of(s, pos, Traits::length(s)); }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: find_last_not_of(basic_string(1, c), pos).
+   size_type find_last_not_of(CharT c, size_type pos = npos) const
+   {
+      const size_type len = this->size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            boost::container::find_if(const_reverse_iterator(last), rend(),
+                  boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! <b>Requires</b>: Requires: pos <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of n and size() - pos.
+   //!
+   //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! <b>Returns</b>: basic_string<CharT,traits,Allocator>(data()+pos,rlen).
+   basic_string substr(size_type pos = 0, size_type n = npos) const
+   {
+      if (pos > this->size())
+         throw_out_of_range("basic_string::substr out of range position");
+      const pointer addr = this->priv_addr();
+      return basic_string(addr + pos,
+                          addr + pos + dtl::min_value(n, size() - pos), this->alloc());
+   }
+
+   //! <b>Effects</b>: Determines the effective length rlen of the string to compare as
+   //!   the smaller of size() and str.size(). The function then compares the two strings by
+   //!   calling traits::compare(data(), str.data(), rlen).
+   //!
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: The nonzero result if the result of the comparison is nonzero.
+   //!   Otherwise, returns a value < 0 if size() < str.size(), a 0 value if size() == str.size(),
+   //!   and value > 0 if size() > str.size()
+   int compare(const basic_string& str) const
+   {
+      const pointer addr     = this->priv_addr();
+      const pointer str_addr = str.priv_addr();
+      return s_compare(addr, addr + this->priv_size(), str_addr, str_addr + str.priv_size());
+   }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: compare(basic_string(sv)).
+   template<template <class, class> class BasicStringView>
+   int compare(BasicStringView<CharT,Traits> sv) const
+   {
+      const pointer addr = this->priv_addr();
+      return s_compare(addr, addr + this->priv_size(), sv.data(), sv.data() + sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to compare as
+   //!   the smaller of (this->size() - pos1), n1 and str.size(). The function then compares the two strings by
+   //!   calling traits::compare(data()+pos1, str.data(), rlen).
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(str).
+   int compare(size_type pos1, size_type n1, const basic_string& str) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr    = this->priv_addr();
+      const pointer str_addr = str.priv_addr();
+      return s_compare(addr + pos1,
+                        addr + pos1 + dtl::min_value(n1, this->size() - pos1),
+                        str_addr, str_addr + str.priv_size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size()
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(sv).
+   template<template <class, class> class BasicStringView>
+   int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr    = this->priv_addr() + pos1;
+      const CharT* str_addr = sv.data();
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                       str_addr, str_addr + sv.size());
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
+   int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const
+   {
+      if (pos1 > this->size() || pos2 > str.size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr     = this->priv_addr() + pos1;
+      const pointer str_addr = str.priv_addr() + pos2;
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                        str_addr, str_addr + dtl::min_value(n2, str.size() - pos2));
+   }
+
+   //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(BasicStringView<CharT, Traits>(sv, pos2, n2)).
+   template<template <class, class> class BasicStringView>
+   int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv, size_type pos2, size_type n2) const
+   {
+      if (pos1 > this->size() || pos2 > sv.size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr     = this->priv_addr() + pos1;
+      const CharT * str_addr = sv.data() + pos2;
+      return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1),
+                       str_addr, str_addr + dtl::min_value(n2, sv.size() - pos2));
+   }
+
+   //! <b>Throws</b>: Nothing
+   //!
+   //! <b>Returns</b>: compare(basic_string(s)).
+   int compare(const CharT* s) const
+   {
+      const pointer addr = this->priv_addr();
+      return s_compare(addr, addr + this->priv_size(), s, s + Traits::length(s));
+   }
+
+   //! <b>Requires</b>: pos1 > size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
+   {
+      if (pos1 > this->size())
+         throw_out_of_range("basic_string::compare out of range position");
+      const pointer addr = this->priv_addr();
+      return s_compare( addr + pos1,
+                        addr + pos1 + dtl::min_value(n1, this->size() - pos1),
+                        s, s + n2);
+   }
+
+   //! <b>Requires</b>: pos1 > size() and s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! <b>Throws</b>: out_of_range if pos1 > size()
+   //!
+   //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1, const CharT* s) const
+   {  return this->compare(pos1, n1, s, Traits::length(s)); }
+
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+   private:
+   void priv_reserve(size_type res_arg, const bool null_terminate = true)
+   {
+      if (res_arg > this->max_size()){
+         throw_length_error("basic_string::reserve max_size() exceeded");
+      }
+
+      if (this->capacity() < res_arg){
+         size_type n = dtl::max_value(res_arg, this->size()) + 1;
+         size_type new_cap = this->next_capacity(n);
+         pointer reuse = 0;
+         pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse);
+         size_type new_length = 0;
+
+         const pointer addr = this->priv_addr();
+         new_length += priv_uninitialized_copy
+            (addr, addr + this->priv_size(), new_start);
+         if(null_terminate){
+            this->priv_construct_null(new_start + new_length);
+         }
+         this->deallocate_block();
+         this->is_short(false);
+         this->priv_long_addr(new_start);
+         this->priv_long_size(new_length);
+         this->priv_storage(new_cap);
+      }
+   }
+
+   template<class It1, class It2>
+   static int s_compare(It1 f1, It1 l1, It2 f2, It2 l2)
+   {
+      const difference_type n1 = l1 - f1;
+      const difference_type n2 = l2 - f2;
+      const int cmp = Traits::compare(boost::movelib::to_raw_pointer(f1),
+                                      boost::movelib::to_raw_pointer(f2),
+                                      dtl::min_value(n1, n2));
+      return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
+   }
+
+   template<class AllocVersion>
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion
+      , typename dtl::enable_if<dtl::is_same<AllocVersion, version_1> >::type* = 0)
+   {
+      //Allocate a new buffer.
+      size_type real_cap = 0;
+      const pointer   long_addr    = this->priv_long_addr();
+      const size_type long_size    = this->priv_long_size();
+      const size_type long_storage = this->priv_long_storage();
+      //We can make this nothrow as chars are always NoThrowCopyables
+      BOOST_TRY{
+         pointer reuse = 0;
+         real_cap = long_size+1;
+         const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
+         //Copy and update
+         Traits::copy( boost::movelib::to_raw_pointer(ret)
+                     , boost::movelib::to_raw_pointer(this->priv_long_addr())
+                     , long_size+1);
+         this->priv_long_addr(ret);
+         this->priv_storage(real_cap);
+         //And release old buffer
+         this->alloc().deallocate(long_addr, long_storage);
+      }
+      BOOST_CATCH(...){
+         return;
+      }
+      BOOST_CATCH_END
+   }
+
+   template<class AllocVersion>
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion
+      , typename dtl::enable_if<dtl::is_same<AllocVersion, version_2> >::type* = 0)
+   {
+      size_type received_size = this->priv_long_size()+1;
+      pointer hint = this->priv_long_addr();
+      if(this->alloc().allocation_command
+         ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
+         this->priv_storage(received_size);
+      }
+   }
+
+   void priv_construct_null(pointer p)
+   {  this->construct(p, CharT(0));  }
+
+   // Helper functions used by constructors.  It is a severe error for
+   // any of them to be called anywhere except from within constructors.
+   void priv_terminate_string()
+   {  this->priv_construct_null(this->priv_end_addr());  }
+
+   template<class FwdIt, class Count> inline
+   void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
+   {
+      //Save initial position
+      FwdIt init = first;
+
+      BOOST_TRY{
+         //Construct objects
+         for (; count--; ++first){
+            this->construct(first, val);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; init != first; ++init){
+            this->destroy(init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template<class InpIt, class FwdIt> inline
+   size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
+   {
+      //Save initial destination position
+      FwdIt dest_init = dest;
+      size_type constructed = 0;
+
+      BOOST_TRY{
+         //Try to build objects
+         for (; first != last; ++dest, ++first, ++constructed){
+            this->construct(dest, *first);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; constructed--; ++dest_init){
+            this->destroy(dest_init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+      return (constructed);
+   }
+
+   template <class InputIterator, class OutIterator>
+   void priv_copy(InputIterator first, InputIterator last, OutIterator result)
+   {
+      for ( ; first != last; ++first, ++result)
+         Traits::assign(*result, *first);
+   }
+
+   void priv_copy(const CharT* first, const CharT* last, CharT* result)
+   {  Traits::copy(result, first, last - first);  }
+
+   template <class Integer>
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       Integer n, Integer x,
+                                       dtl::true_)
+   {  return this->replace(first, last, (size_type) n, (CharT) x);   }
+
+   template <class InputIter>
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       InputIter f, InputIter l,
+                                       dtl::false_)
+   {
+      typedef typename boost::container::iterator_traits<InputIter>::iterator_category Category;
+      return this->priv_replace(first, last, f, l, Category());
+   }
+
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+#if __cplusplus >= 201703L
+
+template <typename InputIterator>
+basic_string(InputIterator, InputIterator) ->
+   basic_string<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+basic_string(InputIterator, InputIterator, Allocator const&) ->
+   basic_string<typename iterator_traits<InputIterator>::value_type, Allocator>;
+
+#endif
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   <char
+   ,std::char_traits<char>
+   ,new_allocator<char> >
+string;
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   <wchar_t
+   ,std::char_traits<wchar_t>
+   ,new_allocator<wchar_t> >
+wstring;
+
+#else
+
+template <class CharT, class Traits, class Allocator>
+const typename basic_string<CharT,Traits,Allocator>::size_type
+   basic_string<CharT,Traits,Allocator>::npos;
+
+template<class S>
+struct is_string
+{
+   static const bool value = false;
+};
+
+template<class C, class T, class A>
+struct is_string< basic_string<C, T, A> >
+{
+   static const bool value = true;
+};
+
+#endif
+
+// ------------------------------------------------------------
+// Non-member functions.
+
+// Operator+
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator>
+   operator+(const basic_string<CharT,Traits,Allocator>& x
+            ,const basic_string<CharT,Traits,Allocator>& y)
+{
+   typedef basic_string<CharT,Traits,Allocator> str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
+   result.append(x);
+   result.append(y);
+   return result;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
+      , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
+{
+   x += y;
+   return boost::move(x);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
+      , const basic_string<CharT,Traits,Allocator>& y)
+{
+   x += y;
+   return boost::move(x);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      (const basic_string<CharT,Traits,Allocator>& x
+      ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
+{
+   y.insert(y.begin(), x.begin(), x.end());
+   return boost::move(y);
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT, Traits, Allocator> operator+
+      (const CharT* s, basic_string<CharT, Traits, Allocator> y)
+{
+   y.insert(y.begin(), s, s + Traits::length(s));
+   return y;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (basic_string<CharT,Traits,Allocator> x, const CharT* s)
+{
+   x += s;
+   return x;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (CharT c, basic_string<CharT,Traits,Allocator> y)
+{
+   y.insert(y.begin(), c);
+   return y;
+}
+
+template <class CharT, class Traits, class Allocator> inline
+   basic_string<CharT,Traits,Allocator> operator+
+      (basic_string<CharT,Traits,Allocator> x, const CharT c)
+{
+   x += c;
+   return x;
+}
+
+// Operator== and operator!=
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
+   return n == y.size() && Traits::compare(s, y.data(), n) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
+   return x.size() == n && Traits::compare(x.data(), s, n) == 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline 
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+      operator==( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+      operator==( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x == y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(s == y); }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(x == s);   }
+
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator!=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x == y);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator!=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(x == y);  }
+
+// Operator< (and also >, <=, and >=).
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return x.compare(y) < 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+{
+   return y.compare(s) > 0;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   return x.compare(s) < 0;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return y.compare(x) > 0;  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<(  const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return x.compare(y) < 0;  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y) {
+   return y < x;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const CharT* s, const basic_string<CharT,Traits,Allocator>& y) {
+   return y < s;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+{
+   return s < x;
+}
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return y < x;  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return y < x;  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
+{
+  return !(y < x);
+}
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(y < s);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(s < x);  }
+
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(y < x);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator<=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(y < x);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const basic_string<CharT,Traits,Allocator>& x,
+           const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x < y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(s < y);  }
+
+template <class CharT, class Traits, class Allocator>
+inline bool
+operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
+   {  return !(x < s);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
+   {  return !(x < y);  }
+
+template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
+inline
+   BOOST_CONTAINER_DOC1ST( bool, 
+                           typename dtl::disable_if
+                              <is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
+operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
+   {  return !(x < y);  }
+
+// Swap.
+template <class CharT, class Traits, class Allocator>
+inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
+{  x.swap(y);  }
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+// I/O.
+namespace dtl {
+
+template <class CharT, class Traits>
+inline bool
+string_fill(std::basic_ostream<CharT, Traits>& os,
+                  std::basic_streambuf<CharT, Traits>* buf,
+                  std::size_t n)
+{
+   CharT f = os.fill();
+   std::size_t i;
+   bool ok = true;
+
+   for (i = 0; i < n; i++)
+      ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
+   return ok;
+}
+
+}  //namespace dtl {
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class CharT, class Traits, class Allocator>
+std::basic_ostream<CharT, Traits>&
+operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s)
+{
+   typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
+   bool ok = false;
+
+   if (sentry) {
+      ok = true;
+      typename basic_string<CharT,Traits,Allocator>::size_type n = s.size();
+      typename basic_string<CharT,Traits,Allocator>::size_type pad_len = 0;
+      const bool left = (os.flags() & std::ios::left) != 0;
+      const std::size_t w = os.width(0);
+      std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
+
+      if (w != 0 && n < w)
+         pad_len = w - n;
+
+      if (!left)
+         ok = dtl::string_fill(os, buf, pad_len);
+
+      ok = ok &&
+            buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
+
+      if (left)
+         ok = ok && dtl::string_fill(os, buf, pad_len);
+   }
+
+   if (!ok)
+      os.setstate(std::ios_base::failbit);
+
+   return os;
+}
+
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>&
+operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
+{
+   typename std::basic_istream<CharT, Traits>::sentry sentry(is);
+
+   if (sentry) {
+      std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+      const std::ctype<CharT>& ctype = std::use_facet<std::ctype<CharT> >(is.getloc());
+
+      s.clear();
+      std::size_t n = is.width(0);
+      if (n == 0)
+         n = static_cast<std::size_t>(-1);
+      else
+         s.reserve(n);
+
+      while (n-- > 0) {
+         typename Traits::int_type c1 = buf->sbumpc();
+
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            CharT c = Traits::to_char_type(c1);
+
+            if (ctype.is(std::ctype<CharT>::space, c)) {
+               if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
+                  is.setstate(std::ios_base::failbit);
+               break;
+            }
+            else
+               s.push_back(c);
+         }
+      }
+
+      // If we have read no characters, then set failbit.
+      if (s.size() == 0)
+         is.setstate(std::ios_base::failbit);
+   }
+   else
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>&
+getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
+{
+   typename basic_string<CharT,Traits,Allocator>::size_type nread = 0;
+   typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
+   if (sentry) {
+      std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+      s.clear();
+
+      while (nread < s.max_size()) {
+         int c1 = buf->sbumpc();
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            ++nread;
+            CharT c = Traits::to_char_type(c1);
+            if (!Traits::eq(c, delim))
+               s.push_back(c);
+            else
+               break;              // Character is extracted but not appended.
+         }
+      }
+   }
+   if (nread == 0 || nread >= s.max_size())
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template <class CharT, class Traits, class Allocator>
+inline std::basic_istream<CharT, Traits>&
+getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
+{
+   return getline(is, s, '\n');
+}
+
+template <class Ch, class Allocator>
+inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator> const& v)
+{
+   return hash_range(v.begin(), v.end());
+}
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class C, class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
+{
+   typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+   static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+                             ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_STRING_HPP
