You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
7.2KB

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