#include <stdio.h>

///////////////////////////////////////////////////////////////////////////////
//
//  SolidSequence 用の抽象クラス

template<typename T>
class ASolidSequence {
public:
  virtual ~ASolidSequence(){};
  virtual const T *get() const = 0;
  virtual int getLength() const = 0;
  virtual int getMaxLength() const = 0;
};

///////////////////////////////////////////////////////////////////////////////
//
//  SolidSequence

template<typename T, int MaxLen>
class SolidSequence : public ASolidSequence<T> {

#define ThisType  SolidSequence<T, MaxLen>
#define SuperType ASolidSequence<T>

  T buffer_[MaxLen+1];
  int length_;

public:
  //===========================================================================
  SolidSequence () {
    buffer_[0] = (T)0;
    length_ = 0;
  }

  //===========================================================================
  SolidSequence (const T *in, int len=-1) {
    set(in, len);
  }

  //===========================================================================
  SolidSequence (const SuperType &in) {
    set(in);
  }

  //===========================================================================
  ~SolidSequence () {}

  //===========================================================================
  // 文字列を追加
  ThisType &append (const T *in, int len=-1) {
    int i;

    if (!in) return *this;

    if (len<0) for (len=0; in[len]; ++len);

    for (i=0; i<len && i<(MaxLen-length_); ++i)
      buffer_[length_ + i] = in[i];
    buffer_[length_ + i] = (T)0;
    length_ += i;

    return *this;
  }

  //===========================================================================
  ThisType &append (const SuperType &in) {
    return append(in.get(), in.getLength());
  }

  //===========================================================================
  // 文字列を設定
  ThisType &set (const T *in, int len=-1) {
    length_ = 0;
    return append (in, len);
  }

  //===========================================================================
  ThisType &set (const SuperType &in) {
    length_ = 0;
    return append (in);
  }

  //===========================================================================
  // 文字列バッファを取得 (override)
  const T *get () const {
    return buffer_;
  }

  //===========================================================================
  // 文字列の長さを取得 (override)
  int getLength () const {
    return length_;
  }

  //===========================================================================
  // インスタンスが保持できる文字列の最大長を取得 (override)
  int getMaxLength () const {
    return MaxLen;
  }

  //===========================================================================
  // 代入演算子 ( const T *in は NULL 終端でなければならない )
  ThisType &operator = (const T *in)         { return set(in); }
  ThisType &operator = (const SuperType &in) { return set(in); }
  // 連結演算子
  ThisType &operator += (const T *in)         { return append(in); }
  ThisType &operator += (const SuperType &in) { return append(in); }
  // 連結演算子
  ThisType operator + (const T *in) const {
    ThisType temp = *this;
    temp.append(in);
    return temp;
  }
  ThisType operator + (const SuperType &in) const {
    ThisType temp = *this;
    temp.append(in);
    return temp;
  }

#undef ThisType
#undef SuperType

};


///////////////////////////////////////////////////////////////////////////////
//
//  Rebinder

template<int MaxLen>
struct Solid {
  typedef SolidSequence<char, MaxLen> String;
};

typedef SolidSequence<char, 64> SolidString;


///////////////////////////////////////////////////////////////////////////////
int main () {
  Solid<22>::String str1, str2;
  Solid<17>::String str3, str4;

  str1 = "Me is ";
  str2 = "da big ";
  str3 = "BaCA ";
  str4 = "man, gehehe.";

  str1 += str2 + str3 + str4;

  puts (str1.get());

  puts ( (SolidString("Gehehe, ") + str1).get() );

  return 0;
}

