//  (C) Copyright Gennadiy Rozental 2001-2008.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at 
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 49313 $
//
//  Description : simple string class definition
// ***************************************************************************

#ifndef  CONST_STRING_HPP
#define  CONST_STRING_HPP

// STL
#include <iterator>
#include <string>
#include <cstring>
using std::string;

namespace common_layer {

// ************************************************************************** //
// **************                 const_string                 ************** //
// ************************************************************************** //

class const_string {
public:
    // Subtypes
    typedef     char const*                     iterator;
    typedef     char const*                     const_iterator;
    typedef     std::reverse_iterator<iterator> reverse_iterator;
    typedef     reverse_iterator                const_reverse_iterator;

    // Constructor
    const_string()
    : m_begin( "" ), m_end( m_begin )                      {}

    // Copy constructor is generated by compiler

    const_string( const std::string& s )
    : m_begin( s.c_str() ),
      m_end( m_begin + s.length() )                        {}

    const_string( char const* s )
    : m_begin( s ? s : "" )
    , m_end( s ? m_begin + std::strlen( s ) : m_begin )
    {}

    const_string( char const* s, size_t length )
    : m_begin( s ), m_end( m_begin + length )              { if( length == 0 ) erase(); }

    const_string( char const* first, char const* last )
    : m_begin( first ), m_end( last )                      {}

    // data access methods
    char            operator[]( size_t index ) const        { return m_begin[index]; }
    char            at( size_t index ) const                { return m_begin[index]; }

    char const*     data() const                            { return m_begin; }

    // length operators
    size_t          length() const                          { return m_end - m_begin; }
    bool            is_empty() const                        { return m_end == m_begin; }

    void            erase()                                 { m_begin = m_end = ""; }
    void            resize( size_t new_len )                { if( m_begin + new_len < m_end ) m_end = m_begin + new_len; }
    void            rshorten( size_t shift = 1 )            { m_end  -= shift; if( m_end <= m_begin ) erase(); }
    void            lshorten( size_t shift = 1 )            { m_begin += shift; if( m_end <= m_begin ) erase(); }

    // Assignment operators
    const_string&   operator=( const_string const& s );
    const_string&   operator=( string const& s )            { return *this = const_string( s ); }
    const_string&   operator=( char const* s )              { return *this = const_string( s ); }

    const_string&   assign( const_string const& s )         { return *this = s; }
    const_string&   assign( string const& s, size_t len )   { return *this = const_string( s.data(), len ); }
    const_string&   assign( string const& s )               { return *this = const_string( s ); }
    const_string&   assign( char const* s )                 { return *this = const_string( s ); }
    const_string&   assign( char const* s, size_t len )     { return *this = const_string( s, len ); }
    const_string&   assign( char const* f, char const* l )  { return *this = const_string( f, l ); }

    void            swap( const_string& s )                 {
       // do not want to include alogrithm
        char const* tmp1 = m_begin;
        char const* tmp2 = m_end;

        m_begin     = s.m_begin;
        m_end       = s.m_end;

        s.m_begin   = tmp1;
        s.m_end     = tmp2;
    }

    // Comparison operators
    friend bool     operator==( const_string const& s1, const_string const& s2 )
    {
         return s1.length() == s2.length() && std::strncmp( s1.data(), s2.data(), s1.length() ) == 0;
    }
    friend bool     operator==( const_string const& s1, char const* s2 )            { return s1 == const_string( s2 ); }
    friend bool     operator==( const_string const& s1, const string& s2 )          { return s1 == const_string( s2 ); }

    friend bool     operator!=( const_string const& s1, const_string const& s2 )    { return !(s1 == s2); }
    friend bool     operator!=( const_string const& s1, char const* s2 )            { return !(s1 == s2); }
    friend bool     operator!=( const_string const& s1, const string& s2 )          { return !(s1 == s2); }

    friend bool     operator==( char const* s2,         const_string const& s1 )    { return s1 == s2; }
    friend bool     operator==( const string& s2,       const_string const& s1 )    { return s1 == s2; }

    friend bool     operator!=( char const* s2,         const_string const& s1 )    { return !(s1 == s2); }
    friend bool     operator!=( const string& s2,       const_string const& s1 )    { return !(s1 == s2); }

    // Iterators
    iterator        begin() const                           { return m_begin; }
    iterator        end() const                             { return m_end;   }
    reverse_iterator rbegin() const                         { return reverse_iterator( m_end );   }
    reverse_iterator rend() const                           { return reverse_iterator( m_begin ); }

private:

    // Data members
    char const*     m_begin;
    char const*     m_end;
};

//____________________________________________________________________________//

// first character
class first_char {
public:
    char operator()( const_string source, char default_char = '\0' ) const {
        return source.is_empty() ? default_char : *source.data();
    }
};

//____________________________________________________________________________//

// last character
class last_char {
public:
    char operator()( const_string source, char default_char = '\0' ) const {
        return source.is_empty() ? default_char : *source.rbegin();
    }
};

//____________________________________________________________________________//

inline const_string&
const_string::operator=( const_string const& s ) {
    if( &s != this ) {
        m_begin = s.m_begin;
        m_end  = s.m_end;
    }

    return *this;
}

//____________________________________________________________________________//

typedef const_string const literal;

//____________________________________________________________________________//

inline std::ostream&
operator<<( std::ostream& os, const_string const& str )
{
    os << std::string( str.begin(), str.length() );

    return os;
}

//____________________________________________________________________________//

}; // namespace common_layer

#endif // CONST_STRING_HPP
