libstdc++
bool_set
1 // TR2 <bool_set> -*- C++ -*-
2 
3 // Copyright (C) 2009-2014 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 #pragma GCC system_header
33 
34 #include <typeinfo>
35 #include <iostream>
36 
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 namespace tr2
40 {
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
42 
43  /**
44  * bool_set
45  *
46  * See N2136, Bool_set: multi-valued logic
47  * by HervĂ© Brönnimann, Guillaume Melquiond, Sylvain Pion.
48  *
49  * The implicit conversion to bool is slippery! I may use the new
50  * explicit conversion. This has been specialized in the language
51  * so that in contexts requiring a bool the conversion happens
52  * implicitly. Thus most objections should be eliminated.
53  */
54  class bool_set
55  {
56  public:
57 
58  /// Default constructor.
59  constexpr bool_set() : _M_b(_S_false) { }
60 
61  /// Constructor from bool.
62  constexpr bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { }
63 
64  // I'm not sure about this.
65  bool contains(bool_set __b) const
66  { return this->is_singleton() && this->equals(__b); }
67 
68  /// Return true if states are equal.
69  bool equals(bool_set __b) const
70  { return __b._M_b == _M_b; }
71 
72  /// Return true if this is empty.
73  bool is_emptyset() const
74  { return _M_b == _S_empty; }
75 
76  /// Return true if this is indeterminate.
77  bool is_indeterminate() const
78  { return _M_b == _S_indet; }
79 
80  /// Return true if this is false or true (normal boolean).
81  bool is_singleton() const
82  { return _M_b == _S_false || _M_b == _S_true_; }
83 
84  /// Conversion to bool.
85  //explicit
86  operator bool() const
87  {
88  if (! is_singleton())
89  throw std::bad_cast();
90  return _M_b;
91  }
92 
93  ///
94  static bool_set indeterminate()
95  {
96  bool_set __b;
97  __b._M_b = _S_indet;
98  return __b;
99  }
100 
101  ///
102  static bool_set emptyset()
103  {
104  bool_set __b;
105  __b._M_b = _S_empty;
106  return __b;
107  }
108 
109  friend bool_set
110  operator!(bool_set __b)
111  { return __b._M_not(); }
112 
113  friend bool_set
114  operator^(bool_set __s, bool_set __t)
115  { return __s._M_xor(__t); }
116 
117  friend bool_set
118  operator|(bool_set __s, bool_set __t)
119  { return __s._M_or(__t); }
120 
121  friend bool_set
122  operator&(bool_set __s, bool_set __t)
123  { return __s._M_and(__t); }
124 
125  friend bool_set
126  operator==(bool_set __s, bool_set __t)
127  { return __s._M_eq(__t); }
128 
129 
130  // These overloads replace the facet additions in the paper!
131 
132  template<typename CharT, typename Traits>
133  friend std::basic_ostream<CharT, Traits>&
134  operator<<(std::basic_ostream<CharT, Traits>& __out, bool_set __b)
135  {
136  int __a = __b._M_b;
137  __out << __a;
138  }
139 
140  template<typename CharT, typename Traits>
141  friend std::basic_istream<CharT, Traits>&
142  operator>>(std::basic_istream<CharT, Traits>& __in, bool_set& __b)
143  {
144  long __c;
145  __in >> __c;
146  if (__c >= _S_false && __c < _S_empty)
147  __b._M_b = static_cast<_Bool_set_val>(__c);
148  }
149 
150  private:
151 
152  ///
153  enum _Bool_set_val: unsigned char
154  {
155  _S_false = 0,
156  _S_true_ = 1,
157  _S_indet = 2,
158  _S_empty = 3
159  };
160 
161  /// Bool set state.
162  _Bool_set_val _M_b;
163 
164  ///
165  bool_set(_Bool_set_val __c) : _M_b(__c) { }
166 
167  ///
168  bool_set _M_not() const
169  { return _S_not[this->_M_b]; }
170 
171  ///
172  bool_set _M_xor(bool_set __b) const
173  { return _S_xor[this->_M_b][__b._M_b]; }
174 
175  ///
176  bool_set _M_or(bool_set __b) const
177  { return _S_or[this->_M_b][__b._M_b]; }
178 
179  ///
180  bool_set _M_and(bool_set __b) const
181  { return _S_and[this->_M_b][__b._M_b]; }
182 
183  ///
184  bool_set _M_eq(bool_set __b) const
185  { return _S_eq[this->_M_b][__b._M_b]; }
186 
187  ///
188  static _Bool_set_val _S_not[4];
189 
190  ///
191  static _Bool_set_val _S_xor[4][4];
192 
193  ///
194  static _Bool_set_val _S_or[4][4];
195 
196  ///
197  static _Bool_set_val _S_and[4][4];
198 
199  ///
200  static _Bool_set_val _S_eq[4][4];
201  };
202 
203  // 20.2.3.2 bool_set values
204 
205  inline bool
206  contains(bool_set __s, bool_set __t)
207  { return __s.contains(__t); }
208 
209  inline bool
210  equals(bool_set __s, bool_set __t)
211  { return __s.equals(__t); }
212 
213  inline bool
214  is_emptyset(bool_set __b)
215  { return __b.is_emptyset(); }
216 
217  inline bool
218  is_indeterminate(bool_set __b)
219  { return __b.is_indeterminate(); }
220 
221  inline bool
222  is_singleton(bool_set __b)
223  { return __b.is_singleton(); }
224 
225  inline bool
226  certainly(bool_set __b)
227  { return ! __b.contains(false); }
228 
229  inline bool
230  possibly(bool_set __b)
231  { return __b.contains(true); }
232 
233 
234  // 20.2.3.3 bool_set set operations
235 
236  inline bool_set
237  set_union(bool __s, bool_set __t)
238  { return bool_set(__s) | __t; }
239 
240  inline bool_set
241  set_union(bool_set __s, bool __t)
242  { return __s | bool_set(__t); }
243 
244  inline bool_set
245  set_union(bool_set __s, bool_set __t)
246  { return __s | __t; }
247 
248  inline bool_set
249  set_intersection(bool __s, bool_set __t)
250  { return bool_set(__s) & __t; }
251 
252  inline bool_set
253  set_intersection(bool_set __s, bool __t)
254  { return __s & bool_set(__t); }
255 
256  inline bool_set
257  set_intersection(bool_set __s, bool_set __t)
258  { return __s & __t; }
259 
260  inline bool_set
261  set_complement(bool_set __b)
262  { return ! __b; }
263 
264 
265  // 20.2.3.4 bool_set logical operators
266 
267  inline bool_set
268  operator^(bool __s, bool_set __t)
269  { return bool_set(__s) ^ __t; }
270 
271  inline bool_set
272  operator^(bool_set __s, bool __t)
273  { return __s ^ bool_set(__t); }
274 
275  inline bool_set
276  operator|(bool __s, bool_set __t)
277  { return bool_set(__s) | __t; }
278 
279  inline bool_set
280  operator|(bool_set __s, bool __t)
281  { return __s | bool_set(__t); }
282 
283  inline bool_set
284  operator&(bool __s, bool_set __t)
285  { return bool_set(__s) & __t; }
286 
287  inline bool_set
288  operator&(bool_set __s, bool __t)
289  { return __s & bool_set(__t); }
290 
291 
292  // 20.2.3.5 bool_set relational operators
293 
294  inline bool_set
295  operator==(bool __s, bool_set __t)
296  { return bool_set(__s) == __t; }
297 
298  inline bool_set
299  operator==(bool_set __s, bool __t)
300  { return __s == bool_set(__t); }
301 
302  inline bool_set
303  operator!=(bool __s, bool_set __t)
304  { return ! (__s == __t); }
305 
306  inline bool_set
307  operator!=(bool_set __s, bool __t)
308  { return ! (__s == __t); }
309 
310  inline bool_set
311  operator!=(bool_set __s, bool_set __t)
312  { return ! (__s == __t); }
313 
314 _GLIBCXX_END_NAMESPACE_VERSION
315 }
316 }
317 
318 #include <tr2/bool_set.tcc>
319 
320 #endif // _GLIBCXX_TR2_BOOL_SET