#include <string>
#include <vector>
#include <locale>
#include <iostream>
#include <cmath>
#include <cstdlib>

class StringTokenizer : public std::vector<std::string>
{
  public:
    StringTokenizer ( const std::string &rStr, const std::string &rDelimiters = " ,\n\t\r" );
    static std::string& toupper ( std::string& s );
    static std::string&  tolower ( std::string& s );
};

inline StringTokenizer::StringTokenizer ( const std::string &rStr, const std::string &rDelimiters )
{
  std::string::size_type lastPos ( rStr.find_first_not_of ( rDelimiters, 0 ) );
  std::string::size_type pos ( rStr.find_first_of ( rDelimiters, lastPos ) );
  while ( std::string::npos != pos || std::string::npos != lastPos )
  {
    push_back ( rStr.substr ( lastPos, pos - lastPos ) );
    lastPos = rStr.find_first_not_of ( rDelimiters, pos );
    pos = rStr.find_first_of ( rDelimiters, lastPos );
  }
}

class TokByString : public std::vector <std::string>
{
  public:
    TokByString ( const std::string& rStr, const std::string& rDelimiters = "\n" );

};

inline TokByString::TokByString ( const std::string& rStr, const std::string& rDelimiters )
{
  std::string::size_type last ( rStr.find ( rDelimiters,0 ) );

  std::string::size_type first=0;
  while ( last != std::string::npos )
  {
    push_back ( rStr.substr ( first, last-first ) );
    first=last+rDelimiters.size();
    last =rStr.find ( rDelimiters,first );
  }


}

inline std::string& StringTokenizer::toupper ( std::string& s )
{
  ;
  std::string::iterator it;
  for ( it=s.begin();it!=s.end();it++ )
  {
    ( *it ) =std::toupper ( *it,std::cout.getloc() );
  }

  return s;
}


inline std::string& StringTokenizer::tolower ( std::string& s )
{

  std::string::iterator it;
  for ( it=s.begin();it!=s.end();it++ )
  {
    ( *it ) =std::tolower ( *it,std::cout.getloc() );
  }

  return s;
}

namespace strtools
{
  inline double atof ( std::string& s )
  {
    StringTokenizer tok ( s,"DE" );
    double mantisa=std::atof ( tok[0].c_str() );
    if ( tok.size() > 1 )
      mantisa*=pow ( ( double ) 10.0,std::atoi ( tok[1].c_str() ) );
    return mantisa;
  }



  inline void remove_character ( char ch, std::string& s )
  {
    size_t pos = 0;

    while ( true )
    {

      pos = s.find ( ch, pos );

      // check if there are no more ch in str

      if ( pos == std::string::npos ) break;

      s.replace ( pos, 1, "" );

    }
  }
  inline std::string& remove_numbers ( std::string& s )
  {
    char numbers[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    for ( int i=0;i<10;i++ )
      remove_character ( numbers[i],s );

    return s;
  }

  inline bool isinteger ( const std::string& s )
  {
    if ( s.find_first_not_of ( "0123456789" ) !=std::string::npos ) return false;
    return true;

  }

  inline bool isnum ( const std::string& snumber )
  {
    return ( snumber.find_first_not_of ( "0123456789.,-+eEdD" ) == std::string::npos );
  }

}
