diff DEPENDENCIES/generic/include/boost/container/string.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/container/string.hpp	Fri Sep 04 12:01:02 2015 +0100
+++ b/DEPENDENCIES/generic/include/boost/container/string.hpp	Mon Sep 07 11:12:49 2015 +0100
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -11,32 +11,44 @@
 #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/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
 
-#include <boost/container/detail/workaround.hpp>
-#include <boost/container/container_fwd.hpp>
-#include <boost/container/throw_exception.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/allocation_type.hpp>
-#include <boost/container/allocator_traits.hpp>
-#include <boost/container/detail/allocator_version_traits.hpp>
-#include <boost/container/detail/mpl.hpp>
-#include <boost/move/utility.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/container/detail/minimal_char_traits_header.hpp>
 #include <boost/functional/hash.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
 
-#include <functional>
-#include <string>
-#include <utility>
-#include <iterator>
-#include <memory>
+
 #include <algorithm>
+#include <functional>   //bind2nd, etc.
 #include <iosfwd>
 #include <istream>
 #include <ostream>
@@ -45,17 +57,15 @@
 #include <cstddef>
 #include <climits>
 #include <boost/container/detail/type_traits.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/aligned_storage.hpp>
+#include <boost/move/traits.hpp>
 
 namespace boost {
 namespace container {
 
-/// @cond
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace container_detail {
 // ------------------------------------------------------------
-// Class basic_string_base. 
+// 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,
@@ -67,11 +77,12 @@
 template <class Allocator>
 class basic_string_base
 {
-   BOOST_MOVABLE_BUT_NOT_COPYABLE(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                                   allocator_type;
    typedef allocator_type                              stored_allocator_type;
    typedef typename allocator_traits_type::pointer     pointer;
    typedef typename allocator_traits_type::value_type  value_type;
@@ -86,22 +97,19 @@
       : members_(a)
    {  init(); }
 
+   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);
    }
 
-   basic_string_base(BOOST_RV_REF(basic_string_base) b)
-      :  members_(boost::move(b.alloc()))
-   { 
-      this->init();
-      this->swap_data(b);
-   }
-
    ~basic_string_base()
-   { 
+   {
       if(!this->is_short()){
          this->deallocate_block();
          this->is_short(true);
@@ -149,9 +157,9 @@
 
    //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 boost::aligned_storage< sizeof(long_t),
-       container_detail::alignment_of<long_t>::value>::type   long_raw_t;
+
+   typedef typename container_detail::aligned_storage
+      <sizeof(long_t), container_detail::alignment_of<long_t>::value>::type   long_raw_t;
 
    protected:
    static const size_type  MinInternalBufferChars = 8;
@@ -248,30 +256,32 @@
 
    protected:
 
-   typedef container_detail::integral_constant<unsigned, 1>      allocator_v1;
-   typedef container_detail::integral_constant<unsigned, 2>      allocator_v2;
    typedef container_detail::integral_constant<unsigned,
       boost::container::container_detail::version<Allocator>::value> alloc_version;
 
-   std::pair<pointer, bool>
-      allocation_command(allocation_type command,
+   pointer allocation_command(allocation_type command,
                          size_type limit_size,
-                         size_type preferred_size,
-                         size_type &received_size, pointer reuse = 0)
+                         size_type &prefer_in_recvd_out_size,
+                         pointer &reuse)
    {
       if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
-         reuse = pointer();
+         reuse = 0;
          command &= ~(expand_fwd | expand_bwd);
       }
       return container_detail::allocator_version_traits<Allocator>::allocation_command
-         (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
+         (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
    }
 
    size_type next_capacity(size_type additional_objects) const
-   {  return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects);  }
+   {
+      return next_capacity_calculator
+         <size_type, NextCapacityDouble /*NextCapacity60Percent*/>::
+            get( allocator_traits_type::max_size(this->alloc())
+               , this->priv_storage(), additional_objects );
+   }
 
    void deallocate(pointer p, size_type n)
-   { 
+   {
       if (p && (n > InternalBufferChars))
          this->alloc().deallocate(p, n);
    }
@@ -306,7 +316,8 @@
       if (n <= this->max_size()) {
          if(n > InternalBufferChars){
             size_type new_cap = this->next_capacity(n);
-            pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
+            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);
@@ -320,7 +331,7 @@
 
    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; }
 
@@ -363,13 +374,13 @@
    {  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;
    }
 
@@ -383,7 +394,7 @@
    {  return this->members_.m_repr.long_repr().length;  }
 
    void priv_size(size_type sz)
-   { 
+   {
       if(this->is_short())
          this->priv_short_size(sz);
       else
@@ -391,12 +402,12 @@
    }
 
    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;
    }
 
@@ -404,7 +415,9 @@
    {
       if(this->is_short()){
          if(other.is_short()){
-            std::swap(this->members_.m_repr, other.members_.m_repr);
+            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());
@@ -425,7 +438,7 @@
             this->members_.m_repr.short_repr() = short_backup;
          }
          else{
-            boost::container::swap_dispatch(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+            boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
          }
       }
    }
@@ -433,7 +446,7 @@
 
 }  //namespace container_detail {
 
-/// @endcond
+#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
@@ -463,15 +476,19 @@
 //! 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 = std::allocator<CharT> >
+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 container_detail::basic_string_base<Allocator>
 {
-   /// @cond
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
    private:
    typedef allocator_traits<Allocator> allocator_traits_type;
    BOOST_COPYABLE_AND_MOVABLE(basic_string)
@@ -483,19 +500,22 @@
 
    template <class Tr>
    struct Eq_traits
-      : public std::binary_function<typename Tr::char_type,
-                                    typename Tr::char_type,
-                                    bool>
    {
-      bool operator()(const typename Tr::char_type& x,
-                      const typename Tr::char_type& y) const
+      //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
-      : public std::unary_function<typename Tr::char_type, bool>
    {
+      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;
@@ -509,7 +529,7 @@
                         std::bind1st(Eq_traits<Tr>(), x)) == m_last;
       }
    };
-   /// @endcond
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
    public:
    //////////////////////////////////////////////
@@ -529,18 +549,16 @@
    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(std::reverse_iterator<iterator>)                     reverse_iterator;
-   typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>)               const_reverse_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);
 
-   /// @cond
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
    private:
    typedef constant_iterator<CharT, difference_type> cvalue_iterator;
-   typedef typename base_t::allocator_v1  allocator_v1;
-   typedef typename base_t::allocator_v2  allocator_v2;
    typedef typename base_t::alloc_version  alloc_version;
    typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
-   /// @endcond
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
    public:                         // Constructor, destructor, assignment.
    //////////////////////////////////////////////
@@ -548,7 +566,7 @@
    //          construct/copy/destroy
    //
    //////////////////////////////////////////////
-   /// @cond
+   #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
    struct reserve_t {};
 
    basic_string(reserve_t, size_type n,
@@ -559,7 +577,7 @@
               , n + 1)
    { this->priv_terminate_string(); }
 
-   /// @endcond
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
    //! <b>Effects</b>: Default constructs a basic_string.
    //!
@@ -572,7 +590,7 @@
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
    //!
    //! <b>Throws</b>: Nothing
-   explicit basic_string(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
+   explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
       : base_t(a)
    { this->priv_terminate_string(); }
 
@@ -580,7 +598,7 @@
    //!
    //! <b>Postcondition</b>: x == *this.
    //!
-   //! <b>Throws</b>: If allocator_type's default constructor throws.
+   //! <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()))
    {
@@ -593,9 +611,16 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   basic_string(BOOST_RV_REF(basic_string) s) BOOST_CONTAINER_NOEXCEPT
-      : base_t(boost::move((base_t&)s))
-   {}
+   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.
    //!
@@ -669,6 +694,15 @@
    }
 
    //! <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 = allocator_type())
+      : base_t(a, n + 1)
+   {
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   //! <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 = allocator_type())
@@ -683,9 +717,9 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   ~basic_string() BOOST_CONTAINER_NOEXCEPT
+   ~basic_string() BOOST_NOEXCEPT_OR_NOTHROW
    {}
-     
+
    //! <b>Effects</b>: Copy constructs a string.
    //!
    //! <b>Postcondition</b>: x == *this.
@@ -712,30 +746,39 @@
       return *this;
    }
 
-   //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+   //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
    //!
-   //! <b>Throws</b>: If allocator_type's copy constructor throws.
+   //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
+   //!   is false and allocation throws
    //!
-   //! <b>Complexity</b>: Constant.
-   basic_string& operator=(BOOST_RV_REF(basic_string) x) BOOST_CONTAINER_NOEXCEPT
+   //! <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)
    {
-      if (&x != this){
-         allocator_type &this_alloc = this->alloc();
-         allocator_type &x_alloc    = x.alloc();
-         //If allocators are equal we can just swap pointers
-         if(this_alloc == x_alloc){
-            //Destroy objects but retain memory in case x reuses it in the future
-            this->clear();
-            this->swap_data(x);
-            //Move allocator if needed
-            container_detail::bool_<allocator_traits_type::
-               propagate_on_container_move_assignment::value> flag;
-            container_detail::move_alloc(this_alloc, x_alloc, flag);
-         }
-         //If unequal allocators, then do a one by one move
-         else{
-            this->assign( x.begin(), x.end());
-         }
+      //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;
+      container_detail::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
+         container_detail::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;
    }
@@ -753,7 +796,7 @@
    //! <b>Throws</b>: If allocator's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
-   allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+   allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
    { return this->alloc(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -763,7 +806,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
-   stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+   stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
    {  return this->alloc(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -773,7 +816,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
-   const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+   const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
    {  return this->alloc(); }
 
    //////////////////////////////////////////////
@@ -787,7 +830,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   iterator begin() BOOST_CONTAINER_NOEXCEPT
+   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.
@@ -795,7 +838,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+   const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
    { return this->priv_addr(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the vector.
@@ -803,7 +846,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   iterator end() BOOST_CONTAINER_NOEXCEPT
+   iterator end() BOOST_NOEXCEPT_OR_NOTHROW
    { return this->priv_end_addr(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -811,7 +854,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+   const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
    { return this->priv_end_addr(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -820,7 +863,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   reverse_iterator rbegin()  BOOST_CONTAINER_NOEXCEPT
+   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
@@ -829,7 +872,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+   const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
    { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -838,7 +881,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   reverse_iterator rend()  BOOST_CONTAINER_NOEXCEPT
+   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
@@ -847,7 +890,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+   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.
@@ -855,7 +898,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+   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.
@@ -863,7 +906,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+   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
@@ -872,7 +915,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+   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
@@ -881,7 +924,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+   const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
    { return const_reverse_iterator(this->priv_addr()); }
 
    //////////////////////////////////////////////
@@ -895,7 +938,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   bool empty() const BOOST_CONTAINER_NOEXCEPT
+   bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
    { return !this->priv_size(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -903,7 +946,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   size_type size() const    BOOST_CONTAINER_NOEXCEPT
+   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.
@@ -911,7 +954,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   size_type length() const BOOST_CONTAINER_NOEXCEPT
+   size_type length() const BOOST_NOEXCEPT_OR_NOTHROW
    { return this->size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the vector.
@@ -919,7 +962,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+   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
@@ -945,13 +988,33 @@
    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_CONTAINER_NOEXCEPT
+   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
@@ -961,29 +1024,7 @@
    //!
    //! <b>Throws</b>: If memory allocation allocation throws
    void reserve(size_type res_arg)
-   {
-      if (res_arg > this->max_size()){
-         throw_length_error("basic_string::reserve max_size() exceeded");
-      }
-
-      if (this->capacity() < res_arg){
-         size_type n = container_detail::max_value(res_arg, this->size()) + 1;
-         size_type new_cap = this->next_capacity(n);
-         pointer new_start = this->allocation_command
-            (allocate_new, n, new_cap, new_cap).first;
-         size_type new_length = 0;
-
-         const pointer addr = this->priv_addr();
-         new_length += priv_uninitialized_copy
-            (addr, addr + this->priv_size(), new_start);
-         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);
-      }
-   }
+   {  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
@@ -1030,7 +1071,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
+   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
       { return *(this->priv_addr() + n); }
 
    //! <b>Requires</b>: size() > n.
@@ -1041,7 +1082,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
-   const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+   const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
       { return *(this->priv_addr() + n); }
 
    //! <b>Requires</b>: size() > n.
@@ -1184,7 +1225,7 @@
    //! <b>Throws</b>: Nothing
    //!
    //! <b>Returns</b>: *this
-   basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_CONTAINER_NOEXCEPT
+   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()
@@ -1209,7 +1250,7 @@
    //! 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);   }
@@ -1229,6 +1270,20 @@
    {  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 = container_detail::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>
@@ -1394,7 +1449,7 @@
       for ( ; first != last; ++first, ++p) {
          p = this->insert(p, *first);
       }
-      return this->begin() + n_pos; 
+      return this->begin() + n_pos;
    }
 
    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1408,27 +1463,28 @@
    {
       const size_type n_pos = p - this->cbegin();
       if (first != last) {
-         const size_type n = std::distance(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;
-         std::pair<pointer, bool> allocation_ret;
          size_type new_cap = 0;
 
          //Check if we have enough capacity
+         pointer hint = pointer();
+         pointer allocation_ret = pointer();
          if (remaining >= n){
-            enough_capacity = true;           
+            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, new_cap, old_start);
+                  (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
 
             //Check forward expansion
-            if(old_start == allocation_ret.first){
+            if(old_start == allocation_ret){
                enough_capacity = true;
                this->priv_storage(new_cap);
             }
@@ -1451,7 +1507,7 @@
             }
             else {
                ForwardIter mid = first;
-               std::advance(mid, elems_after + 1);
+               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);
@@ -1464,8 +1520,8 @@
             }
          }
          else{
-            pointer new_start = allocation_ret.first;
-            if(!allocation_ret.second){
+            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
@@ -1527,7 +1583,7 @@
       const pointer addr = this->priv_addr();
       erase(addr + pos, addr + pos + container_detail::min_value(n, this->size() - pos));
       return *this;
-   } 
+   }
 
    //! <b>Effects</b>: Removes the character referred to by p.
    //!
@@ -1535,7 +1591,7 @@
    //!
    //! <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_CONTAINER_NOEXCEPT
+   iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
    {
       // The move includes the terminating null.
       CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
@@ -1555,7 +1611,7 @@
    //!
    //! <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_CONTAINER_NOEXCEPT
+   iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
    {
       CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
       if (first != last) { // The move includes the terminating null.
@@ -1575,7 +1631,7 @@
    //! <b>Throws</b>: Nothing
    //!
    //! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
-   void pop_back() BOOST_CONTAINER_NOEXCEPT
+   void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
    {
       const size_type old_size = this->priv_size();
       Traits::assign(this->priv_addr()[old_size-1], CharT(0));
@@ -1587,7 +1643,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in the vector.
-   void clear() BOOST_CONTAINER_NOEXCEPT
+   void clear() BOOST_NOEXCEPT_OR_NOTHROW
    {
       if (!this->empty()) {
          Traits::assign(*this->priv_addr(), CharT(0));
@@ -1800,7 +1856,7 @@
          >::type * = 0
       )
    {
-      difference_type n = std::distance(j1, j2);
+      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*>(container_detail::to_raw_pointer(i1)));
@@ -1808,7 +1864,7 @@
       }
       else {
          ForwardIter m = j1;
-         std::advance(m, len);
+         boost::container::iterator_advance(m, len);
          this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
          this->insert(i2, m, j2);
       }
@@ -1841,6 +1897,8 @@
    //!
    //! <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);
       container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
@@ -1855,18 +1913,18 @@
 
    //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
    //!
-   //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //! <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_CONTAINER_NOEXCEPT
+   const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
    {  return container_detail::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>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //! <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_CONTAINER_NOEXCEPT
+   const CharT* data()  const BOOST_NOEXCEPT_OR_NOTHROW
    {  return container_detail::to_raw_pointer(this->priv_addr()); }
 
    //////////////////////////////////////////////
@@ -2296,8 +2354,35 @@
    int compare(size_type pos1, size_type n1, const CharT* s) const
    {  return this->compare(pos1, n1, s, Traits::length(s)); }
 
-   /// @cond
+   #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 = container_detail::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);
+      }
+   }
+
    static int s_compare(const_pointer f1, const_pointer l1,
                         const_pointer f2, const_pointer l2)
    {
@@ -2312,7 +2397,7 @@
    template<class AllocVersion>
    void priv_shrink_to_fit_dynamic_buffer
       ( AllocVersion
-      , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v1> >::type* = 0)
+      , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_1> >::type* = 0)
    {
       //Allocate a new buffer.
       size_type real_cap = 0;
@@ -2321,13 +2406,14 @@
       const size_type long_storage = this->priv_long_storage();
       //We can make this nothrow as chars are always NoThrowCopyables
       BOOST_TRY{
-         const std::pair<pointer, bool> ret = this->allocation_command
-               (allocate_new, long_size+1, long_size+1, real_cap, long_addr);
+         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( container_detail::to_raw_pointer(ret.first)
+         Traits::copy( container_detail::to_raw_pointer(ret)
                      , container_detail::to_raw_pointer(this->priv_long_addr())
                      , long_size+1);
-         this->priv_long_addr(ret.first);
+         this->priv_long_addr(ret);
          this->priv_storage(real_cap);
          //And release old buffer
          this->alloc().deallocate(long_addr, long_storage);
@@ -2341,13 +2427,12 @@
    template<class AllocVersion>
    void priv_shrink_to_fit_dynamic_buffer
       ( AllocVersion
-      , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v2> >::type* = 0)
+      , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_2> >::type* = 0)
    {
-      size_type received_size;
+      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(), this->priv_long_size()+1
-         , received_size, this->priv_long_addr()).first){
+         ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
          this->priv_storage(received_size);
       }
    }
@@ -2427,19 +2512,21 @@
                                        InputIter f, InputIter l,
                                        container_detail::false_)
    {
-      typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+      typedef typename boost::container::iterator_traits<InputIter>::iterator_category Category;
       return this->priv_replace(first, last, f, l, Category());
    }
 
-   /// @endcond
+   #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 };
 
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+
 //!Typedef for a basic_string of
 //!narrow characters
 typedef basic_string
    <char
    ,std::char_traits<char>
-   ,std::allocator<char> >
+   ,new_allocator<char> >
 string;
 
 //!Typedef for a basic_string of
@@ -2447,15 +2534,17 @@
 typedef basic_string
    <wchar_t
    ,std::char_traits<wchar_t>
-   ,std::allocator<wchar_t> >
+   ,new_allocator<wchar_t> >
 wstring;
 
+#endif
+
 // ------------------------------------------------------------
 // Non-member functions.
 
 // Operator+
 
-template <class CharT, class Traits, class Allocator> inline 
+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)
@@ -2471,29 +2560,29 @@
 
 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 mx
-      , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my)
+      ( 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)
 {
-   mx += my;
-   return boost::move(mx);
+   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 mx
+      ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
       , const basic_string<CharT,Traits,Allocator>& y)
 {
-   mx += y;
-   return boost::move(mx);
+   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 my)
+      ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
 {
-   my.insert(my.begin(), x.begin(), x.end());
-   return boost::move(my);
+   y.insert(y.begin(), x.begin(), x.end());
+   return boost::move(y);
 }
 
 template <class CharT, class Traits, class Allocator> inline
@@ -2504,7 +2593,7 @@
    return y;
 }
 
-template <class CharT, class Traits, class Allocator> inline 
+template <class CharT, class Traits, class Allocator> inline
    basic_string<CharT,Traits,Allocator> operator+
       (basic_string<CharT,Traits,Allocator> x, const CharT* s)
 {
@@ -2520,7 +2609,7 @@
    return y;
 }
 
-template <class CharT, class Traits, class Allocator> inline 
+template <class CharT, class Traits, class Allocator> inline
    basic_string<CharT,Traits,Allocator> operator+
       (basic_string<CharT,Traits,Allocator> x, const CharT c)
 {
@@ -2663,8 +2752,8 @@
 inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
 {  x.swap(y);  }
 
-/// @cond
-// I/O. 
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+// I/O.
 namespace container_detail {
 
 template <class CharT, class Traits>
@@ -2683,7 +2772,7 @@
 }
 
 }  //namespace container_detail {
-/// @endcond
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
 template <class CharT, class Traits, class Allocator>
 std::basic_ostream<CharT, Traits>&
@@ -2702,9 +2791,9 @@
 
       if (w != 0 && n < w)
          pad_len = w - n;
-      
+
       if (!left)
-         ok = container_detail::string_fill(os, buf, pad_len);   
+         ok = container_detail::string_fill(os, buf, pad_len);
 
       ok = ok &&
             buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
@@ -2756,7 +2845,7 @@
                s.push_back(c);
          }
       }
-     
+
       // If we have read no characters, then set failbit.
       if (s.size() == 0)
          is.setstate(std::ios_base::failbit);
@@ -2767,7 +2856,7 @@
    return is;
 }
 
-template <class CharT, class Traits, class Allocator>   
+template <class CharT, class Traits, class Allocator>
 std::basic_istream<CharT, Traits>&
 getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
 {
@@ -2799,7 +2888,7 @@
    return is;
 }
 
-template <class CharT, class Traits, class Allocator>   
+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)
 {
@@ -2814,7 +2903,7 @@
 
 }}
 
-/// @cond
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
 namespace boost {
 
@@ -2822,12 +2911,15 @@
 //!specialization for optimizations
 template <class C, class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
-   : public ::boost::has_trivial_destructor_after_move<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;
+};
 
 }
 
-/// @endcond
+#endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
 
 #include <boost/container/detail/config_end.hpp>