| // TR2 <bool_set> -*- C++ -*- | |
| // Copyright (C) 2009-2025 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 | |
| // <http://www.gnu.org/licenses/>. | |
| /** @file tr2/bool_set | |
| * This is a TR2 C++ Library header. | |
| */ | |
| #ifndef _GLIBCXX_TR2_BOOL_SET | |
| #define _GLIBCXX_TR2_BOOL_SET 1 | |
| #ifdef _GLIBCXX_SYSHDR | |
| #pragma GCC system_header | |
| #endif | |
| #include <typeinfo> | |
| #include <iostream> | |
| 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<typename CharT, typename Traits> | |
| friend std::basic_ostream<CharT, Traits>& | |
| operator<<(std::basic_ostream<CharT, Traits>& __out, bool_set __b) | |
| { | |
| int __a = __b._M_b; | |
| __out << __a; | |
| } | |
| template<typename CharT, typename Traits> | |
| friend std::basic_istream<CharT, Traits>& | |
| operator>>(std::basic_istream<CharT, Traits>& __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 <tr2/bool_set.tcc> | |
| #endif // _GLIBCXX_TR2_BOOL_SET |