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