#define _CRT_SECURE_NO_WARNINGS // don't warn about strcpy in VS10
#include <cstring>
#include <iostream>
namespace my {
class string {
size_t len;
char* str;
string(char* buf, size_t buf_len)
: len(buf_len)
, str(buf)
{ }
public:
explicit string(const char* src)
: len(strlen(src))
, str(new char[len+1])
{
std::strcpy(str, src);
}
string(const string& other)
: len(other.length())
, str(new char[len+1])
{
other.copy_to(str);
}
string& operator=(const string& other)
{
if (this != &other) {
char* tmp = new char[other.len];
other.copy_to(tmp);
delete[] str;
str = tmp;
len = other.len;
}
return *this;
}
~string() { delete[] str; }
size_t length() const { return len; }
private:
void copy_to(char* buff) const { std::strcpy(buff, str); }
friend struct helper; // because you can't befriend a template
struct helper {
static void copy(const string& str, char* buf)
{
str.copy_to(buf);
}
template <class T>
static void copy(const T& t, char* buf)
{
t.copy_to(buf);
}
static string create(char* buf, size_t len)
{
return string(buf, len);
}
};
template <class T>
class concat {
const T& lhs;
const string& rhs;
//bool valid;
public:
concat(const T& left, const string& right)
: lhs(left)
, rhs(right)
//, valid(true)
{}
// ~concat() { valid = false; }
size_t length() const
{
return lhs.length() + rhs.length();
}
void copy_to(char* dest) const
{
//if (!valid)
//throw "Here there be dragons^H^H^H undefined behaviour";
helper::copy(lhs, dest);
helper::copy(rhs, dest + lhs.length());
}
operator string() const
{
char* buf = new char[length() + 1];
copy_to(buf);
return helper::create(buf, length());
}
concat<concat<T> > operator+(const string& str) const
{
return concat<concat<T> >(*this, str);
}
};
public:
concat<string> operator+(const string& str) const
{
return concat<string>(*this, str);
}
friend std::ostream& operator<<(std::ostream& os, const string& str)
{
return os << str.str;
}
};
}
int main()
{
my::string a("hello"), b(" "), c("world"), d("!");
my::string s = a + b + c + d;
std::cout << s << std::endl;
}