/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
    http://www.boost.org/

    Copyright (c) 2001 by Andrei Alexandrescu. Distributed under the Boost
    Software License, Version 1.0. (See accompanying file
    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// This code is taken from: 
// Andrei Alexandrescu, Generic<Programming>: A Policy-Based basic_string 
// Implementation. http://www.cuj.com/documents/s=7994/cujcexp1906alexandr/
//
// #HK030306: 
//      - Moved into the namespace boost::wave::util 
//      - Added a bunch of missing typename(s) 
//      - Integrated with boost config
//      - Added a missing header include
//      - Added special constructors and operator= to allow CowString to be 
//        a real COW-string (removed unnecessary data copying)
//      - Fixed a string terminating bug in append
//
// #HK040109:
//      - Incorporated the changes from Andrei's latest version of this class
//
// #HK070307:
//      - Once again incorporated the changes from Andrei's latest version of 
//        this class
//
// #HK090523:
//      - Incorporated the changes from latest version of flex_string as 
//        maintained in Loki

#ifndef FLEX_STRING_INC_
#define FLEX_STRING_INC_

/*
////////////////////////////////////////////////////////////////////////////////
template <typename E, class A = @>
class StoragePolicy
{
    typedef E value_type;
    typedef @ iterator;
    typedef @ const_iterator;
    typedef A allocator_type;
    typedef @ size_type;
    
    StoragePolicy(const StoragePolicy& s);
    StoragePolicy(const A&);
    StoragePolicy(const E* s, size_type len, const A&);
    StoragePolicy(size_type len, E c, const A&);
    ~StoragePolicy();

    iterator begin();
    const_iterator begin() const;
    iterator end();
    const_iterator end() const;
    
    size_type size() const;
    size_type max_size() const;
    size_type capacity() const;

    void reserve(size_type res_arg);

    void append(const E* s, size_type sz);
    
    template <class InputIterator>
    void append(InputIterator b, InputIterator e);

    void resize(size_type newSize, E fill);

    void swap(StoragePolicy& rhs);
    
    const E* c_str() const;
    const E* data() const;
    
    A get_allocator() const;
};
////////////////////////////////////////////////////////////////////////////////
*/

#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>

#include <boost/iterator/reverse_iterator.hpp>

#include <boost/wave/wave_config.hpp>
#if BOOST_WAVE_SERIALIZATION != 0
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/collections_save_imp.hpp>
#include <boost/serialization/collections_load_imp.hpp>
#define BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK 1
#endif

#include <memory>
#include <new>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <limits>
#include <stdexcept>
#include <iosfwd>
#include <cstddef>
#include <cstring>
#include <cstdlib>

// this must occur after all of the includes and before any code appears
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {

namespace flex_string_details
{
    template <class InIt, class OutIt>
    OutIt copy_n(InIt b, 
        typename std::iterator_traits<InIt>::difference_type n, OutIt d)
    {
        for (/**/; n != 0; --n, ++b, ++d)
        {
            *d = *b;
        }
        return d;
    }

    template <class Pod, class T>
    inline void pod_fill(Pod* b, Pod* e, T c)
    {
        switch ((e - b) & 7)
        {
        case 0:
            while (b != e)
            {
                *b = c; ++b;
        case 7: *b = c; ++b;
        case 6: *b = c; ++b;
        case 5: *b = c; ++b;
        case 4: *b = c; ++b;
        case 3: *b = c; ++b;
        case 2: *b = c; ++b;
        case 1: *b = c; ++b;
            }
        }
    }

    template <class Pod>
    inline void pod_move(const Pod* b, const Pod* e, Pod* d)
    {
        using namespace std;
        memmove(d, b, (e - b) * sizeof(*b));
    }

    template <class Pod>
    inline Pod* pod_copy(const Pod* b, const Pod* e, Pod* d)
    {
        const std::size_t s = e - b;
        using namespace std;
        memcpy(d, b, s * sizeof(*b));
        return d + s;
    }

    template <typename T> struct get_unsigned
    {
        typedef T result;
    };

    template <> struct get_unsigned<char>
    {
        typedef unsigned char result;
    };

    template <> struct get_unsigned<signed char>
    {
        typedef unsigned char result;
    };

    template <> struct get_unsigned<short int>
    {
        typedef unsigned short int result;
    };

    template <> struct get_unsigned<int>
    {
        typedef unsigned int result;
    };

    template <> struct get_unsigned<long int>
    {
        typedef unsigned long int result;
    };

    enum Shallow {};
}

template <class T> class mallocator
{
public:
    typedef T                 value_type;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
    typedef value_type&       reference;
    typedef const value_type& const_reference;
    typedef std::size_t       size_type;
    //typedef unsigned int      size_type;
    //typedef std::ptrdiff_t    difference_type;
    typedef int               difference_type;

    template <class U> 
    struct rebind { typedef mallocator<U> other; };

    mallocator() {}
    mallocator(const mallocator&) {}
    //template <class U> 
    //mallocator(const mallocator<U>&) {}
    ~mallocator() {}

    pointer address(reference x) const { return &x; }
    const_pointer address(const_reference x) const 
    { 
        return x;
    }

    pointer allocate(size_type n, const_pointer = 0) 
    {
        using namespace std;
        void* p = malloc(n * sizeof(T));
        if (!p) boost::throw_exception(std::bad_alloc());
        return static_cast<pointer>(p);
    }

    void deallocate(pointer p, size_type) 
    { 
        using namespace std;
        free(p); 
    }

    size_type max_size() const 
    { 
        return static_cast<size_type>(-1) / sizeof(T);
    }

    void construct(pointer p, const value_type& x) 
    { 
        new(p) value_type(x); 
    }

    void destroy(pointer p) 
    { 
        p->~value_type(); 
    }

private:
    void operator=(const mallocator&);
};

template<> class mallocator<void>
{
  typedef void        value_type;
  typedef void*       pointer;
  typedef const void* const_pointer;

  template <class U> 
  struct rebind { typedef mallocator<U> other; };
};

template <class T>
inline bool operator==(const mallocator<T>&, 
                       const mallocator<T>&) {
  return true;
}

template <class T>
inline bool operator!=(const mallocator<T>&, 
                       const mallocator<T>&) {
  return false;
}

template <class Allocator>
typename Allocator::pointer Reallocate(
    Allocator& alloc,
    typename Allocator::pointer p, 
    typename Allocator::size_type oldObjCount,
    typename Allocator::size_type newObjCount,
    void*)
{
    // @@@ not implemented
    return NULL;
}

template <class Allocator>
typename Allocator::pointer Reallocate(
    Allocator& alloc,
    typename Allocator::pointer p, 
    typename Allocator::size_type oldObjCount,
    typename Allocator::size_type newObjCount,
    mallocator<void>*)
{
    // @@@ not implemented
    return NULL;
}

////////////////////////////////////////////////////////////////////////////////
// class template SimpleStringStorage
// Allocates memory with malloc
////////////////////////////////////////////////////////////////////////////////

template <typename E, class A = std::allocator<E> >
class SimpleStringStorage
{
    // The "public" below exists because MSVC can't do template typedefs
public:
    struct Data
    {
        Data() : pEnd_(buffer_), pEndOfMem_(buffer_) { buffer_[0] = E(0); }

        E* pEnd_;
        E* pEndOfMem_;
        E buffer_[1];
    };
    static const Data emptyString_;

    typedef typename A::size_type size_type;

private:
    Data* pData_;

    void Init(size_type size, size_type capacity)
    {
        BOOST_ASSERT(size <= capacity);
        if (capacity == 0) 
        {
            pData_ = const_cast<Data*>(&emptyString_);
        }
        else
        {
            // 11-17-2000: comment added: 
            //     No need to allocate (capacity + 1) to 
            //     accommodate the terminating 0, because Data already
            //     has one one character in there
            pData_ = static_cast<Data*>(
                malloc(sizeof(Data) + capacity * sizeof(E)));
            if (!pData_) boost::throw_exception(std::bad_alloc());
            pData_->pEnd_ = pData_->buffer_ + size;
            pData_->pEndOfMem_ = pData_->buffer_ + capacity;
        }
    }

private:
    // Warning - this doesn't initialize pData_. Used in reserve()
    SimpleStringStorage()
    { }

public:
    typedef E value_type;
    typedef E* iterator;
    typedef const E* const_iterator;
    typedef A allocator_type;

    SimpleStringStorage(const SimpleStringStorage& rhs) 
    {
        const size_type sz = rhs.size();
        Init(sz, sz);
        if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
    }

    SimpleStringStorage(const SimpleStringStorage& s, 
        flex_string_details::Shallow) 
        : pData_(s.pData_)
    {
    }

    SimpleStringStorage(const A&)
    { pData_ = const_cast<Data*>(&emptyString_); }

    SimpleStringStorage(const E* s, size_type len, const A&)
    {
        Init(len, len);
        flex_string_details::pod_copy(s, s + len, begin());
    }

    SimpleStringStorage(size_type len, E c, const A&)
    {
        Init(len, len);
        flex_string_details::pod_fill(begin(), end(), c);
    }

    SimpleStringStorage& operator=(const SimpleStringStorage& rhs)
    {
        const size_type sz = rhs.size();
        reserve(sz);
        flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
        pData_->pEnd_ = &*begin() + sz;
        return *this;
    }

    ~SimpleStringStorage()
    {
        BOOST_ASSERT(begin() <= end());
        if (pData_ != &emptyString_) free(pData_);
    }

    iterator begin()
    { return pData_->buffer_; }

    const_iterator begin() const
    { return pData_->buffer_; }

    iterator end()
    { return pData_->pEnd_; }

    const_iterator end() const
    { return pData_->pEnd_; }

    size_type size() const
    { return pData_->pEnd_ - pData_->buffer_; }

    size_type max_size() const
    { return std::size_t(-1) / sizeof(E) - sizeof(Data) - 1; }

    size_type capacity() const
    { return pData_->pEndOfMem_ - pData_->buffer_; }

    void reserve(size_type res_arg)
    {
        if (res_arg <= capacity())
        {
            // @@@ insert shrinkage here if you wish
            return;
        }

        if (pData_ == &emptyString_) 
        {
            Init(0, res_arg);
        }
        else
        {
            const size_type sz = size();

            void* p = realloc(pData_, 
                sizeof(Data) + res_arg * sizeof(E));
            if (!p) boost::throw_exception(std::bad_alloc());
        
            if (p != pData_)
            {
                pData_ = static_cast<Data*>(p);
                pData_->pEnd_ = pData_->buffer_ + sz;
            }
            pData_->pEndOfMem_ = pData_->buffer_ + res_arg;
        }
    }

    void append(const E* s, size_type sz)
    {
        const size_type neededCapacity = size() + sz;

        if (capacity() < neededCapacity)
        {
            const iterator b = begin();
            static std::less_equal<const E*> le;
            if (le(b, s) && le(s, end()))
            {
               // aliased
                const size_type offset = s - b;
                reserve(neededCapacity);
                s = begin() + offset;
            }
            else
            {
                reserve(neededCapacity);
            }
        }
        flex_string_details::pod_copy(s, s + sz, end());
        pData_->pEnd_ += sz;
    }

    template <class InputIterator>
    void append(InputIterator b, InputIterator e)
    {
        // @@@ todo: optimize this depending on iterator type
        for (; b != e; ++b)
        {
            *this += *b;
        }
    }

    void resize(size_type newSize, E fill)
    {
        const int delta = int(newSize - size());
        if (delta == 0) return;

        if (delta > 0)
        {
            if (newSize > capacity()) 
            {
                reserve(newSize);
            }
            E* e = &*end();
            flex_string_details::pod_fill(e, e + delta, fill);
        }
        pData_->pEnd_ = pData_->buffer_ + newSize;
    }

    void swap(SimpleStringStorage& rhs)
    {
        std::swap(pData_, rhs.pData_);
    }
    
    const E* c_str() const
    {
        if (pData_ != &emptyString_) *pData_->pEnd_ = E();
        return pData_->buffer_; 
    }

    const E* data() const
    { return pData_->buffer_; }
    
    A get_allocator() const
    { return A(); }
};

template <typename E, class A>
const typename SimpleStringStorage<E, A>::Data
SimpleStringStorage<E, A>::emptyString_ = 
    typename SimpleStringStorage<E, A>::Data();

////////////////////////////////////////////////////////////////////////////////
// class template AllocatorStringStorage
// Allocates with your allocator
// Takes advantage of the Empty Base Optimization if available
////////////////////////////////////////////////////////////////////////////////

template <typename E, class A = std::allocator<E> >
class AllocatorStringStorage : public A
{
    typedef typename A::size_type size_type;
    typedef typename SimpleStringStorage<E, A>::Data Data;

    void* Alloc(size_type sz, const void* p = 0)
    {
        return A::allocate(1 + (sz - 1) / sizeof(E), 
            static_cast<const char*>(p));
    }

    void* Realloc(void* p, size_type oldSz, size_type newSz)
    {
        void* r = Alloc(newSz);
        flex_string_details::pod_copy(p, p + Min(oldSz, newSz), r);
        Free(p, oldSz);
        return r;
    }

    void Free(void* p, size_type sz)
    {
        A::deallocate(static_cast<E*>(p), sz);
    }

    Data* pData_;

    void Init(size_type size, size_type cap)
    {
        BOOST_ASSERT(size <= cap);

        if (cap == 0)
        {
            pData_ = const_cast<Data*>(
                &SimpleStringStorage<E, A>::emptyString_);
        }
        else
        {
            pData_ = static_cast<Data*>(Alloc(
                cap * sizeof(E) + sizeof(Data)));
            pData_->pEnd_ = pData_->buffer_ + size;
            pData_->pEndOfMem_ = pData_->buffer_ + cap;
        }
    }

public:
    typedef E value_type;
    typedef E* iterator;
    typedef const E* const_iterator;
    typedef A allocator_type;

    AllocatorStringStorage() 
    : A(), pData_(0)
    {
    }

    AllocatorStringStorage(const AllocatorStringStorage& rhs) 
    : A(rhs.get_allocator())
    {
        const size_type sz = rhs.size();
        Init(sz, sz);
        if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
    }

    AllocatorStringStorage(const AllocatorStringStorage& s, 
        flex_string_details::Shallow) 
    : A(s.get_allocator())
    {
        pData_ = s.pData_;
    }

    AllocatorStringStorage(const A& a) : A(a)
    { 
        pData_ = const_cast<Data*>(
            &SimpleStringStorage<E, A>::emptyString_);
    }

    AllocatorStringStorage(const E* s, size_type len, const A& a)
    : A(a)
    {
        Init(len, len);
        flex_string_details::pod_copy(s, s + len, begin());
    }

    AllocatorStringStorage(size_type len, E c, const A& a)
    : A(a)
    {
        Init(len, len);
        flex_string_details::pod_fill(&*begin(), &*end(), c);
    }

    AllocatorStringStorage& operator=(const AllocatorStringStorage& rhs)
    {
        const size_type sz = rhs.size();
        reserve(sz);
        flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
        pData_->pEnd_ = &*begin() + rhs.size();
        return *this;
    }

    ~AllocatorStringStorage()
    {
        if (capacity())
        {
            Free(pData_, 
                sizeof(Data) + capacity() * sizeof(E));
        }
    }

    iterator begin()
    { return pData_->buffer_; }

    const_iterator begin() const
    { return pData_->buffer_; }

    iterator end()
    { return pData_->pEnd_; }

    const_iterator end() const
    { return pData_->pEnd_; }

    size_type size() const
    { return size_type(end() - begin()); }

    size_type max_size() const
    { return A::max_size(); }

    size_type capacity() const
    { return size_type(pData_->pEndOfMem_ - pData_->buffer_); }

    void resize(size_type n, E c)
    {
        reserve(n);
        iterator newEnd = begin() + n;
        iterator oldEnd = end();
        if (newEnd > oldEnd) 
        {
            // Copy the characters
            flex_string_details::pod_fill(oldEnd, newEnd, c);
        }
        if (capacity()) pData_->pEnd_ = newEnd;
    }

    void reserve(size_type res_arg)
    {
        if (res_arg <= capacity())
        {
            // @@@ shrink to fit here 
            return;
        }

        A& myAlloc = *this;
        AllocatorStringStorage newStr(myAlloc);
        newStr.Init(size(), res_arg);

        flex_string_details::pod_copy(begin(), end(), newStr.begin());

        swap(newStr);
    }

    template <class ForwardIterator>
    void append(ForwardIterator b, ForwardIterator e)
    {
        const size_type 
            sz = std::distance(b, e),
            neededCapacity = size() + sz;

        if (capacity() < neededCapacity)
        {
//             typedef std::less_equal<const E*> le_type;
//             BOOST_ASSERT(!(le_type()(begin(), &*b) && le_type()(&*b, end())));
            reserve(neededCapacity);
        }
        std::copy(b, e, end());
        pData_->pEnd_ += sz;
    }

    void swap(AllocatorStringStorage& rhs)
    {
        // @@@ The following line is commented due to a bug in MSVC
        //std::swap(lhsAlloc, rhsAlloc);
        std::swap(pData_, rhs.pData_);
    }

    const E* c_str() const
    { 
        if (pData_ != &SimpleStringStorage<E, A>::emptyString_) 
        {
            *pData_->pEnd_ = E();
        }
        return &*begin(); 
    }

    const E* data() const
    { return &*begin(); }

    A get_allocator() const
    { return *this; }
};

////////////////////////////////////////////////////////////////////////////////
// class template VectorStringStorage
// Uses std::vector
// Takes advantage of the Empty Base Optimization if available
////////////////////////////////////////////////////////////////////////////////

template <typename E, class A = std::allocator<E> >
class VectorStringStorage : protected std::vector<E, A>
{
    typedef std::vector<E, A> base;

public: // protected:
    typedef E value_type;
    typedef typename base::iterator iterator;
    typedef typename base::const_iterator const_iterator;
    typedef A allocator_type;
    typedef typename A::size_type size_type;
    
    VectorStringStorage(const VectorStringStorage& s) : base(s)
    { }
    
    VectorStringStorage(const A& a) : base(1, E(), a)
    { }
    
    VectorStringStorage(const E* s, size_type len, const A& a)
    : base(a)
    {
        base::reserve(len + 1);
        base::insert(base::end(), s, s + len);
        // Terminating zero
        base::insert(base::end(), E());
    }

    VectorStringStorage(size_type len, E c, const A& a)
    : base(len + 1, c, a)
    {
        // Terminating zero
        base::back() = E();
    }
    
    VectorStringStorage& operator=(const VectorStringStorage& rhs)
    {
        base& v = *this;
        v = rhs;
        return *this;
    }
   
    iterator begin()
    { return base::begin(); }
    
    const_iterator begin() const
    { return base::begin(); }
    
    iterator end()
    { return base::end() - 1; }
    
    const_iterator end() const
    { return base::end() - 1; }
    
    size_type size() const
    { return base::size() - 1; }

    size_type max_size() const
    { return base::max_size() - 1; }

    size_type capacity() const
    { return base::capacity() - 1; }

    void reserve(size_type res_arg)
    { 
        BOOST_ASSERT(res_arg < max_size());
        base::reserve(res_arg + 1); 
    }
    
    void append(const E* s, size_type sz)
    {
        // Check for aliasing because std::vector doesn't do it.
        static std::less_equal<const E*> le;
        if (!base::empty())
        {
            const E* start = &base::front();
            if (le(start, s) && le(s, start + size()))
            {
                // aliased
                const size_type offset = s - start;
                reserve(size() + sz);
                s = &base::front() + offset;
            }
        }
        base::insert(end(), s, s + sz);
    }
    
    template <class InputIterator>
    void append(InputIterator b, InputIterator e)
    {
        base::insert(end(), b, e);
    }

    void resize(size_type n, E c)
    {
        base::reserve(n + 1);
        base::back() = c;
        base::resize(n + 1, c);
        base::back() = E();
    }

    void swap(VectorStringStorage& rhs)
    { base::swap(rhs); }
    
    const E* c_str() const
    { return &*begin(); }

    const E* data() const
    { return &*begin(); }
    
    A get_allocator() const
    { return base::get_allocator(); }
};

////////////////////////////////////////////////////////////////////////////////
// class template SmallStringOpt
// Builds the small string optimization over any other storage
////////////////////////////////////////////////////////////////////////////////

template <class Storage, unsigned int threshold, 
    typename Align = typename Storage::value_type*>
class SmallStringOpt
{
public:
    typedef typename Storage::value_type value_type;
    typedef value_type* iterator;
    typedef const value_type* const_iterator;
    typedef typename Storage::allocator_type allocator_type;
    typedef typename allocator_type::size_type size_type;
    
private:
  enum { temp1 = threshold * sizeof(value_type) > sizeof(Storage) 
        ? threshold  * sizeof(value_type) 
        : sizeof(Storage) };
    
    enum { temp2 = temp1 > sizeof(Align) ? temp1 : sizeof(Align) };

public:
    enum { maxSmallString = 
    (temp2 + sizeof(value_type) - 1) / sizeof(value_type) };
    
private:
    enum { magic = maxSmallString + 1 };
    
    union
    {
        mutable value_type buf_[maxSmallString + 1];
        Align align_;
    };

    Storage& GetStorage()
    {
        BOOST_ASSERT(buf_[maxSmallString] == magic);
        Storage* p = reinterpret_cast<Storage*>(&buf_[0]);
        return *p;
    }

    const Storage& GetStorage() const
    {
        BOOST_ASSERT(buf_[maxSmallString] == magic);
        const Storage *p = reinterpret_cast<const Storage*>(&buf_[0]);
        return *p;
    }

    bool Small() const
    {
        return buf_[maxSmallString] != magic;
    }

public:
  SmallStringOpt(const SmallStringOpt& s)
    {
        if (s.Small())
        {
            flex_string_details::pod_copy(
                s.buf_, 
                s.buf_ + s.size(), 
                buf_);
        }
        else
        {
            new(buf_) Storage(s.GetStorage());
        }
        buf_[maxSmallString] = s.buf_[maxSmallString];
    }

    SmallStringOpt(const allocator_type&)
    {
        buf_[maxSmallString] = maxSmallString;
    }

    SmallStringOpt(const value_type* s, size_type len, const allocator_type& a)
    {
        if (len <= maxSmallString)
        {
            flex_string_details::pod_copy(s, s + len, buf_);
            buf_[maxSmallString] = value_type(maxSmallString - len);
        }
        else
        {
            new(buf_) Storage(s, len, a);
            buf_[maxSmallString] = magic;
        }
    }

    SmallStringOpt(size_type len, value_type c, const allocator_type& a)
    {
        if (len <= maxSmallString)
        {
            flex_string_details::pod_fill(buf_, buf_ + len, c);
            buf_[maxSmallString] = value_type(maxSmallString - len);
        }
        else
        {
            new(buf_) Storage(len, c, a);
            buf_[maxSmallString] = magic;
        }
    }

    SmallStringOpt& operator=(const SmallStringOpt& rhs)
    {
        reserve(rhs.size());
        resize(0, 0);
        append(rhs.data(), rhs.size());
        return *this;
    }

    ~SmallStringOpt()
    {
        if (!Small()) GetStorage().~Storage();
    }

    iterator begin()
    {
        if (Small()) return buf_;
        return &*GetStorage().begin(); 
    }

    const_iterator begin() const
    {
        if (Small()) return buf_;
        return &*GetStorage().begin(); 
    }

    iterator end()
    {
        if (Small()) return buf_ + maxSmallString - buf_[maxSmallString];
        return &*GetStorage().end(); 
    }

    const_iterator end() const
    {
        if (Small()) return buf_ + maxSmallString - buf_[maxSmallString];
        return &*GetStorage().end(); 
    }

    size_type size() const
    {
        BOOST_ASSERT(!Small() || maxSmallString >= buf_[maxSmallString]);
        return Small() 
            ? maxSmallString - buf_[maxSmallString] 
            : GetStorage().size();
    }

    size_type max_size() const
    { return get_allocator().max_size(); }

    size_type capacity() const
    { return Small() ? maxSmallString : GetStorage().capacity(); }

    void reserve(size_type res_arg)
    {
        if (Small())
        {
            if (res_arg <= maxSmallString) return;
            SmallStringOpt temp(*this);
            this->~SmallStringOpt();
            new(buf_) Storage(temp.data(), temp.size(), 
                temp.get_allocator());
            buf_[maxSmallString] = magic;
            GetStorage().reserve(res_arg);
        }
        else
        {
            GetStorage().reserve(res_arg);
        }
        BOOST_ASSERT(capacity() >= res_arg);
    }

    void append(const value_type* s, size_type sz)
    {
        if (!Small())
        {
            GetStorage().append(s, sz);
        }
        else
        {
            // append to a small string
            const size_type neededCapacity = 
                maxSmallString - buf_[maxSmallString] + sz;

            if (maxSmallString < neededCapacity)
            {
                // need to change storage strategy
                allocator_type alloc;
                Storage temp(alloc);
                temp.reserve(neededCapacity);
                temp.append(buf_, maxSmallString - buf_[maxSmallString]);
                temp.append(s, sz);
                buf_[maxSmallString] = magic;
                new(buf_) Storage(temp.get_allocator());
                GetStorage().swap(temp);
            }
            else
            {
                flex_string_details::pod_move(s, s + sz, 
                    buf_ + maxSmallString - buf_[maxSmallString]);
                buf_[maxSmallString] -= value_type(sz);
            }
        }
    }

    template <class InputIterator>
    void append(InputIterator b, InputIterator e)
    {
        // @@@ todo: optimize this depending on iterator type
        for (; b != e; ++b)
        {
            *this += *b;
        }
    }

    void resize(size_type n, value_type c)
    {
        if (Small())
        {
            if (n > maxSmallString)
            {
                // Small string resized to big string
                SmallStringOpt temp(*this); // can't throw
                // 11-17-2001: correct exception safety bug
                Storage newString(temp.data(), temp.size(), 
                    temp.get_allocator());
                newString.resize(n, c);
                // We make the reasonable assumption that an empty Storage
                //     constructor won't throw
                this->~SmallStringOpt();
                new(&buf_[0]) Storage(temp.get_allocator());
                buf_[maxSmallString] = value_type(magic);
                GetStorage().swap(newString);
            }
            else
            {
                // Small string resized to small string
                // 11-17-2001: bug fix: terminating zero not copied
                size_type toFill = n > size() ? n - size() : 0;
                flex_string_details::pod_fill(end(), end() + toFill, c);
                buf_[maxSmallString] = value_type(maxSmallString - n);
            }
        }
        else
        {
            if (n > maxSmallString)
            {
                // Big string resized to big string
                GetStorage().resize(n, c);
            }
            else
            {
                // Big string resized to small string
                // 11-17=2001: bug fix in the BOOST_ASSERTion below
                BOOST_ASSERT(capacity() > n);
                SmallStringOpt newObj(data(), n, get_allocator());
                newObj.swap(*this);
            }
        }
    }

    void swap(SmallStringOpt& rhs)
    {
        if (Small())
        {
            if (rhs.Small())
            {
                // Small swapped with small
                std::swap_ranges(buf_, buf_ + maxSmallString + 1, 
                    rhs.buf_);
            }
            else
            {
                // Small swapped with big
                // Make a copy of myself - can't throw
                SmallStringOpt temp(*this);
                // Nuke myself
                this->~SmallStringOpt();
                // Make an empty storage for myself (likely won't throw)
                new(buf_) Storage(0, value_type(), rhs.get_allocator());
                buf_[maxSmallString] = magic;
                // Recurse to this same function
                swap(rhs);
                // Nuke rhs
                rhs.~SmallStringOpt();
                // Build the new small string into rhs
                new(&rhs) SmallStringOpt(temp);
            }
        }
        else
        {
            if (rhs.Small())
            {
                // Big swapped with small
                // Already implemented, recurse with reversed args
                rhs.swap(*this);
            }
            else
            {
                // Big swapped with big
                GetStorage().swap(rhs.GetStorage());
            }
        }
    }

    const value_type* c_str() const
    { 
        if (!Small()) return GetStorage().c_str(); 
        buf_[maxSmallString - buf_[maxSmallString]] = value_type();
        return buf_;
    }

    const value_type* data() const
    { return Small() ? buf_ : GetStorage().data(); }
    
    allocator_type get_allocator() const
    { return allocator_type(); }
};

////////////////////////////////////////////////////////////////////////////////
// class template CowString
// Implements Copy on Write over any storage
////////////////////////////////////////////////////////////////////////////////

template <
    typename Storage, 
    typename Align = BOOST_DEDUCED_TYPENAME Storage::value_type*
>
class CowString
{
    typedef typename Storage::value_type E;
    typedef typename flex_string_details::get_unsigned<E>::result RefCountType;

public:
    typedef E value_type;
    typedef typename Storage::iterator iterator;
    typedef typename Storage::const_iterator const_iterator;
    typedef typename Storage::allocator_type allocator_type;
    typedef typename allocator_type::size_type size_type;
    typedef typename Storage::reference reference;
    
private:
    union
    {
        mutable char buf_[sizeof(Storage)];
        Align align_;
    };

    Storage& Data() const
    { 
        Storage* p = reinterpret_cast<Storage*>(&buf_[0]);
        return *p;
    }

    RefCountType GetRefs() const
    {
        const Storage& d = Data();
        BOOST_ASSERT(d.size() > 0);
        BOOST_ASSERT(static_cast<RefCountType>(*d.begin()) != 0);
        return *d.begin();
    }
    
    RefCountType& Refs()
    {
        Storage& d = Data();
        BOOST_ASSERT(d.size() > 0);
        return reinterpret_cast<RefCountType&>(*d.begin());
    }
    
    void MakeUnique() const
    {
        BOOST_ASSERT(GetRefs() >= 1);
        if (GetRefs() == 1) return;

        union
        {
            char buf_[sizeof(Storage)];
            Align align_;
        } temp;

        --(*Data().begin()); // decrement the use count of the remaining object

        Storage* p = reinterpret_cast<Storage*>(&temp.buf_[0]);
        new(buf_) Storage(
            *new(p) Storage(Data()), 
            flex_string_details::Shallow());
        *Data().begin() = 1;
    }

public:
    CowString(const CowString& s)
    {
        if (s.GetRefs() == (std::numeric_limits<RefCountType>::max)())
        {
            // must make a brand new copy
            new(buf_) Storage(s.Data()); // non shallow
            Refs() = 1;
        }
        else
        {
            new(buf_) Storage(s.Data(), flex_string_details::Shallow());
            ++Refs();
        }
        BOOST_ASSERT(Data().size() > 0);
    }
    
    CowString(const allocator_type& a)
    {
        new(buf_) Storage(1, 1, a);
    }
    
    CowString(const E* s, size_type len, const allocator_type& a)
    {
        // Warning - MSVC's debugger has trouble tracing through the code below.
        // It seems to be a const-correctness issue
        //
        new(buf_) Storage(a);
        Data().reserve(len + 1);
        Data().resize(1, 1);
        Data().append(s, s + len);
    }

    CowString(size_type len, E c, const allocator_type& a)
    {
        new(buf_) Storage(len + 1, c, a);
        Refs() = 1;
    }
    
    CowString& operator=(const CowString& rhs)
    {
//        CowString(rhs).swap(*this);
        if (--Refs() == 0) 
            Data().~Storage();
        if (rhs.GetRefs() == (std::numeric_limits<RefCountType>::max)())
        {
            // must make a brand new copy
            new(buf_) Storage(rhs.Data()); // non shallow
            Refs() = 1;
        }
        else
        {
            new(buf_) Storage(rhs.Data(), flex_string_details::Shallow());
            ++Refs();
        }
        BOOST_ASSERT(Data().size() > 0);
        return *this;
    }

    ~CowString()
    {
        BOOST_ASSERT(Data().size() > 0);
        if (--Refs() == 0) 
            Data().~Storage();
    }

    iterator begin()
    {
        BOOST_ASSERT(Data().size() > 0);
        MakeUnique();
        return Data().begin() + 1; 
    }
    
    const_iterator begin() const
    {
        BOOST_ASSERT(Data().size() > 0);
        return Data().begin() + 1; 
    }
    
    iterator end()
    {
        MakeUnique();
        return Data().end(); 
    }
    
    const_iterator end() const
    {
        return Data().end(); 
    }
    
    size_type size() const
    {
        BOOST_ASSERT(Data().size() > 0);
        return Data().size() - 1;
    }

    size_type max_size() const
    { 
        BOOST_ASSERT(Data().max_size() > 0);
        return Data().max_size() - 1;
    }

    size_type capacity() const
    { 
        BOOST_ASSERT(Data().capacity() > 0);
        return Data().capacity() - 1;
    }

    void resize(size_type n, E c)
    {
        BOOST_ASSERT(Data().size() > 0);
        MakeUnique();
        Data().resize(n + 1, c);
    }

    template <class FwdIterator>
    void append(FwdIterator b, FwdIterator e)
    {
        MakeUnique();
        Data().append(b, e);
    }
    
    void reserve(size_type res_arg)
    {
        if (capacity() > res_arg) return;
        MakeUnique();
        Data().reserve(res_arg + 1);
    }
    
    void swap(CowString& rhs)
    {
        Data().swap(rhs.Data());
    }
    
    const E* c_str() const
    { 
        BOOST_ASSERT(Data().size() > 0);
        return Data().c_str() + 1;
    }

    const E* data() const
    { 
        BOOST_ASSERT(Data().size() > 0);
        return Data().data() + 1;
    }
    
    allocator_type get_allocator() const
    { 
        return Data().get_allocator();
    }
};

////////////////////////////////////////////////////////////////////////////////
// class template flex_string
// a std::basic_string compatible implementation 
// Uses a Storage policy 
////////////////////////////////////////////////////////////////////////////////

template <typename E,
    class T = std::char_traits<E>,
    class A = std::allocator<E>,
    class Storage = AllocatorStringStorage<E, A> >
class flex_string : private Storage
{
#if defined(BOOST_WAVE_FLEXSTRING_THROW_ON_ENFORCE)
    template <typename Exception>
    static void Enforce(bool condition, Exception*, const char* msg)
    { if (!condition) boost::throw_exception(Exception(msg)); }
#else
    template <typename Exception>
    static inline void Enforce(bool condition, Exception*, const char* msg)
    { BOOST_ASSERT(condition && msg); }
#endif // defined(BOOST_WAVE_FLEXSTRING_THROW_ON_ENFORCE)

#ifndef NDEBUG
    bool Sane() const
    {
        return
            begin() <= end() &&
            empty() == (size() == 0) &&
            empty() == (begin() == end()) &&
            size() <= max_size() &&
            capacity() <= max_size() &&
            size() <= capacity();
    }

    struct Invariant;
    friend struct Invariant;
    struct Invariant
    {
        Invariant(const flex_string& s) : s_(s)
        {
            BOOST_ASSERT(s_.Sane());
        }
        ~Invariant()
        {
            BOOST_ASSERT(s_.Sane());
        }
    private:
        const flex_string& s_;
        Invariant& operator=(const Invariant&);
    };
#endif

public:
    // types
    typedef T traits_type;
    typedef typename traits_type::char_type value_type;
    typedef A allocator_type;
    typedef typename A::size_type size_type;
    typedef typename A::difference_type difference_type;
    
    typedef typename A::reference reference;
    typedef typename A::const_reference const_reference;
    typedef typename A::pointer pointer;
    typedef typename A::const_pointer const_pointer;
    
    typedef typename Storage::iterator iterator;
    typedef typename Storage::const_iterator const_iterator;

    typedef boost::reverse_iterator<iterator> reverse_iterator;
    typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;

    static const size_type npos;    // = size_type(-1)

private:
    static size_type Min(size_type lhs, size_type rhs)
    { return lhs < rhs ? lhs : rhs; }
    static void Procust(size_type& n, size_type nmax)
    { if (n > nmax) n = nmax; }
    
public:    
    // 21.3.1 construct/copy/destroy
    explicit flex_string(const A& a = A())
    : Storage(a) 
    {}
    
    flex_string(const flex_string& str)
    : Storage(str) 
    {
    }
    
    flex_string(const flex_string& str, size_type pos, 
        size_type n = npos, const A& a = A())
    : Storage(a) 
    {
        Enforce(pos <= str.size(), (std::out_of_range*)0, "");
        assign(str, pos, n);
    }
    
    flex_string(const value_type* s, const A& a = A())
    : Storage(s, traits_type::length(s), a)
    {}
    
    flex_string(const value_type* s, size_type n, const A& a = A())
    : Storage(s, n, a)
    {}
    
    flex_string(size_type n, value_type c, const A& a = A())
    : Storage(n, c, a)
    {}

    template <class InputIterator>
    flex_string(InputIterator begin, InputIterator end, const A& a = A())
    : Storage(a)
    {
        assign(begin, end);
    }

    ~flex_string()
    {}
    
    flex_string& operator=(const flex_string& str)
    {
        if (this != &str) {
            Storage& s = *this;
            s = str;
        }
        return *this;
    }   
    
    flex_string& operator=(const value_type* s)
    {
        assign(s);
        return *this;
    }

    flex_string& operator=(value_type c)
    {
        assign(1, c);
        return *this;
    }
    
    // 21.3.2 iterators:
    iterator begin()
    { return Storage::begin(); }
    
    const_iterator begin() const
    { return Storage::begin(); }
    
    iterator end()
    { return Storage::end(); }
    
    const_iterator end() const
    { return Storage::end(); }

    reverse_iterator rbegin()
    { return reverse_iterator(end()); }
    
    const_reverse_iterator rbegin() const
    { return const_reverse_iterator(end()); }
    
    reverse_iterator rend()
    { return reverse_iterator(begin()); }
    
    const_reverse_iterator rend() const
    { return const_reverse_iterator(begin()); }

#if BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK != 0
    //  temporary hack to make it easier to serialize flex_string's using
    //  the Boost.Serialization library 
    value_type & back() { return *(begin()+size()-1); }
    value_type const& back() const { return *(begin()+size()-1); }
#endif

    // 21.3.3 capacity:
    size_type size() const
    { return Storage::size(); }
    
    size_type length() const
    { return size(); }
    
    size_type max_size() const
    { return Storage::max_size(); }

    void resize(size_type n, value_type c)
    { Storage::resize(n, c); }
    
    void resize(size_type n)
    { resize(n, value_type()); }
    
    size_type capacity() const
    { return Storage::capacity(); }
    
    void reserve(size_type res_arg = 0)
    {
        Enforce(res_arg <= max_size(), (std::length_error*)0, "");
        Storage::reserve(res_arg);
    }
    
    void clear()
    { resize(0); } 
    
    bool empty() const
    { return size() == 0; }
    
    // 21.3.4 element access:
    const_reference operator[](size_type pos) const
    { return *(begin() + pos); }
    
    reference operator[](size_type pos)
    { return *(begin() + pos); }

    const_reference at(size_type n) const
    {
        Enforce(n < size(), (std::out_of_range*)0, "");
        return (*this)[n];
    }
    
    reference at(size_type n)
    {
        Enforce(n < size(), (std::out_of_range*)0, "");
        return (*this)[n];
    }
    
    // 21.3.5 modifiers:
    flex_string& operator+=(const flex_string& str)
    { return append(str); }
    
    flex_string& operator+=(const value_type* s)
    { return append(s); }

    flex_string& operator+=(value_type c)
    { 
        push_back(c);
        return *this;
    }
    
    flex_string& append(const flex_string& str)
    { return append(str, 0, npos); }
    
    flex_string& append(const flex_string& str, const size_type pos,
        size_type n)
    { 
        const size_type sz = str.size();
        Enforce(pos <= sz, (std::out_of_range*)0, "");
        Procust(n, sz - pos);
        return append(str.c_str() + pos, n); 
    }
    
    flex_string& append(const value_type* s, const size_type n)
    { 
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        if (IsAliasedRange(s, s + n))
        {
            const size_type offset = s - &*begin();
            Storage::reserve(size() + n);
            s = &*begin() + offset;
        }
        Storage::append(s, s+ n); 
        return *this;
    }
    
    flex_string& append(const value_type* s)
    { return append(s, traits_type::length(s)); }
    
    flex_string& append(size_type n, value_type c)
    { 
        resize(size() + n, c);
        return *this;
    }

    template<class InputIterator>
    flex_string& append(InputIterator first, InputIterator last)
    {
        insert(end(), first, last);
        return *this;
    }

    void push_back(value_type c)
    { 
        const size_type cap = capacity();
        if (size() == cap)
        {
            reserve(cap << 1u);
        }
        Storage::append(&c, &c + 1);
    }

    flex_string& assign(const flex_string& str)
    { 
        if (&str == this) return *this;
        return assign(str.data(), str.size());
    }
    
    flex_string& assign(const flex_string& str, size_type pos,
        size_type n)
    { 
        const size_type sz = str.size();
        Enforce(pos <= str.size(), (std::out_of_range*)0, "");
        Procust(n, sz - pos);
        return assign(str.data() + pos, n);
    }
    
    flex_string& assign(const value_type* s, size_type n)
    {
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        if (size() >= n)
        {
            std::copy(s, s + n, begin());
            resize(n);
        }
        else
        {
            const value_type *const s2 = s + size();
            std::copy(s, s2, begin());
            append(s2, n - size());
        }
        return *this;
    }
    
    flex_string& assign(const value_type* s)
    { return assign(s, traits_type::length(s)); }
    
    template <class ItOrLength, class ItOrChar>
    flex_string& assign(ItOrLength first_or_n, ItOrChar last_or_c)
    { return replace(begin(), end(), first_or_n, last_or_c); }
    
    flex_string& insert(size_type pos1, const flex_string& str)
    { return insert(pos1, str.data(), str.size()); }
    
    flex_string& insert(size_type pos1, const flex_string& str,
        size_type pos2, size_type n)
    { 
        Enforce(pos2 <= str.length(), (std::out_of_range*)0, "");
        Procust(n, str.length() - pos2);
        return insert(pos1, str.data() + pos2, n); 
    }
    
    flex_string& insert(size_type pos, const value_type* s, size_type n)
    { 
        Enforce(pos <= length(), (std::out_of_range*)0, "");
        insert(begin() + pos, s, s + n); 
        return *this;
    }
    
    flex_string& insert(size_type pos, const value_type* s)
    { return insert(pos, s, traits_type::length(s)); }
    
    flex_string& insert(size_type pos, size_type n, value_type c)
    { 
        Enforce(pos <= length(), (std::out_of_range*)0, "");
        insert(begin() + pos, n, c);
        return *this;
    }
    
    iterator insert(iterator p, value_type c = value_type()) 
    {
        const size_type pos = p - begin();
        insert(pos, &c, 1);
        return begin() + pos;
    }
    
private:
    // Care must be taken when dereferencing some iterator types.
    //
    // Users can implement this function in their namespace if their storage 
    // uses a special iterator type, the function will be found through ADL.
    template<class Iterator>
    const typename std::iterator_traits<Iterator>::value_type* 
    DereferenceValidIterator(Iterator it) const
    {
        return &*it;
    }

    // Care must be taken when dereferencing a reverse iterators, hence this 
    // special case. This isn't in the std namespace so as not to pollute it or 
    // create name clashes.
    template<typename Iterator>
    const typename std::iterator_traits<Iterator>::value_type* 
    DereferenceValidIterator(std::reverse_iterator<Iterator> it) const
    {
        return &*--it;
    }

    // Determine if the range aliases the current string.
    //
    // This method cannot be const because calling begin/end on copy-on-write 
    // implementations must have side effects.
    // A const version wouldn't make the string unique through this call.
    template<class Iterator>
    bool IsAliasedRange(Iterator beginIterator, Iterator endIterator)
    {
        if(!empty() && beginIterator != endIterator)
        {
            typedef const typename std::iterator_traits<Iterator>::value_type * 
                pointer;

            pointer myBegin(&*begin());
            pointer myEnd(&*begin() + size());
            pointer rangeBegin(DereferenceValidIterator(beginIterator));

            const std::less_equal<pointer> less_equal = std::less_equal<pointer>();
            if(less_equal(myBegin, rangeBegin) && less_equal(rangeBegin, myEnd))
                return true;
        }
        return false;
    }

    template <int i> class Selector {};

    flex_string& InsertImplDiscr(iterator p, 
        size_type n, value_type c, Selector<1>)
    { 
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        assert(begin() <= p && p <= end());
        const size_type insertOffset(p - begin());
        const size_type originalSize(size());
        if(n < originalSize - insertOffset)
        {
            // The new characters fit within the original string.
            // The characters that are pushed back need to be moved because 
            // they're aliased.
            // The appended characters will all be overwritten by the move.
            append(n, value_type(0));
            value_type* begin(&*begin());
            flex_string_details::pod_move(begin + insertOffset, 
                begin + originalSize, begin + insertOffset + n);
            std::fill(begin + insertOffset, begin + insertOffset + n, c);
        }
        else
        {
            // The new characters exceed the original string.
            // The characters that are pushed back can simply be copied since 
            // they aren't aliased.
            // The appended characters will partly be overwritten by the copy.
            append(n, c);
            value_type* begin(&*begin());
            flex_string_details::pod_copy(begin + insertOffset, 
                begin + originalSize, begin + insertOffset + n);
            std::fill(begin + insertOffset, begin + originalSize, c);
        }
        return *this;
    }

    template<class InputIterator>
    flex_string& InsertImplDiscr(iterator i,
        InputIterator b, InputIterator e, Selector<0>)
    { 
        InsertImpl(i, b, e, 
            typename std::iterator_traits<InputIterator>::iterator_category());
        return *this;
    }

    template <class FwdIterator>
    void InsertImpl(iterator i,
        FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
    { 
        if(s1 == s2)
        {
            // Insert an empty range.
            return;
        }

        if(IsAliasedRange(s1, s2))
        {
            // The source range is contained in the current string, copy it 
            // and recurse.
            const flex_string temporary(s1, s2);
            InsertImpl(i, temporary.begin(), temporary.end(),
                typename std::iterator_traits<FwdIterator>::iterator_category());
            return;
        }

#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        const size_type pos = i - begin();
        const typename std::iterator_traits<FwdIterator>::difference_type n2 = 
            std::distance(s1, s2);

        assert(n2 >= 0);
        using namespace flex_string_details;
        assert(pos <= size());

        const typename std::iterator_traits<FwdIterator>::difference_type maxn2 = 
            capacity() - size();
        if (maxn2 < n2)
        {
            // Reallocate the string.
            assert(!IsAliasedRange(s1, s2));
            reserve(size() + n2);
            i = begin() + pos;
        }
        if (pos + n2 <= size())
        {
            const iterator tailBegin = end() - n2;
            Storage::append(tailBegin, tailBegin + n2);
            std::copy(reverse_iterator(tailBegin), reverse_iterator(i), 
                reverse_iterator(tailBegin + n2));
            std::copy(s1, s2, i);
        }
        else
        {
            FwdIterator t = s1;
            const size_type old_size = size();
            std::advance(t, old_size - pos);
            assert(std::distance(t, s2) >= 0);
            Storage::append(t, s2);
            Storage::append(data() + pos, data() + old_size);
            std::copy(s1, t, i);
        }
    }

    template <class InputIterator>
    void InsertImpl(iterator insertPosition,
        InputIterator inputBegin, InputIterator inputEnd, 
        std::input_iterator_tag)
    {
        flex_string temporary(begin(), insertPosition);
        for (; inputBegin != inputEnd; ++inputBegin)
        {
            temporary.push_back(*inputBegin);
        }
        temporary.append(insertPosition, end());
        swap(temporary);
    }

public:
    template <class ItOrLength, class ItOrChar>
    void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c)
    { 
        Selector<std::numeric_limits<ItOrLength>::is_specialized> sel;
        InsertImplDiscr(p, first_or_n, last_or_c, sel);
    }
    
    flex_string& erase(size_type pos = 0, size_type n = npos)
    { 
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        Enforce(pos <= length(), (std::out_of_range*)0, "");
        Procust(n, length() - pos);
        std::copy(begin() + pos + n, end(), begin() + pos);
        resize(length() - n);
        return *this;
    }
    
    iterator erase(iterator position)
    {
        const size_type pos(position - begin());
        erase(pos, 1);
        return begin() + pos;
    }
    
    iterator erase(iterator first, iterator last)
    {
        const size_type pos(first - begin());
        erase(pos, last - first);
        return begin() + pos;
    }

    // Replaces at most n1 chars of *this, starting with pos1 with the content of str
    flex_string& replace(size_type pos1, size_type n1, const flex_string& str)
    { return replace(pos1, n1, str, 0, npos); }
    
    // Replaces at most n1 chars of *this, starting with pos1,
    // with at most n2 chars of str starting with pos2
    flex_string& replace(size_type pos1, size_type n1, const flex_string& str,
        size_type pos2, size_type n2)
    {
        Enforce(pos2 <= str.length(), (std::out_of_range*)0, "");
        return replace(pos1, n1, str.data() + pos2, 
            Min(n2, str.size() - pos2));
    }
    
    // Replaces at most n1 chars of *this, starting with pos, with chars from s
    flex_string& replace(size_type pos, size_type n1, const value_type* s)
    { return replace(pos, n1, s, traits_type::length(s)); }
    
    // Replaces at most n1 chars of *this, starting with pos, with n2 occurences of c
    // consolidated with
    // Replaces at most n1 chars of *this, starting with pos,
    // with at most n2 chars of str.
    // str must have at least n2 chars.
    template <class StrOrLength, class NumOrChar>
    flex_string& replace(size_type pos, size_type n1, 
        StrOrLength s_or_n2, NumOrChar n_or_c)
    {
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        Enforce(pos <= size(), (std::out_of_range*)0, "");
        Procust(n1, length() - pos);
        const iterator b = begin() + pos;
        return replace(b, b + n1, s_or_n2, n_or_c);
    }

    flex_string& replace(iterator i1, iterator i2, const flex_string& str)
    { return replace(i1, i2, str.c_str(), str.length()); }
    
    flex_string& replace(iterator i1, iterator i2, const value_type* s)
    { return replace(i1, i2, s, traits_type::length(s)); }

private:
    flex_string& ReplaceImplDiscr(iterator i1, iterator i2, 
        const value_type* s, size_type n, Selector<2>)
    { 
        assert(i1 <= i2);
        assert(begin() <= i1 && i1 <= end());
        assert(begin() <= i2 && i2 <= end());
        return replace(i1, i2, s, s + n); 
    }
    
    flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
        size_type n2, value_type c, Selector<1>)
    { 
        const size_type n1 = i2 - i1;
        if (n1 > n2)
        {
            std::fill(i1, i1 + n2, c);
            erase(i1 + n2, i2);
        }
        else
        {
            std::fill(i1, i2, c);
            insert(i2, n2 - n1, c);
        }
        return *this;
    }

    template <class InputIterator>
    flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
        InputIterator b, InputIterator e, Selector<0>)
    { 
        ReplaceImpl(i1, i2, b, e, 
            typename std::iterator_traits<InputIterator>::iterator_category());
        return *this;
    }

    template <class FwdIterator>
    void ReplaceImpl(iterator i1, iterator i2,
        FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
    { 
#ifndef NDEBUG
        Invariant checker(*this); 
#endif
        const typename std::iterator_traits<iterator>::difference_type n1 = 
            i2 - i1;
        assert(n1 >= 0);
        const typename std::iterator_traits<FwdIterator>::difference_type n2 = 
        std::distance(s1, s2);
        assert(n2 >= 0);

        if (IsAliasedRange(s1, s2))
        {
            // Aliased replace, copy to new string.
            flex_string temporary;
            temporary.reserve(size() - n1 + n2);
            temporary.append(begin(), i1).append(s1, s2).append(i2, end());
            swap(temporary);
            return;
        }

        if (n1 > n2)
        {
            // Shrinks
            std::copy(s1, s2, i1);
            erase(i1 + n2, i2);
        }
        else
        {
            // Grows
            flex_string_details::copy_n(s1, n1, i1);
            std::advance(s1, n1);
            insert(i2, s1, s2);
        }
    }

    template <class InputIterator>
    void ReplaceImpl(iterator i1, iterator i2,
        InputIterator b, InputIterator e, std::input_iterator_tag)
    {
        flex_string temp(begin(), i1);
        temp.append(b, e).append(i2, end());
        swap(temp);
    }

public:
    template <class T1, class T2>
    flex_string& replace(iterator i1, iterator i2,
        T1 first_or_n_or_s, T2 last_or_c_or_n)
    { 
        const bool 
            num1 = std::numeric_limits<T1>::is_specialized,
            num2 = std::numeric_limits<T2>::is_specialized;
        return ReplaceImplDiscr(i1, i2, first_or_n_or_s, last_or_c_or_n, 
            Selector<num1 ? (num2 ? 1 : -1) : (num2 ? 2 : 0)>()); 
    }
       
    size_type copy(value_type* s, size_type n, size_type pos = 0) const
    {
        Enforce(pos <= size(), (std::out_of_range*)0, "");
        n = Min(n, size() - pos);
        
        flex_string_details::pod_copy(
            &*begin() + pos,
            &*begin() + pos + n,
            s);
        return n;
    }
    
    void swap(flex_string& rhs)
    {
        Storage& srhs = rhs;
        this->Storage::swap(srhs);
    }
    
    // 21.3.6 string operations:
    const value_type* c_str() const
    { return Storage::c_str(); }
    
    const value_type* data() const
    { return Storage::data(); }
    
    allocator_type get_allocator() const
    { return Storage::get_allocator(); }
    
    size_type find(const flex_string& str, size_type pos = 0) const
    { return find(str.data(), pos, str.length()); }

    size_type find (const value_type* s, size_type pos, size_type n) const
    {
        const size_type size_(size());
        if (n + pos > size_) 
            return npos; 
        for (; pos < size_; ++pos)
        {
            if (traits_type::compare(&*begin() + pos, s, n) == 0)
            {
                return pos;
            }
        }
        return npos;
    }
    
    size_type find (const value_type* s, size_type pos = 0) const
    { return find(s, pos, traits_type::length(s)); }

    size_type find (value_type c, size_type pos = 0) const
    { return find(&c, pos, 1); }
    
    size_type rfind(const flex_string& str, size_type pos = npos) const
    { return rfind(str.c_str(), pos, str.length()); }
    
    size_type rfind(const value_type* s, size_type pos, size_type n) const
    {
        if (n > length()) return npos;
        pos = Min(pos, length() - n);
        if (n == 0) return pos;

        const_iterator i(begin() + pos);
        for (; ; --i)
        {
            if (traits_type::eq(*i, *s) 
                && traits_type::compare(&*i, s, n) == 0)
            {
                return i - begin();
            }
            if (i == begin()) break;
        }
        return npos;
    }

    size_type rfind(const value_type* s, size_type pos = npos) const
    { return rfind(s, pos, traits_type::length(s)); }

    size_type rfind(value_type c, size_type pos = npos) const
    { return rfind(&c, pos, 1); }
    
    size_type find_first_of(const flex_string& str, size_type pos = 0) const
    { return find_first_of(str.c_str(), pos, str.length()); }
    
    size_type find_first_of(const value_type* s, 
        size_type pos, size_type n) const
    {
        if (pos > length() || n == 0) return npos;
        const_iterator i(begin() + pos),
            finish(end());
        for (; i != finish; ++i)
        {
            if (traits_type::find(s, n, *i) != 0)
            {
                return i - begin();
            }
        }
        return npos;
    }
        
    size_type find_first_of(const value_type* s, size_type pos = 0) const
    { return find_first_of(s, pos, traits_type::length(s)); }
    
    size_type find_first_of(value_type c, size_type pos = 0) const
    { return find_first_of(&c, pos, 1); }
    
    size_type find_last_of (const flex_string& str,
        size_type pos = npos) const
    { return find_last_of(str.c_str(), pos, str.length()); }
    
    size_type find_last_of (const value_type* s, size_type pos, 
        size_type n) const
    {
        if (!empty() && n > 0)
        {
            pos = Min(pos, length() - 1);
            const_iterator i(begin() + pos);
            for (;; --i)
            {
                if (traits_type::find(s, n, *i) != 0)
                {
                    return i - begin();
                }
                if (i == begin()) break;
            }
        }
        return npos;
    }

    size_type find_last_of (const value_type* s, 
        size_type pos = npos) const
    { return find_last_of(s, pos, traits_type::length(s)); }

    size_type find_last_of (value_type c, size_type pos = npos) const
    { return find_last_of(&c, pos, 1); }
    
    size_type find_first_not_of(const flex_string& str,
        size_type pos = 0) const
    { return find_first_not_of(str.data(), pos, str.size()); }
    
    size_type find_first_not_of(const value_type* s, size_type pos,
        size_type n) const
    {
        if (pos < length())
        {
            const_iterator 
                i(begin() + pos),
                finish(end());
            for (; i != finish; ++i)
            {
                if (traits_type::find(s, n, *i) == 0)
                {
                    return i - begin();
                }
            }
        }
        return npos;
    }
    
    size_type find_first_not_of(const value_type* s, 
        size_type pos = 0) const
    { return find_first_not_of(s, pos, traits_type::length(s)); }
        
    size_type find_first_not_of(value_type c, size_type pos = 0) const
    { return find_first_not_of(&c, pos, 1); }
    
    size_type find_last_not_of(const flex_string& str,
        size_type pos = npos) const
    { return find_last_not_of(str.c_str(), pos, str.length()); }
    
    size_type find_last_not_of(const value_type* s, size_type pos,
        size_type n) const
    {
        if (!empty())
        {
            pos = Min(pos, size() - 1);
            const_iterator i(begin() + pos);
            for (;; --i)
            {
                if (traits_type::find(s, n, *i) == 0)
                {
                    return i - begin();
                }
                if (i == begin()) break;
            }
        }
        return npos;
    }

    size_type find_last_not_of(const value_type* s, 
        size_type pos = npos) const
    { return find_last_not_of(s, pos, traits_type::length(s)); }
    
    size_type find_last_not_of (value_type c, size_type pos = npos) const
    { return find_last_not_of(&c, pos, 1); }
    
    flex_string substr(size_type pos = 0, size_type n = npos) const
    {
        Enforce(pos <= size(), (std::out_of_range*)0, "");
        return flex_string(data() + pos, Min(n, size() - pos));
    }

    std::ptrdiff_t compare(const flex_string& str) const
    { 
        // FIX due to Goncalo N M de Carvalho July 18, 2005
        return compare(0, size(), str);
    }
    
    std::ptrdiff_t compare(size_type pos1, size_type n1,
        const flex_string& str) const
    { return compare(pos1, n1, str.data(), str.size()); }
    
    // FIX to compare: added the TC 
    // (http://www.comeaucomputing.com/iso/lwg-defects.html number 5)
    // Thanks to Caleb Epstein for the fix
    std::ptrdiff_t compare(size_type pos1, size_type n1,
        const value_type* s) const
    {
        return compare(pos1, n1, s, traits_type::length(s));
    }
    
    std::ptrdiff_t compare(size_type pos1, size_type n1,
        const value_type* s, size_type n2) const
    {
        Enforce(pos1 <= size(), (std::out_of_range*)0, "");
        Procust(n1, size() - pos1);
        const int r = traits_type::compare(pos1 + data(), s, Min(n1, n2));
        return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
    }

    std::ptrdiff_t compare(size_type pos1, size_type n1,
        const flex_string& str,
        size_type pos2, size_type n2) const
    {
        Enforce(pos2 <= str.size(), (std::out_of_range*)0, "");
        return compare(pos1, n1, str.data() + pos2, Min(n2, str.size() - pos2));
    }

    std::ptrdiff_t compare(const value_type* s) const
    { 
        // Could forward to compare(0, size(), s, traits_type::length(s)) 
        // but that does two extra checks 
        const size_type n1(size()), n2(traits_type::length(s)); 
        const int r = traits_type::compare(data(), s, Min(n1, n2)); 
        return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0; 
    }
};

// non-member functions
template <typename E, class T, class A, class S>
flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{
    flex_string<E, T, A, S> result;
    result.reserve(lhs.size() + rhs.size());
    result.append(lhs).append(rhs);
    return result;
}

template <typename E, class T, class A, class S>
flex_string<E, T, A, S> operator+(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{
    flex_string<E, T, A, S> result;
    const typename flex_string<E, T, A, S>::size_type len = 
        flex_string<E, T, A, S>::traits_type::length(lhs);
    result.reserve(len + rhs.size());
    result.append(lhs, len).append(rhs);
    return result;
}

template <typename E, class T, class A, class S>
flex_string<E, T, A, S> operator+(
    typename flex_string<E, T, A, S>::value_type lhs, 
    const flex_string<E, T, A, S>& rhs)
{
    flex_string<E, T, A, S> result;
    result.reserve(1 + rhs.size());
    result.push_back(lhs);
    result.append(rhs);
    return result;
}

template <typename E, class T, class A, class S>
flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{
    typedef typename flex_string<E, T, A, S>::size_type size_type;
    typedef typename flex_string<E, T, A, S>::traits_type traits_type;

    flex_string<E, T, A, S> result;
    const size_type len = traits_type::length(rhs);
    result.reserve(lhs.size() + len);
    result.append(lhs).append(rhs, len);
    return result;
}

template <typename E, class T, class A, class S>
flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs, 
    typename flex_string<E, T, A, S>::value_type rhs)
{
    flex_string<E, T, A, S> result;
    result.reserve(lhs.size() + 1);
    result.append(lhs);
    result.push_back(rhs);
    return result;
}

template <typename E, class T, class A, class S>
inline bool operator==(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return lhs.compare(rhs) == 0; }

template <typename E, class T, class A, class S>
inline bool operator==(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return rhs == lhs; }

template <typename E, class T, class A, class S>
inline bool operator==(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return lhs.compare(rhs) == 0; }

template <typename E, class T, class A, class S>
inline bool operator!=(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(lhs == rhs); }

template <typename E, class T, class A, class S>
inline bool operator!=(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(lhs == rhs); }

template <typename E, class T, class A, class S>
inline bool operator!=(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return !(lhs == rhs); }

template <typename E, class T, class A, class S>
inline bool operator<(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return lhs.compare(rhs) < 0; }

template <typename E, class T, class A, class S>
inline bool operator<(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return lhs.compare(rhs) < 0; }

template <typename E, class T, class A, class S>
inline bool operator<(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return rhs.compare(lhs) > 0; }

template <typename E, class T, class A, class S>
inline bool operator>(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return rhs < lhs; }

template <typename E, class T, class A, class S>
inline bool operator>(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return rhs < lhs; }

template <typename E, class T, class A, class S>
bool operator>(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return rhs < lhs; }

template <typename E, class T, class A, class S>
inline bool operator<=(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(rhs < lhs); }

template <typename E, class T, class A, class S>
inline bool operator<=(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return !(rhs < lhs); }

template <typename E, class T, class A, class S>
bool operator<=(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(rhs < lhs); }

template <typename E, class T, class A, class S>
bool operator>=(const flex_string<E, T, A, S>& lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(lhs < rhs); }

template <typename E, class T, class A, class S>
bool operator>=(const flex_string<E, T, A, S>& lhs, 
    const typename flex_string<E, T, A, S>::value_type* rhs)
{ return !(lhs < rhs); }

template <typename E, class T, class A, class S>
inline bool operator>=(const typename flex_string<E, T, A, S>::value_type* lhs, 
    const flex_string<E, T, A, S>& rhs)
{ return !(lhs < rhs); }

template <typename E, class T, class A, class S>
void swap(flex_string<E, T, A, S>& lhs, flex_string<E, T, A, S>& rhs)
{
    // subclause 21.3.7.8:
    lhs.swap(rhs);
}

template <typename E, class T, class A, class S>
inline std::basic_istream<typename flex_string<E, T, A, S>::value_type, 
    typename flex_string<E, T, A, S>::traits_type>&
operator>>(
    std::basic_istream<typename flex_string<E, T, A, S>::value_type, 
    typename flex_string<E, T, A, S>::traits_type>& is,
    flex_string<E, T, A, S>& str);

template <typename E, class T, class A, class S>
std::basic_ostream<typename flex_string<E, T, A, S>::value_type,
    typename flex_string<E, T, A, S>::traits_type>&
operator<<(
    std::basic_ostream<typename flex_string<E, T, A, S>::value_type, 
    typename flex_string<E, T, A, S>::traits_type>& os,
    const flex_string<E, T, A, S>& str)
{ return os << str.c_str(); }


// The getline below implementations are from the SGI STL (http://www.sgi.com/tech/stl/) 
// and come with the following copyright:
// 
// Permission to use, copy, modify, distribute and sell this software and its 
// documentation for any purpose is hereby granted without fee, provided that 
// the below copyright notice appears in all copies and that both the copyright 
// notice and this permission notice appear in supporting documentation. Silicon 
// Graphics makes no representations about the suitability of this software for 
// any purpose. It is provided "as is" without express or implied warranty.
// 
// Copyright (c) 1997-1999
// Silicon Graphics Computer Systems, Inc.
// 
// Copyright (c) 1994
// Hewlett-Packard Company 

template <typename E, class T, class A, class S>
std::basic_istream<typename flex_string<E, T, A, S>::value_type,
    typename flex_string<E, T, A, S>::traits_type>&
getline(
    std::basic_istream<typename flex_string<E, T, A, S>::value_type, 
        typename flex_string<E, T, A, S>::traits_type>& is,
    flex_string<E, T, A, S>& str,
    typename flex_string<E, T, A, S>::value_type delim)
{
    size_t nread = 0;
    typename std::basic_istream<typename flex_string<E, T, A, S>::value_type,
        typename flex_string<E, T, A, S>::traits_type>::sentry sentry(is, true);

    if (sentry) {
        std::basic_streambuf<typename flex_string<E, T, A, S>::value_type,
            typename flex_string<E, T, A, S>::traits_type>* buf = is.rdbuf();
        str.clear();

        while (nread < str.max_size()) {
            int c1 = buf->sbumpc();
            if (flex_string<E, T, A, S>::traits_type::eq_int_type(c1,
                flex_string<E, T, A, S>::traits_type::eof()))
            {
                is.setstate(std::ios_base::eofbit);
                break;
            }
            else {
                ++nread;
                typename flex_string<E, T, A, S>::value_type c =
                    flex_string<E, T, A, S>::traits_type::to_char_type(c1);

                if (!flex_string<E, T, A, S>::traits_type::eq(c, delim))
                    str.push_back(c);
                else
                    break;         // Character is extracted but not appended.
            }
        }
    }
    if (nread == 0 || nread >= str.max_size())
        is.setstate(std::ios_base::failbit);

    return is;
}

template <typename E, class T, class A, class S>
std::basic_istream<typename flex_string<E, T, A, S>::value_type, 
    typename flex_string<E, T, A, S>::traits_type>&
getline(
    std::basic_istream<typename flex_string<E, T, A, S>::value_type, 
        typename flex_string<E, T, A, S>::traits_type>& is,
    flex_string<E, T, A, S>& str)
{
    return getline(is, str, is.widen('\n'));
}

template <typename E1, class T, class A, class S>
const typename flex_string<E1, T, A, S>::size_type
flex_string<E1, T, A, S>::npos = (typename flex_string<E1, T, A, S>::size_type)(-1);

///////////////////////////////////////////////////////////////////////////////
}   // namespace util
}   // namespace wave
}   // namespace boost

