//////////////////////////////////////////////////////////////////////////// // // multivalue.h マルチヴァリュー // // programmed by Robert (2002/06/10) // #ifndef ___MULTIVALUE_H__200206100256__INCLUDED___ #define ___MULTIVALUE_H__200206100256__INCLUDED___ /* マルチヴァリューを扱うためのテンプレートです 普通の値であれば inline 展開により十分高速なコードが生成されます 使用例) Type2 hoge() { return Value2(1, 2); } hoge() >> a >> b; // >> 演算子で取り出します cout << a << ":" << b << endl; // 1:2 と出力されます Type2 sage() { // リテラル文字列は暗黙では char* になります return Value2("sage", true); } if(sage() >> s >> mvget) // mlget を使うと変数に保存せずに使えます cout << s << endl; Type3 age(Value3(7, 8, 9)); // 普通の変数としても使えます age >> a >> b; // 別に3つの値全てを取り出す必要はありません cout << a << ":" << b << endl; age = Value3(5, 6, 7); age >> mvskip >> b; // 2番目の値だけを取得します age >> b; cout << b << endl; age = koge(); // 戻り値の型は Type3 です age >> a >> b >> c; cout << a << b << c << endl; */ /* スキップ用クラス foo() >> mvskip >> a; の様に使えます mvskip の部分の値は別変数に保存されないまま飛ばされます 定数はデフォルトでファイルスコープを持つので、 リンクでの二重定義エラーは出ません */ const class MultivalueSkip { } mvskip; /* 途中での値取得用クラス foo() >> str >> mvget; の様に使えます mvget の部分の値が >> 演算子の戻り値になります 定数はデフォルトでファイルスコープを持つので、 リンクでの二重定義エラーは出ません */ const class MultivalueGet { } mvget; /* 複数の値を保持するためのクラス 値を保持して、>> 演算子を使って値を取り出します 通常、Value 系関数テンプレートを通じて構築します >> 演算子の引数で必然的に t_value1& という型を使うので、 テンプレート引数は参照型にはできません */ // 1つの値用のマルチ(?)ヴァリュークラステンプレート template class Type1 { private: t_value1 m_value1; // 保持する値 public: explicit Type1(t_value1& value1) : m_value1(value1) { } Type1() { } void operator>>(t_value1& value1) const // 値の代入 { value1 = m_value1; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // 2つの値用のマルチヴァリュークラステンプレート template class Type2 { private: typedef Type1 multi_t; t_value1 m_value1; multi_t m_multi; public: Type2(t_value1& value1, t_value2& value2) : m_value1(value1), m_multi(value2) { } Type2() { } const multi_t& operator>>(t_value1& value1) const // 値の代入(const) { value1 = m_value1; return m_multi; } multi_t& operator>>(t_value1& value1) // 値の代入 { value1 = m_value1; return m_multi; } const multi_t& operator>>(MultivalueSkip) const // 値のスキップ(const) { return m_multi; } multi_t& operator>>(MultivalueSkip) // 値のスキップ { return m_multi; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // 3つの値用のマルチヴァリュークラステンプレート template class Type3 { private: typedef Type2 multi_t; t_value1 m_value1; multi_t m_multi; public: Type3(t_value1& value1, t_value2& value2, t_value3& value3) : m_value1(value1), m_multi(value2, value3) { } Type3() { } const multi_t& operator>>(t_value1& value1) const // 値の代入(const) { value1 = m_value1; return m_multi; } multi_t& operator>>(t_value1& value1) // 値の代入 { value1 = m_value1; return m_multi; } const multi_t& operator>>(MultivalueSkip) const // 値のスキップ(const) { return m_multi; } multi_t& operator>>(MultivalueSkip) // 値のスキップ { return m_multi; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // 4つの値用のマルチヴァリュークラステンプレート template class Type4 { private: typedef Type3 multi_t; t_value1 m_value1; multi_t m_multi; public: Type4(t_value1& value1, t_value2& value2, t_value3& value3, t_value4& value4) : m_value1(value1), m_multi(value2, value3, value4) { } Type4() { } const multi_t& operator>>(t_value1& value1) const // 値の代入(const) { value1 = m_value1; return m_multi; } multi_t& operator>>(t_value1& value1) // 値の代入 { value1 = m_value1; return m_multi; } const multi_t& operator>>(MultivalueSkip) const // 値のスキップ(const) { return m_multi; } multi_t& operator>>(MultivalueSkip) // 値のスキップ { return m_multi; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // 5つの値用のマルチヴァリュークラステンプレート template class Type5 { private: typedef Type4 multi_t; t_value1 m_value1; multi_t m_multi; public: Type5(t_value1& value1, t_value2& value2, t_value3& value3, t_value4& value4, t_value5& value5) : m_value1(value1), m_multi(value2, value3, value4, value5) { } Type5() { } const multi_t& operator>>(t_value1& value1) const // 値の代入(const) { value1 = m_value1; return m_multi; } multi_t& operator>>(t_value1& value1) // 値の代入 { value1 = m_value1; return m_multi; } const multi_t& operator>>(MultivalueSkip) const // 値のスキップ(const) { return m_multi; } multi_t& operator>>(MultivalueSkip) // 値のスキップ { return m_multi; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // 6つの値用のマルチヴァリュークラステンプレート template class Type6 { private: typedef Type5 multi_t; t_value1 m_value1; multi_t m_multi; public: Type6(t_value1& value1, t_value2& value2, t_value3& value3, t_value4& value4, t_value5& value5, t_value6& value6) : m_value1(value1), m_multi(value2, value3, value4, value5, value6) { } Type6() { } const multi_t& operator>>(t_value1& value1) const // 値の代入(const) { value1 = m_value1; return m_multi; } multi_t& operator>>(t_value1& value1) // 値の代入 { value1 = m_value1; return m_multi; } const multi_t& operator>>(MultivalueSkip) const // 値のスキップ(const) { return m_multi; } multi_t& operator>>(MultivalueSkip) // 値のスキップ { return m_multi; } t_value1 operator>>(MultivalueGet) const // 値の取得 { return m_value1; } }; // これ以上は必要になったときに各自増やしてください // 意外と簡単に増やせます // 1つの値用のマルチ(?)ヴァリューオブジェクトを返します template inline Type1 Value1(t_value1 value1) { return Type1 (value1); } // 2つの値用のマルチヴァリューオブジェクトを返します template inline Type2 Value2(t_value1 value1, t_value2 value2) { return Type2 (value1, value2); } // 3つの値用のマルチヴァリューオブジェクトを返します template inline Type3 Value3(t_value1 value1, t_value2 value2, t_value3 value3) { return Type3 (value1, value2, value3); } // 4つの値用のマルチヴァリューオブジェクトを返します template inline Type4 Value4(t_value1 value1, t_value2 value2, t_value3 value3, t_value4 value4) { return Type4 (value1, value2, value3, value4); } // 5つの値用のマルチヴァリューオブジェクトを返します template inline Type5 Value5(t_value1 value1, t_value2 value2, t_value3 value3, t_value4 value4, t_value5 value5) { return Type5 (value1, value2, value3, value4, value5); } // 6つの値用のマルチヴァリューオブジェクトを返します template inline Type6 Value6(t_value1 value1, t_value2 value2, t_value3 value3, t_value4 value4, t_value5 value5, t_value6 value6) { return Type6 (value1, value2, value3, value4, value5, value6); } // これ以上は必要になったときに各自増やしてください #endif // #ifndef ___MULTIVALUE_H__200206100256__INCLUDED___