libstdc++
|
00001 // TR2 <bool_set> -*- C++ -*- 00002 00003 // Copyright (C) 2009, 2011 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file tr2/bool_set 00026 * This is a TR2 C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_TR2_BOOL_SET 00030 #define _GLIBCXX_TR2_BOOL_SET 1 00031 00032 #pragma GCC system_header 00033 00034 #include <typeinfo> 00035 #include <iostream> 00036 00037 namespace std _GLIBCXX_VISIBILITY(default) 00038 { 00039 namespace tr2 00040 { 00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00042 00043 /** 00044 * bool_set 00045 * 00046 * See N2136, Bool_set: multi-valued logic 00047 * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. 00048 * 00049 * The implicit conversion to bool is slippery! I may use the new 00050 * explicit conversion. This has been specialized in the language 00051 * so that in contexts requiring a bool the conversion happens 00052 * implicitly. Thus most objections should be eliminated. 00053 */ 00054 class bool_set 00055 { 00056 public: 00057 00058 /// Default constructor. 00059 bool_set() : _M_b(_S_false) { } 00060 00061 /// Constructor from bool. 00062 bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { } 00063 00064 // I'm not sure about this. 00065 bool contains(bool_set __b) const 00066 { return this->is_singleton() && this->equals(__b); } 00067 00068 /// Return true if states are equal. 00069 bool equals(bool_set __b) const 00070 { return __b._M_b == _M_b; } 00071 00072 /// Return true if this is empty. 00073 bool is_emptyset() const 00074 { return _M_b == _S_empty; } 00075 00076 /// Return true if this is indeterminate. 00077 bool is_indeterminate() const 00078 { return _M_b == _S_indet; } 00079 00080 /// Return true if this is false or true (normal boolean). 00081 bool is_singleton() const 00082 { return _M_b == _S_false || _M_b == _S_true_; } 00083 00084 /// Conversion to bool. 00085 //explicit 00086 operator bool() const 00087 { 00088 if (! is_singleton()) 00089 throw std::bad_cast(); 00090 return _M_b; 00091 } 00092 00093 /// 00094 static bool_set indeterminate() 00095 { 00096 bool_set __b; 00097 __b._M_b = _S_indet; 00098 return __b; 00099 } 00100 00101 /// 00102 static bool_set emptyset() 00103 { 00104 bool_set __b; 00105 __b._M_b = _S_empty; 00106 return __b; 00107 } 00108 00109 friend bool_set 00110 operator!(bool_set __b) 00111 { return __b._M_not(); } 00112 00113 friend bool_set 00114 operator^(bool_set __s, bool_set __t) 00115 { return __s._M_xor(__t); } 00116 00117 friend bool_set 00118 operator|(bool_set __s, bool_set __t) 00119 { return __s._M_or(__t); } 00120 00121 friend bool_set 00122 operator&(bool_set __s, bool_set __t) 00123 { return __s._M_and(__t); } 00124 00125 friend bool_set 00126 operator==(bool_set __s, bool_set __t) 00127 { return __s._M_eq(__t); } 00128 00129 00130 // These overloads replace the facet additions in the paper! 00131 00132 template<typename CharT, typename Traits> 00133 friend std::basic_ostream<CharT, Traits>& 00134 operator<<(std::basic_ostream<CharT, Traits>& __out, bool_set __b) 00135 { 00136 int __a = __b._M_b; 00137 __out << __a; 00138 } 00139 00140 template<typename CharT, typename Traits> 00141 friend std::basic_istream<CharT, Traits>& 00142 operator>>(std::basic_istream<CharT, Traits>& __in, bool_set& __b) 00143 { 00144 long __c; 00145 __in >> __c; 00146 if (__c >= _S_false && __c < _S_empty) 00147 __b._M_b = static_cast<_Bool_set_val>(__c); 00148 } 00149 00150 private: 00151 00152 /// 00153 enum _Bool_set_val: unsigned char 00154 { 00155 _S_false = 0, 00156 _S_true_ = 1, 00157 _S_indet = 2, 00158 _S_empty = 3 00159 }; 00160 00161 /// Bool set state. 00162 _Bool_set_val _M_b; 00163 00164 /// 00165 bool_set(_Bool_set_val __c) : _M_b(__c) { } 00166 00167 /// 00168 bool_set _M_not() const 00169 { return _S_not[this->_M_b]; } 00170 00171 /// 00172 bool_set _M_xor(bool_set __b) const 00173 { return _S_xor[this->_M_b][__b._M_b]; } 00174 00175 /// 00176 bool_set _M_or(bool_set __b) const 00177 { return _S_or[this->_M_b][__b._M_b]; } 00178 00179 /// 00180 bool_set _M_and(bool_set __b) const 00181 { return _S_and[this->_M_b][__b._M_b]; } 00182 00183 /// 00184 bool_set _M_eq(bool_set __b) const 00185 { return _S_eq[this->_M_b][__b._M_b]; } 00186 00187 /// 00188 static _Bool_set_val _S_not[4]; 00189 00190 /// 00191 static _Bool_set_val _S_xor[4][4]; 00192 00193 /// 00194 static _Bool_set_val _S_or[4][4]; 00195 00196 /// 00197 static _Bool_set_val _S_and[4][4]; 00198 00199 /// 00200 static _Bool_set_val _S_eq[4][4]; 00201 }; 00202 00203 // 20.2.3.2 bool_set values 00204 00205 inline bool 00206 contains(bool_set __s, bool_set __t) 00207 { return __s.contains(__t); } 00208 00209 inline bool 00210 equals(bool_set __s, bool_set __t) 00211 { return __s.equals(__t); } 00212 00213 inline bool 00214 is_emptyset(bool_set __b) 00215 { return __b.is_emptyset(); } 00216 00217 inline bool 00218 is_indeterminate(bool_set __b) 00219 { return __b.is_indeterminate(); } 00220 00221 inline bool 00222 is_singleton(bool_set __b) 00223 { return __b.is_singleton(); } 00224 00225 inline bool 00226 certainly(bool_set __b) 00227 { return ! __b.contains(false); } 00228 00229 inline bool 00230 possibly(bool_set __b) 00231 { return __b.contains(true); } 00232 00233 00234 // 20.2.3.3 bool_set set operations 00235 00236 inline bool_set 00237 set_union(bool __s, bool_set __t) 00238 { return bool_set(__s) | __t; } 00239 00240 inline bool_set 00241 set_union(bool_set __s, bool __t) 00242 { return __s | bool_set(__t); } 00243 00244 inline bool_set 00245 set_union(bool_set __s, bool_set __t) 00246 { return __s | __t; } 00247 00248 inline bool_set 00249 set_intersection(bool __s, bool_set __t) 00250 { return bool_set(__s) & __t; } 00251 00252 inline bool_set 00253 set_intersection(bool_set __s, bool __t) 00254 { return __s & bool_set(__t); } 00255 00256 inline bool_set 00257 set_intersection(bool_set __s, bool_set __t) 00258 { return __s & __t; } 00259 00260 inline bool_set 00261 set_complement(bool_set __b) 00262 { return ! __b; } 00263 00264 00265 // 20.2.3.4 bool_set logical operators 00266 00267 inline bool_set 00268 operator^(bool __s, bool_set __t) 00269 { return bool_set(__s) ^ __t; } 00270 00271 inline bool_set 00272 operator^(bool_set __s, bool __t) 00273 { return __s ^ bool_set(__t); } 00274 00275 inline bool_set 00276 operator|(bool __s, bool_set __t) 00277 { return bool_set(__s) | __t; } 00278 00279 inline bool_set 00280 operator|(bool_set __s, bool __t) 00281 { return __s | bool_set(__t); } 00282 00283 inline bool_set 00284 operator&(bool __s, bool_set __t) 00285 { return bool_set(__s) & __t; } 00286 00287 inline bool_set 00288 operator&(bool_set __s, bool __t) 00289 { return __s & bool_set(__t); } 00290 00291 00292 // 20.2.3.5 bool_set relational operators 00293 00294 inline bool_set 00295 operator==(bool __s, bool_set __t) 00296 { return bool_set(__s) == __t; } 00297 00298 inline bool_set 00299 operator==(bool_set __s, bool __t) 00300 { return __s == bool_set(__t); } 00301 00302 inline bool_set 00303 operator!=(bool __s, bool_set __t) 00304 { return ! (__s == __t); } 00305 00306 inline bool_set 00307 operator!=(bool_set __s, bool __t) 00308 { return ! (__s == __t); } 00309 00310 inline bool_set 00311 operator!=(bool_set __s, bool_set __t) 00312 { return ! (__s == __t); } 00313 00314 _GLIBCXX_END_NAMESPACE_VERSION 00315 } 00316 } 00317 00318 #include <tr2/bool_set.tcc> 00319 00320 #endif // _GLIBCXX_TR2_BOOL_SET