Home | History | Annotate | Download | only in tr2
      1 // TR2 <bool_set> -*- C++ -*-
      2 
      3 // Copyright (C) 2009-2013 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 Brnnimann, 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
    321