// ConstSting
// Copyright 1998 by Kevin Atkinson under the terms of the LGPL

#ifndef __ConstString_hh__
#define __ConstString_hh__

#include <cstring>

namespace autil {

  //: A special string that is created from a existing const char *
  // It contains a small subset of the standard string class.  When an
  // object is created only a link to the const char * is created.  The
  // data is NOT copied.  thus the const char * needs to stick around
  // for the life of the class.
  class ConstString {
  private:
    const char *str_data; 
  public:
    typedef const char   value_type;      //:
    typedef unsigned int size_type;       //:
    typedef          int difference_type; //:

    typedef const char&     const_reference; //:
    typedef const_reference reference;       //:
    typedef const char*     const_pointer;   //:
    typedef const_pointer   pointer;         //:

    typedef const char*    const_iterator;   //:
    typedef const_iterator iterator;         
    //: The same as const_iterator because the data can not be changed.

    ConstString() : str_data("") {}                 //:
    ConstString(const char *str) : str_data(str) {} //:
    ConstString& operator= (const char *str)       //:
    {str_data = str; return *this;}

    size_type size() const //: 
    { 
      return strlen(str_data);
    }
  
    bool empty() const //:
    {return !str_data[0];}

    void resize(size_type i) //:
    {if (i == 0) str_data=""; else abort();}

    const_iterator      begin() const {return str_data;}          //:
    const_iterator      end()   const {return str_data + size();} //:

    size_type length() const {return size();}   //:
    size_type max_size() const {return size();} //:
  
    const_reference operator[](size_type pos) const {return str_data[pos];} //:
    const_reference at(size_type pos) const //: 
    {
      return str_data[pos];
    }

    operator const char * () const {return str_data;} //:
    const char* c_str() const {return str_data;}      //:
    const char* data()  const {return str_data;}      //:
  
    int compare(ConstString str) const //:
    {
      return strcmp(str_data, str.str_data);
    }
  };


  //! with_class = ConstString

  //:
  inline int compare (ConstString lhs, ConstString rhs) {
    return lhs.compare(rhs);
  }

  //:
  inline int compare (ConstString lhs, const char *rhs) {
    return lhs.compare(rhs);
  }

  //:
  inline int compare (const char *lhs, ConstString rhs) {
    return static_cast<const ConstString>(lhs).compare(rhs);
  }

#define CS_COMPARE(OP, LHS, RHS) \
  inline bool operator OP (RHS lhs, LHS rhs) \
   {return compare(lhs,rhs) OP 0;}

#define CS_COMPARES(OP) \
  CS_COMPARE(OP, ConstString, ConstString) \
  CS_COMPARE(OP, const char *, ConstString) \
  CS_COMPARE(OP, ConstString, const char *) \
  
  CS_COMPARES(==)
  CS_COMPARES(!=)
  CS_COMPARES(<)
  CS_COMPARES(<=)
  CS_COMPARES(>)
  CS_COMPARES(>=)

}

#undef CS_COMPARES
#undef CS_COMPARE

#endif

  
 
  
  
  
