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