1// TR2 <bool_set> -*- C++ -*-
2
3// Copyright (C) 2009, 2011 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
37namespace std _GLIBCXX_VISIBILITY(default)
38{
39namespace 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    bool_set() : _M_b(_S_false) { }
60
61    ///  Constructor from bool.
62    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
321