/*
  AnsiString.h
  C++Builder の AnsiStringの一部のメソッドの実装
  コピーを頻繁に行なうため、効率は良くない
 */

#include "stdio.h"
#include "stdlib.h"

inline int mylog10(double d) {
    int c=0;
    while(d>=10) {
	d/=10;
	c++;
    }
    return c;
}

class AnsiString {
private:
    char* cstr;
    int len;
public:
    char* c_str() const {
      return cstr;
    }

    int Length() const {
	return len;
    }
    
    AnsiString() {
	cstr = new char[1];
	cstr[0]='\0';
	len = 1;
    }

   AnsiString(const char *str) {
	len = strlen(str);
	cstr = new char[len+1];
	strcpy(cstr, str);
    }
    
    AnsiString(const AnsiString& str) {
	len = str.Length();
	cstr = new char[len+1];
	strcpy(cstr, str.c_str());
    }

    AnsiString(const int src) {
	len = mylog10((double)src)+1;
	cstr = new char[len+1];
	sprintf(cstr, "%d", src);
    }

    AnsiString(const double src) {
	len = mylog10(src)+1+1+6;
	cstr = new char[len+1];
	sprintf(cstr, "%lf", src);
	len = strlen(cstr);
    }

    ~AnsiString() {
	delete[] cstr;
    }

    char& operator[] (const int idx) {
	return cstr[idx+1];
    }

    AnsiString& operator= (const AnsiString& rhs) {
	delete[] cstr;
	len = rhs.Length();
	cstr = new char[len+1];
	strcpy(cstr, rhs.c_str());
	return *this;
    }

    AnsiString& operator+= (const AnsiString& rhs) {
	int len2 = rhs.Length();
	len+=len2;
	char* old = cstr;
	cstr = new char[len+1];
	sprintf(cstr, "%s%s", old, rhs.c_str());
	return *this;
    }
    
    AnsiString operator+ (const AnsiString& rhs) const {
	AnsiString ret(*this);	// コピー作成
	ret += rhs;
	return ret;
    }

    friend AnsiString operator+(const char* lhs, const AnsiString& rhs);

    int ToInt() const {
	return atoi(cstr);
    }

    int ToIntDef(int def) const {
	char* endp;
	long ret;
	ret = strtol(cstr, &endp, 0);
	if (endp==cstr) {
	    return def;
	} else {
	    return (int)ret;
	}
    }

    double ToDouble() const {
	return atof(cstr);
    }
};

inline AnsiString operator+(const char* lhs, const AnsiString& rhs) {
    AnsiString ret(lhs);	//コピー作成
    ret += rhs;
    return ret;
}

inline int StrToInt(const AnsiString s) {
    return s.ToInt();
}

inline int StrToIntDef(const AnsiString s, int def) {
    return s.ToIntDef(def);
}

inline double StrToFloat(const AnsiString s) {
    return s.ToDouble();
}

inline AnsiString IntToStr(int i) {
    return AnsiString(i);
}

inline AnsiString FloatToStr(double d) {
    return AnsiString(d);
}
