1*38fd1498Szrj// TR2 <bool_set> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2009-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file tr2/bool_set 26*38fd1498Szrj * This is a TR2 C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_TR2_BOOL_SET 30*38fd1498Szrj#define _GLIBCXX_TR2_BOOL_SET 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#include <typeinfo> 35*38fd1498Szrj#include <iostream> 36*38fd1498Szrj 37*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 38*38fd1498Szrj{ 39*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 40*38fd1498Szrj 41*38fd1498Szrjnamespace tr2 42*38fd1498Szrj{ 43*38fd1498Szrj /** 44*38fd1498Szrj * bool_set 45*38fd1498Szrj * 46*38fd1498Szrj * See N2136, Bool_set: multi-valued logic 47*38fd1498Szrj * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. 48*38fd1498Szrj * 49*38fd1498Szrj * The implicit conversion to bool is slippery! I may use the new 50*38fd1498Szrj * explicit conversion. This has been specialized in the language 51*38fd1498Szrj * so that in contexts requiring a bool the conversion happens 52*38fd1498Szrj * implicitly. Thus most objections should be eliminated. 53*38fd1498Szrj */ 54*38fd1498Szrj class bool_set 55*38fd1498Szrj { 56*38fd1498Szrj public: 57*38fd1498Szrj 58*38fd1498Szrj /// Default constructor. 59*38fd1498Szrj constexpr bool_set() : _M_b(_S_false) { } 60*38fd1498Szrj 61*38fd1498Szrj /// Constructor from bool. 62*38fd1498Szrj constexpr bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { } 63*38fd1498Szrj 64*38fd1498Szrj // I'm not sure about this. 65*38fd1498Szrj bool contains(bool_set __b) const 66*38fd1498Szrj { return this->is_singleton() && this->equals(__b); } 67*38fd1498Szrj 68*38fd1498Szrj /// Return true if states are equal. 69*38fd1498Szrj bool equals(bool_set __b) const 70*38fd1498Szrj { return __b._M_b == _M_b; } 71*38fd1498Szrj 72*38fd1498Szrj /// Return true if this is empty. 73*38fd1498Szrj bool is_emptyset() const 74*38fd1498Szrj { return _M_b == _S_empty; } 75*38fd1498Szrj 76*38fd1498Szrj /// Return true if this is indeterminate. 77*38fd1498Szrj bool is_indeterminate() const 78*38fd1498Szrj { return _M_b == _S_indet; } 79*38fd1498Szrj 80*38fd1498Szrj /// Return true if this is false or true (normal boolean). 81*38fd1498Szrj bool is_singleton() const 82*38fd1498Szrj { return _M_b == _S_false || _M_b == _S_true_; } 83*38fd1498Szrj 84*38fd1498Szrj /// Conversion to bool. 85*38fd1498Szrj //explicit 86*38fd1498Szrj operator bool() const 87*38fd1498Szrj { 88*38fd1498Szrj if (! is_singleton()) 89*38fd1498Szrj throw std::bad_cast(); 90*38fd1498Szrj return _M_b; 91*38fd1498Szrj } 92*38fd1498Szrj 93*38fd1498Szrj /// 94*38fd1498Szrj static bool_set indeterminate() 95*38fd1498Szrj { 96*38fd1498Szrj bool_set __b; 97*38fd1498Szrj __b._M_b = _S_indet; 98*38fd1498Szrj return __b; 99*38fd1498Szrj } 100*38fd1498Szrj 101*38fd1498Szrj /// 102*38fd1498Szrj static bool_set emptyset() 103*38fd1498Szrj { 104*38fd1498Szrj bool_set __b; 105*38fd1498Szrj __b._M_b = _S_empty; 106*38fd1498Szrj return __b; 107*38fd1498Szrj } 108*38fd1498Szrj 109*38fd1498Szrj friend bool_set 110*38fd1498Szrj operator!(bool_set __b) 111*38fd1498Szrj { return __b._M_not(); } 112*38fd1498Szrj 113*38fd1498Szrj friend bool_set 114*38fd1498Szrj operator^(bool_set __s, bool_set __t) 115*38fd1498Szrj { return __s._M_xor(__t); } 116*38fd1498Szrj 117*38fd1498Szrj friend bool_set 118*38fd1498Szrj operator|(bool_set __s, bool_set __t) 119*38fd1498Szrj { return __s._M_or(__t); } 120*38fd1498Szrj 121*38fd1498Szrj friend bool_set 122*38fd1498Szrj operator&(bool_set __s, bool_set __t) 123*38fd1498Szrj { return __s._M_and(__t); } 124*38fd1498Szrj 125*38fd1498Szrj friend bool_set 126*38fd1498Szrj operator==(bool_set __s, bool_set __t) 127*38fd1498Szrj { return __s._M_eq(__t); } 128*38fd1498Szrj 129*38fd1498Szrj 130*38fd1498Szrj // These overloads replace the facet additions in the paper! 131*38fd1498Szrj 132*38fd1498Szrj template<typename CharT, typename Traits> 133*38fd1498Szrj friend std::basic_ostream<CharT, Traits>& 134*38fd1498Szrj operator<<(std::basic_ostream<CharT, Traits>& __out, bool_set __b) 135*38fd1498Szrj { 136*38fd1498Szrj int __a = __b._M_b; 137*38fd1498Szrj __out << __a; 138*38fd1498Szrj } 139*38fd1498Szrj 140*38fd1498Szrj template<typename CharT, typename Traits> 141*38fd1498Szrj friend std::basic_istream<CharT, Traits>& 142*38fd1498Szrj operator>>(std::basic_istream<CharT, Traits>& __in, bool_set& __b) 143*38fd1498Szrj { 144*38fd1498Szrj long __c; 145*38fd1498Szrj __in >> __c; 146*38fd1498Szrj if (__c >= _S_false && __c < _S_empty) 147*38fd1498Szrj __b._M_b = static_cast<_Bool_set_val>(__c); 148*38fd1498Szrj } 149*38fd1498Szrj 150*38fd1498Szrj private: 151*38fd1498Szrj 152*38fd1498Szrj /// 153*38fd1498Szrj enum _Bool_set_val: unsigned char 154*38fd1498Szrj { 155*38fd1498Szrj _S_false = 0, 156*38fd1498Szrj _S_true_ = 1, 157*38fd1498Szrj _S_indet = 2, 158*38fd1498Szrj _S_empty = 3 159*38fd1498Szrj }; 160*38fd1498Szrj 161*38fd1498Szrj /// Bool set state. 162*38fd1498Szrj _Bool_set_val _M_b; 163*38fd1498Szrj 164*38fd1498Szrj /// 165*38fd1498Szrj bool_set(_Bool_set_val __c) : _M_b(__c) { } 166*38fd1498Szrj 167*38fd1498Szrj /// 168*38fd1498Szrj bool_set _M_not() const 169*38fd1498Szrj { return _S_not[this->_M_b]; } 170*38fd1498Szrj 171*38fd1498Szrj /// 172*38fd1498Szrj bool_set _M_xor(bool_set __b) const 173*38fd1498Szrj { return _S_xor[this->_M_b][__b._M_b]; } 174*38fd1498Szrj 175*38fd1498Szrj /// 176*38fd1498Szrj bool_set _M_or(bool_set __b) const 177*38fd1498Szrj { return _S_or[this->_M_b][__b._M_b]; } 178*38fd1498Szrj 179*38fd1498Szrj /// 180*38fd1498Szrj bool_set _M_and(bool_set __b) const 181*38fd1498Szrj { return _S_and[this->_M_b][__b._M_b]; } 182*38fd1498Szrj 183*38fd1498Szrj /// 184*38fd1498Szrj bool_set _M_eq(bool_set __b) const 185*38fd1498Szrj { return _S_eq[this->_M_b][__b._M_b]; } 186*38fd1498Szrj 187*38fd1498Szrj /// 188*38fd1498Szrj static _Bool_set_val _S_not[4]; 189*38fd1498Szrj 190*38fd1498Szrj /// 191*38fd1498Szrj static _Bool_set_val _S_xor[4][4]; 192*38fd1498Szrj 193*38fd1498Szrj /// 194*38fd1498Szrj static _Bool_set_val _S_or[4][4]; 195*38fd1498Szrj 196*38fd1498Szrj /// 197*38fd1498Szrj static _Bool_set_val _S_and[4][4]; 198*38fd1498Szrj 199*38fd1498Szrj /// 200*38fd1498Szrj static _Bool_set_val _S_eq[4][4]; 201*38fd1498Szrj }; 202*38fd1498Szrj 203*38fd1498Szrj // 20.2.3.2 bool_set values 204*38fd1498Szrj 205*38fd1498Szrj inline bool 206*38fd1498Szrj contains(bool_set __s, bool_set __t) 207*38fd1498Szrj { return __s.contains(__t); } 208*38fd1498Szrj 209*38fd1498Szrj inline bool 210*38fd1498Szrj equals(bool_set __s, bool_set __t) 211*38fd1498Szrj { return __s.equals(__t); } 212*38fd1498Szrj 213*38fd1498Szrj inline bool 214*38fd1498Szrj is_emptyset(bool_set __b) 215*38fd1498Szrj { return __b.is_emptyset(); } 216*38fd1498Szrj 217*38fd1498Szrj inline bool 218*38fd1498Szrj is_indeterminate(bool_set __b) 219*38fd1498Szrj { return __b.is_indeterminate(); } 220*38fd1498Szrj 221*38fd1498Szrj inline bool 222*38fd1498Szrj is_singleton(bool_set __b) 223*38fd1498Szrj { return __b.is_singleton(); } 224*38fd1498Szrj 225*38fd1498Szrj inline bool 226*38fd1498Szrj certainly(bool_set __b) 227*38fd1498Szrj { return ! __b.contains(false); } 228*38fd1498Szrj 229*38fd1498Szrj inline bool 230*38fd1498Szrj possibly(bool_set __b) 231*38fd1498Szrj { return __b.contains(true); } 232*38fd1498Szrj 233*38fd1498Szrj 234*38fd1498Szrj // 20.2.3.3 bool_set set operations 235*38fd1498Szrj 236*38fd1498Szrj inline bool_set 237*38fd1498Szrj set_union(bool __s, bool_set __t) 238*38fd1498Szrj { return bool_set(__s) | __t; } 239*38fd1498Szrj 240*38fd1498Szrj inline bool_set 241*38fd1498Szrj set_union(bool_set __s, bool __t) 242*38fd1498Szrj { return __s | bool_set(__t); } 243*38fd1498Szrj 244*38fd1498Szrj inline bool_set 245*38fd1498Szrj set_union(bool_set __s, bool_set __t) 246*38fd1498Szrj { return __s | __t; } 247*38fd1498Szrj 248*38fd1498Szrj inline bool_set 249*38fd1498Szrj set_intersection(bool __s, bool_set __t) 250*38fd1498Szrj { return bool_set(__s) & __t; } 251*38fd1498Szrj 252*38fd1498Szrj inline bool_set 253*38fd1498Szrj set_intersection(bool_set __s, bool __t) 254*38fd1498Szrj { return __s & bool_set(__t); } 255*38fd1498Szrj 256*38fd1498Szrj inline bool_set 257*38fd1498Szrj set_intersection(bool_set __s, bool_set __t) 258*38fd1498Szrj { return __s & __t; } 259*38fd1498Szrj 260*38fd1498Szrj inline bool_set 261*38fd1498Szrj set_complement(bool_set __b) 262*38fd1498Szrj { return ! __b; } 263*38fd1498Szrj 264*38fd1498Szrj 265*38fd1498Szrj // 20.2.3.4 bool_set logical operators 266*38fd1498Szrj 267*38fd1498Szrj inline bool_set 268*38fd1498Szrj operator^(bool __s, bool_set __t) 269*38fd1498Szrj { return bool_set(__s) ^ __t; } 270*38fd1498Szrj 271*38fd1498Szrj inline bool_set 272*38fd1498Szrj operator^(bool_set __s, bool __t) 273*38fd1498Szrj { return __s ^ bool_set(__t); } 274*38fd1498Szrj 275*38fd1498Szrj inline bool_set 276*38fd1498Szrj operator|(bool __s, bool_set __t) 277*38fd1498Szrj { return bool_set(__s) | __t; } 278*38fd1498Szrj 279*38fd1498Szrj inline bool_set 280*38fd1498Szrj operator|(bool_set __s, bool __t) 281*38fd1498Szrj { return __s | bool_set(__t); } 282*38fd1498Szrj 283*38fd1498Szrj inline bool_set 284*38fd1498Szrj operator&(bool __s, bool_set __t) 285*38fd1498Szrj { return bool_set(__s) & __t; } 286*38fd1498Szrj 287*38fd1498Szrj inline bool_set 288*38fd1498Szrj operator&(bool_set __s, bool __t) 289*38fd1498Szrj { return __s & bool_set(__t); } 290*38fd1498Szrj 291*38fd1498Szrj 292*38fd1498Szrj // 20.2.3.5 bool_set relational operators 293*38fd1498Szrj 294*38fd1498Szrj inline bool_set 295*38fd1498Szrj operator==(bool __s, bool_set __t) 296*38fd1498Szrj { return bool_set(__s) == __t; } 297*38fd1498Szrj 298*38fd1498Szrj inline bool_set 299*38fd1498Szrj operator==(bool_set __s, bool __t) 300*38fd1498Szrj { return __s == bool_set(__t); } 301*38fd1498Szrj 302*38fd1498Szrj inline bool_set 303*38fd1498Szrj operator!=(bool __s, bool_set __t) 304*38fd1498Szrj { return ! (__s == __t); } 305*38fd1498Szrj 306*38fd1498Szrj inline bool_set 307*38fd1498Szrj operator!=(bool_set __s, bool __t) 308*38fd1498Szrj { return ! (__s == __t); } 309*38fd1498Szrj 310*38fd1498Szrj inline bool_set 311*38fd1498Szrj operator!=(bool_set __s, bool_set __t) 312*38fd1498Szrj { return ! (__s == __t); } 313*38fd1498Szrj} 314*38fd1498Szrj 315*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 316*38fd1498Szrj} 317*38fd1498Szrj 318*38fd1498Szrj#include <tr2/bool_set.tcc> 319*38fd1498Szrj 320*38fd1498Szrj#endif // _GLIBCXX_TR2_BOOL_SET 321