#if BOOST_WAVE_SERIALIZATION != 0
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace serialization {

#if !defined(BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK)

// FIXME: This doesn't work because of the missing flex_string::operator>>()
template <typename E, class T, class A, class S>
struct implementation_level<boost::wave::util::flex_string<E, T, A, S> >
{
    typedef mpl::integral_c_tag tag;
    typedef mpl::int_<boost::serialization::primitive_type> type;
    BOOST_STATIC_CONSTANT(
        int,
        value = implementation_level::type::value
    );
};

#else

//  We serialize flex_strings as vectors of char's for now
template<class Archive, typename E, class T, class A, class S>
inline void save(Archive & ar, 
    boost::wave::util::flex_string<E, T, A, S> const &t,
    const unsigned int file_version)
{
    boost::serialization::stl::save_collection<
        Archive, wave::util::flex_string<E, T, A, S> >(ar, t);
}

template<class Archive, typename E, class T, class A, class S>
inline void load(Archive & ar, boost::wave::util::flex_string<E, T, A, S> &t,
    const unsigned int file_version)
{
    boost::serialization::stl::load_collection<
        Archive, boost::wave::util::flex_string<E, T, A, S>,
        boost::serialization::stl::archive_input_seq<
            Archive, boost::wave::util::flex_string<E, T, A, S> >,
        boost::serialization::stl::reserve_imp<
            boost::wave::util::flex_string<E, T, A, S> >
    >(ar, t);
}

// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive, typename E, class T, class A, class S>
inline void serialize(Archive & ar, boost::wave::util::flex_string<E, T, A, S> &t,
    const unsigned int file_version)
{
    boost::serialization::split_free(ar, t, file_version);
}

#endif

///////////////////////////////////////////////////////////////////////////////
}} // boost::serialization
#endif

// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // FLEX_STRING_INC_
