// TR2 -*- C++ -*- // Copyright (C) 2009-2021 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/bool_set * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_BOOL_SET #define _GLIBCXX_TR2_BOOL_SET 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * bool_set * * See N2136, Bool_set: multi-valued logic * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. * * The implicit conversion to bool is slippery! I may use the new * explicit conversion. This has been specialized in the language * so that in contexts requiring a bool the conversion happens * implicitly. Thus most objections should be eliminated. */ class bool_set { public: /// Default constructor. constexpr bool_set() : _M_b(_S_false) { } /// Constructor from bool. constexpr bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { } // I'm not sure about this. bool contains(bool_set __b) const { return this->is_singleton() && this->equals(__b); } /// Return true if states are equal. bool equals(bool_set __b) const { return __b._M_b == _M_b; } /// Return true if this is empty. bool is_emptyset() const { return _M_b == _S_empty; } /// Return true if this is indeterminate. bool is_indeterminate() const { return _M_b == _S_indet; } /// Return true if this is false or true (normal boolean). bool is_singleton() const { return _M_b == _S_false || _M_b == _S_true_; } /// Conversion to bool. //explicit operator bool() const { if (! is_singleton()) throw std::bad_cast(); return _M_b; } /// static bool_set indeterminate() { bool_set __b; __b._M_b = _S_indet; return __b; } /// static bool_set emptyset() { bool_set __b; __b._M_b = _S_empty; return __b; } friend bool_set operator!(bool_set __b) { return __b._M_not(); } friend bool_set operator^(bool_set __s, bool_set __t) { return __s._M_xor(__t); } friend bool_set operator|(bool_set __s, bool_set __t) { return __s._M_or(__t); } friend bool_set operator&(bool_set __s, bool_set __t) { return __s._M_and(__t); } friend bool_set operator==(bool_set __s, bool_set __t) { return __s._M_eq(__t); } // These overloads replace the facet additions in the paper! template friend std::basic_ostream& operator<<(std::basic_ostream& __out, bool_set __b) { int __a = __b._M_b; __out << __a; } template friend std::basic_istream& operator>>(std::basic_istream& __in, bool_set& __b) { long __c; __in >> __c; if (__c >= _S_false && __c < _S_empty) __b._M_b = static_cast<_Bool_set_val>(__c); } private: /// enum _Bool_set_val: unsigned char { _S_false = 0, _S_true_ = 1, _S_indet = 2, _S_empty = 3 }; /// Bool set state. _Bool_set_val _M_b; /// bool_set(_Bool_set_val __c) : _M_b(__c) { } /// bool_set _M_not() const { return _S_not[this->_M_b]; } /// bool_set _M_xor(bool_set __b) const { return _S_xor[this->_M_b][__b._M_b]; } /// bool_set _M_or(bool_set __b) const { return _S_or[this->_M_b][__b._M_b]; } /// bool_set _M_and(bool_set __b) const { return _S_and[this->_M_b][__b._M_b]; } /// bool_set _M_eq(bool_set __b) const { return _S_eq[this->_M_b][__b._M_b]; } /// static _Bool_set_val _S_not[4]; /// static _Bool_set_val _S_xor[4][4]; /// static _Bool_set_val _S_or[4][4]; /// static _Bool_set_val _S_and[4][4]; /// static _Bool_set_val _S_eq[4][4]; }; // 20.2.3.2 bool_set values inline bool contains(bool_set __s, bool_set __t) { return __s.contains(__t); } inline bool equals(bool_set __s, bool_set __t) { return __s.equals(__t); } inline bool is_emptyset(bool_set __b) { return __b.is_emptyset(); } inline bool is_indeterminate(bool_set __b) { return __b.is_indeterminate(); } inline bool is_singleton(bool_set __b) { return __b.is_singleton(); } inline bool certainly(bool_set __b) { return ! __b.contains(false); } inline bool possibly(bool_set __b) { return __b.contains(true); } // 20.2.3.3 bool_set set operations inline bool_set set_union(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set set_union(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set set_union(bool_set __s, bool_set __t) { return __s | __t; } inline bool_set set_intersection(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set set_intersection(bool_set __s, bool __t) { return __s & bool_set(__t); } inline bool_set set_intersection(bool_set __s, bool_set __t) { return __s & __t; } inline bool_set set_complement(bool_set __b) { return ! __b; } // 20.2.3.4 bool_set logical operators inline bool_set operator^(bool __s, bool_set __t) { return bool_set(__s) ^ __t; } inline bool_set operator^(bool_set __s, bool __t) { return __s ^ bool_set(__t); } inline bool_set operator|(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set operator|(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set operator&(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set operator&(bool_set __s, bool __t) { return __s & bool_set(__t); } // 20.2.3.5 bool_set relational operators inline bool_set operator==(bool __s, bool_set __t) { return bool_set(__s) == __t; } inline bool_set operator==(bool_set __s, bool __t) { return __s == bool_set(__t); } inline bool_set operator!=(bool __s, bool_set __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool_set __t) { return ! (__s == __t); } } _GLIBCXX_END_NAMESPACE_VERSION } #include #endif // _GLIBCXX_TR2_BOOL_SET