Immutable を利用した Substring

もし Immutable な文字列クラスを作った場合、文字列の一部を切り出すときもわざわざ新しくメモリを確保しなくても取り出すことが出来るような気がしてきた。

/* final */ class string
{
private:
    const boost::shared_ptr<wchar_t> str_;
    const int first_;
    const int length_;

    string(boost::shared_ptr<wchar_t> str, int first, int length)
        : str_(str), first_(first), length_(length)
    {
    }

public:
    string substr(int index) const
    {
        // ほんとはここにエラーチェックが入る
        return string(str_, first_ + index, length_ - index);
    }

    string substr(int index, int count) const
    {
        // ほんとはここにエラーチェックが入る
        return string(str_, first_ + index, std::min(length_ - index, count));
    }
};

ただし、普通の Immutable な string を実装するなら first_ は必要ないので、代入とかするたびに first_ をコピーする文だけ余分に時間が掛かるのが問題かも。
とりあえずこの方向で Immutable な string クラスを作ってみようかな。
……でも絶対誰かが既に実装してるんだろうなぁ……。


ちなみに↑の例では共有される文字列として boost::shared_ptr を使ってるけど、これは無駄な領域が多いので実際は専用のクラスで管理した方がいい。
無駄な領域というのは例えば weak_ptr のためのカウンタだったり、文字列用のメモリと参照カウント用のメモリが別だったりとかそういう部分。
それを IUnknown の実装クラスみたいな、オブジェクトと参照カウンタが一体になったクラスを作れば無駄な領域は発生しない。
もちろんスレッドセーフにするためには参照カウントのインクリメント・デクリメントをうまくやる必要があるんだろうけど、それは boost/detail/interlocked.hpp にある BOOST_INTERLOCKED_INCREMENT 辺りを使えば何とかなりそう。