/****************************************************************************** 三態 bool 三態 bool モジュールヘッダファイル Coded by Wraith in May 8, 2004. ******************************************************************************/ /////////////////////////////////////////////////////////////////////////////// // // ■ boolean.h // http://tricklib.com/cxx/ex/boolean/boolean.h // // □ 関連ファイル // ありません。 // // □ リファレンス・サポートページ // http://tricklib.com/cxx/ex/boolean/ // // □ ライセンス情報 // http://tricklib.com/license.htm // #ifndef TRICKLIB_BOOLEAN_H #define TRICKLIB_BOOLEAN_H /////////////////////////////////////////////////////////////////////////////// // // オプションマクロ定義 // // // ☆名前空間指定マクロ // // このモジュールが展開される名前空間を変更できます。 // // コンパイル時に指定するのが面倒な場合は以下のコメント行の名前空間をご希望の // 名前空間に修正した上で(コメントを解除して)有効にしてください。 // //#define TRICKLIB_BOOLEAN_NAMESPACE tricklib #if !defined(TRICKLIB_BOOLEAN_NAMESPACE) #define TRICKLIB_BOOLEAN_NAMESPACE tricklib #endif // // ☆例外有効化指定マクロ // // このマクロを指定すると null 値を保持している三態 bool が組み込み bool と // して評価された際に例外が投げられます。このマクロが指定されていない場合、 // false の値を持つ組み込み bool として評価されます。 // // コンパイル時に指定するのが面倒な場合は以下のコメント行を(コメントを解除 // して)有効にしてください。 // //#define TRICKLIB_BOOLEAN_WITH_EXCEPTION #if !defined(TRICKLIB_BOOLEAN_WITH_EXCEPTION) #if defined(TRICKLIB_BOOLEAN_EXCEPTION_OBJECT) #define TRICKLIB_BOOLEAN_WITH_EXCEPTION #endif #endif // // ☆例外オブジェクト指定マクロ // // このマクロを指定すると null 値を保持している三態 bool が組み込み bool と // して評価された際に例外が投げられます。このマクロが指定されていない場合、 // false の値を持つ組み込み bool として評価されます。 // // コンパイル時に指定するのが面倒な場合は以下のコメント行を(コメントを解除 // して)有効にしてください。 // //#define TRICKLIB_BOOLEAN_EXCEPTION_OBJECT #if !defined(TRICKLIB_BOOLEAN_EXCEPTION_OBJECT) #if defined(TRICKLIB_BOOLEAN_WITH_EXCEPTION) #if !defined(__DMC__) /////////////////////////////////////////////////////////////////////////////// // // include // #include #endif #endif #endif /////////////////////////////////////////////////////////////////////////////// // // ... // namespace TRICKLIB_BOOLEAN_NAMESPACE { #if !defined(TRICKLIB_BOOLEAN_EXCEPTION_OBJECT) #if defined(TRICKLIB_BOOLEAN_WITH_EXCEPTION) /////////////////////////////////////////////////////////////////////////////// // // ■三態 bool 例外クラス // #define TRICKLIB_BOOLEAN_EXCEPTION_OBJECT TRICKLIB_BOOLEAN_NAMESPACE::evaluate_null() #if !defined(__DMC__) class evaluate_null :public std::range_error { public: evaluate_null() :std::range_error("Evaluate null at nullable_bool.") { } }; #else class evaluate_null { public: evaluate_null() { } }; #endif #endif #endif /////////////////////////////////////////////////////////////////////////////// // // ■三態 bool クラス // class nullable_bool { enum value_type { null_value = -1, false_value = 0, // == (int)false true_value = 1, // == (int)true }; static value_type translate(bool X) { return (value_type)(int)X; // return X? true_value: false_value; } value_type value; public: typedef nullable_bool this_type; bool is_null() const { return null_value == value; } bool is_not_null() const { return !is_null(); } bool is_true() const { return !is_not_true(); } bool is_not_true() const { // ※ null_value, false_value 以外の値は true_value と見なす。 return is_null() || is_false(); } bool is_false() const { return false_value == value; } bool is_not_false() const { return !is_false(); } bool is_equal(const this_type &a) const { if (is_true()) { return is_true(); } else { return value == a.value; } } bool is_not_equal(const this_type &a) const { if (is_true()) { return !is_true(); } else { return value != a.value; } } this_type & set_null() { value = null_value; return *this; } nullable_bool() :value(null_value) { } nullable_bool(bool X_value) :value(translate(X_value)) { } nullable_bool(const this_type &X) :value(X.value) { } operator bool () const { #ifdef TRICKLIB_BOOLEAN_WITH_EXCEPTION if (is_null()) { throw TRICKLIB_BOOLEAN_EXCEPTION_OBJECT; } #endif return true_value == value; } this_type operator ! () const { return is_null() ? *this: this_type(false_value == value); } this_type & operator=(bool X_value) { value = translate(X_value); return *this; } this_type & operator=(const this_type &X) { value = X.value; return *this; } this_type & operator|=(bool X) { return *this = *this |X; } this_type & operator|=(const this_type &X) { return *this = *this |X; } this_type & operator&=(bool X) { return *this = *this &X; } this_type & operator&=(const this_type &X) { return *this = *this &X; } this_type & operator^=(bool X) { return *this = *this ^X; } this_type & operator^=(const this_type &X) { return *this = *this ^X; } static this_type get_null() { return nullable_bool(); } #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4927 ) #endif friend inline const nullable_bool operator==(const nullable_bool &A, const nullable_bool &B) { if (nullable_bool::null_value == (A.value |B.value)) { return nullable_bool::get_null(); } else { return nullable_bool(A.value == B.value); } } friend inline const nullable_bool operator==(const nullable_bool &A, const bool &B) { if (A.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(A.value == nullable_bool::translate(B)); } } friend inline const nullable_bool operator==(const bool &A, const nullable_bool &B) { if (B.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(nullable_bool::translate(A) == B.value); } } friend inline const nullable_bool operator!=(const nullable_bool &A, const nullable_bool &B) { if (nullable_bool::null_value == (A.value |B.value)) { return nullable_bool::get_null(); } else { return nullable_bool(A.value != B.value); } } friend inline const nullable_bool operator!=(const nullable_bool &A, const bool &B) { if (A.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(A.value != nullable_bool::translate(B)); } } friend inline const nullable_bool operator!=(const bool &A, const nullable_bool &B) { if (B.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(nullable_bool::translate(A) != B.value); } } friend inline const nullable_bool operator|(const nullable_bool &A, const nullable_bool &B) { if (nullable_bool::null_value == (A.value |B.value)) { return nullable_bool::get_null(); } else { return nullable_bool(A.value |B.value); } } friend inline const nullable_bool operator|(const nullable_bool &A, const bool &B) { if (A.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(A.value |nullable_bool::translate(B)); } } friend inline const nullable_bool operator|(const bool &A, const nullable_bool &B) { if (B.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(nullable_bool::translate(A) |B.value); } } friend inline const nullable_bool operator&(const nullable_bool &A, const nullable_bool &B) { if (nullable_bool::null_value == (A.value |B.value)) { return nullable_bool::get_null(); } else { return nullable_bool(A.value &B.value); } } friend inline const nullable_bool operator&(const nullable_bool &A, const bool &B) { if (A.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(A.value &nullable_bool::translate(B)); } } friend inline const nullable_bool operator&(const bool &A, const nullable_bool &B) { if (B.is_null()) { return nullable_bool::get_null(); } else { return nullable_bool(nullable_bool::translate(A) &B.value); } } friend inline const nullable_bool operator^(const nullable_bool &A, const nullable_bool &B) { return A != B; } friend inline const nullable_bool operator^(const nullable_bool &A, const bool &B) { return A != B; } friend inline const nullable_bool operator^(const bool &A, const nullable_bool &B) { return A != B; } #ifdef _MSC_VER #pragma warning( pop ) #endif }; // 三態 bool 補助関数 inline const bool nullable_bool_is_null(const nullable_bool &X) { return X.is_null(); } inline const bool nullable_bool_is_null(const bool &) { return false; } inline const bool nullable_bool_is_not_null(const nullable_bool &X) { return X.is_not_null(); } inline const bool nullable_bool_is_not_null(const bool &) { return true; } inline const bool nullable_bool_is_true(const nullable_bool &X) { return X.is_true(); } inline const bool nullable_bool_is_true(const bool &X) { return X; } inline const bool nullable_bool_is_not_true(const nullable_bool &X) { return X.is_not_true(); } inline const bool nullable_bool_is_not_true(const bool &X) { return !X; } inline const bool nullable_bool_is_false(const nullable_bool &X) { return X.is_false(); } inline const bool nullable_bool_is_false(const bool &X) { return !X; } inline const bool nullable_bool_is_not_false(const nullable_bool &X) { return X.is_not_false(); } inline const bool nullable_bool_is_not_false(const bool &X) { return X; } /////////////////////////////////////////////////////////////////////////////// // // ... // } #endif // TRICKLIB_BOOLEAN_H /****************************************************************************** □■□■ Wraith the Trickster □■□■ ■□■□ 〜I'll go with heaven's advantage and fool's wisdom.〜 ■□■□ ******************************************************************************/