1*38fd1498Szrj // TR2 <bool_set> support files -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2009-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file tr2/bool_set.tcc 26*38fd1498Szrj * This is a TR2 C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj #ifndef _GLIBCXX_TR2_BOOL_SET_TCC 30*38fd1498Szrj #define _GLIBCXX_TR2_BOOL_SET_TCC 1 31*38fd1498Szrj 32*38fd1498Szrj #pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 35*38fd1498Szrj { 36*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 37*38fd1498Szrj 38*38fd1498Szrj namespace tr2 39*38fd1498Szrj { 40*38fd1498Szrj bool_set::_Bool_set_val 41*38fd1498Szrj bool_set::_S_not[4] = 42*38fd1498Szrj { _S_true_, _S_false, _S_indet, _S_empty }; 43*38fd1498Szrj 44*38fd1498Szrj bool_set::_Bool_set_val 45*38fd1498Szrj bool_set::_S_xor[4][4] = 46*38fd1498Szrj { { _S_false, _S_true_, _S_indet, _S_empty }, 47*38fd1498Szrj { _S_true_, _S_false, _S_indet, _S_empty }, 48*38fd1498Szrj { _S_indet, _S_indet, _S_indet, _S_empty }, 49*38fd1498Szrj { _S_empty, _S_empty, _S_empty, _S_empty } }; 50*38fd1498Szrj 51*38fd1498Szrj bool_set::_Bool_set_val 52*38fd1498Szrj bool_set::_S_or[4][4] = 53*38fd1498Szrj { { _S_false, _S_true_, _S_indet, _S_empty }, 54*38fd1498Szrj { _S_true_, _S_true_, _S_true_, _S_empty }, 55*38fd1498Szrj { _S_indet, _S_true_, _S_indet, _S_empty }, 56*38fd1498Szrj { _S_empty, _S_empty, _S_empty, _S_empty } }; 57*38fd1498Szrj 58*38fd1498Szrj bool_set::_Bool_set_val 59*38fd1498Szrj bool_set::_S_and[4][4] = 60*38fd1498Szrj { { _S_false, _S_false, _S_false, _S_empty }, 61*38fd1498Szrj { _S_false, _S_true_, _S_indet, _S_empty }, 62*38fd1498Szrj { _S_false, _S_indet, _S_indet, _S_empty }, 63*38fd1498Szrj { _S_empty, _S_empty, _S_empty, _S_empty } }; 64*38fd1498Szrj 65*38fd1498Szrj bool_set::_Bool_set_val 66*38fd1498Szrj bool_set::_S_eq[4][4] = 67*38fd1498Szrj { { _S_true_, _S_false, _S_indet, _S_empty }, 68*38fd1498Szrj { _S_false, _S_true_, _S_indet, _S_empty }, 69*38fd1498Szrj { _S_indet, _S_indet, _S_indet, _S_empty }, 70*38fd1498Szrj { _S_empty, _S_empty, _S_empty, _S_empty } }; 71*38fd1498Szrj } 72*38fd1498Szrj 73*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 74*38fd1498Szrj } 75*38fd1498Szrj 76*38fd1498Szrj // I object to these things. 77*38fd1498Szrj // The stuff in locale facets are for basic types. 78*38fd1498Szrj // I think we could hack operator<< and operator>>. 79*38fd1498Szrj 80*38fd1498Szrj /** 81*38fd1498Szrj * @brief Numeric parsing. 82*38fd1498Szrj * 83*38fd1498Szrj * Parses the input stream into the bool @a v. It does so by calling 84*38fd1498Szrj * num_get::do_get(). 85*38fd1498Szrj * 86*38fd1498Szrj * If ios_base::boolalpha is set, attempts to read 87*38fd1498Szrj * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets 88*38fd1498Szrj * @a v to true or false if successful. Sets err to 89*38fd1498Szrj * ios_base::failbit if reading the string fails. Sets err to 90*38fd1498Szrj * ios_base::eofbit if the stream is emptied. 91*38fd1498Szrj * 92*38fd1498Szrj * If ios_base::boolalpha is not set, proceeds as with reading a long, 93*38fd1498Szrj * except if the value is 1, sets @a v to true, if the value is 0, sets 94*38fd1498Szrj * @a v to false, and otherwise set err to ios_base::failbit. 95*38fd1498Szrj * 96*38fd1498Szrj * @param in Start of input stream. 97*38fd1498Szrj * @param end End of input stream. 98*38fd1498Szrj * @param io Source of locale and flags. 99*38fd1498Szrj * @param err Error flags to set. 100*38fd1498Szrj * @param v Value to format and insert. 101*38fd1498Szrj * @return Iterator after reading. 102*38fd1498Szrj iter_type 103*38fd1498Szrj get(iter_type __in, iter_type __end, ios_base& __io, 104*38fd1498Szrj ios_base::iostate& __err, bool& __v) const 105*38fd1498Szrj { return this->do_get(__in, __end, __io, __err, __v); } 106*38fd1498Szrj */ 107*38fd1498Szrj /* 108*38fd1498Szrj template<typename _CharT, typename _InIter> 109*38fd1498Szrj _InIter 110*38fd1498Szrj num_get<_CharT, _InIter>:: 111*38fd1498Szrj do_get(iter_type __beg, iter_type __end, ios_base& __io, 112*38fd1498Szrj ios_base::iostate& __err, bool_set& __v) const 113*38fd1498Szrj { 114*38fd1498Szrj if (!(__io.flags() & ios_base::boolalpha)) 115*38fd1498Szrj { 116*38fd1498Szrj // Parse bool values as long. 117*38fd1498Szrj // NB: We can't just call do_get(long) here, as it might 118*38fd1498Szrj // refer to a derived class. 119*38fd1498Szrj long __l = -1; 120*38fd1498Szrj __beg = _M_extract_int(__beg, __end, __io, __err, __l); 121*38fd1498Szrj if (__c >= _S_false && __c < _S_empty) 122*38fd1498Szrj __b._M_b = static_cast<_Bool_set_val>(__c); 123*38fd1498Szrj else 124*38fd1498Szrj { 125*38fd1498Szrj // What should we do here? 126*38fd1498Szrj __v = true; 127*38fd1498Szrj __err = ios_base::failbit; 128*38fd1498Szrj if (__beg == __end) 129*38fd1498Szrj __err |= ios_base::eofbit; 130*38fd1498Szrj } 131*38fd1498Szrj } 132*38fd1498Szrj else 133*38fd1498Szrj { 134*38fd1498Szrj // Parse bool values as alphanumeric. 135*38fd1498Szrj typedef __numpunct_cache<_CharT> __cache_type; 136*38fd1498Szrj __use_cache<__cache_type> __uc; 137*38fd1498Szrj const locale& __loc = __io._M_getloc(); 138*38fd1498Szrj const __cache_type* __lc = __uc(__loc); 139*38fd1498Szrj 140*38fd1498Szrj bool __testf = true; 141*38fd1498Szrj bool __testt = true; 142*38fd1498Szrj bool __donef = __lc->_M_falsename_size == 0; 143*38fd1498Szrj bool __donet = __lc->_M_truename_size == 0; 144*38fd1498Szrj bool __testeof = false; 145*38fd1498Szrj size_t __n = 0; 146*38fd1498Szrj while (!__donef || !__donet) 147*38fd1498Szrj { 148*38fd1498Szrj if (__beg == __end) 149*38fd1498Szrj { 150*38fd1498Szrj __testeof = true; 151*38fd1498Szrj break; 152*38fd1498Szrj } 153*38fd1498Szrj 154*38fd1498Szrj const char_type __c = *__beg; 155*38fd1498Szrj 156*38fd1498Szrj if (!__donef) 157*38fd1498Szrj __testf = __c == __lc->_M_falsename[__n]; 158*38fd1498Szrj 159*38fd1498Szrj if (!__testf && __donet) 160*38fd1498Szrj break; 161*38fd1498Szrj 162*38fd1498Szrj if (!__donet) 163*38fd1498Szrj __testt = __c == __lc->_M_truename[__n]; 164*38fd1498Szrj 165*38fd1498Szrj if (!__testt && __donef) 166*38fd1498Szrj break; 167*38fd1498Szrj 168*38fd1498Szrj if (!__testt && !__testf) 169*38fd1498Szrj break; 170*38fd1498Szrj 171*38fd1498Szrj ++__n; 172*38fd1498Szrj ++__beg; 173*38fd1498Szrj 174*38fd1498Szrj __donef = !__testf || __n >= __lc->_M_falsename_size; 175*38fd1498Szrj __donet = !__testt || __n >= __lc->_M_truename_size; 176*38fd1498Szrj } 177*38fd1498Szrj if (__testf && __n == __lc->_M_falsename_size && __n) 178*38fd1498Szrj { 179*38fd1498Szrj __v = false; 180*38fd1498Szrj if (__testt && __n == __lc->_M_truename_size) 181*38fd1498Szrj __err = ios_base::failbit; 182*38fd1498Szrj else 183*38fd1498Szrj __err = __testeof ? ios_base::eofbit : ios_base::goodbit; 184*38fd1498Szrj } 185*38fd1498Szrj else if (__testt && __n == __lc->_M_truename_size && __n) 186*38fd1498Szrj { 187*38fd1498Szrj __v = true; 188*38fd1498Szrj __err = __testeof ? ios_base::eofbit : ios_base::goodbit; 189*38fd1498Szrj } 190*38fd1498Szrj else 191*38fd1498Szrj { 192*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 193*38fd1498Szrj // 23. Num_get overflow result. 194*38fd1498Szrj __v = false; 195*38fd1498Szrj __err = ios_base::failbit; 196*38fd1498Szrj if (__testeof) 197*38fd1498Szrj __err |= ios_base::eofbit; 198*38fd1498Szrj } 199*38fd1498Szrj } 200*38fd1498Szrj return __beg; 201*38fd1498Szrj } 202*38fd1498Szrj */ 203*38fd1498Szrj 204*38fd1498Szrj /** 205*38fd1498Szrj * @brief Numeric formatting. 206*38fd1498Szrj * 207*38fd1498Szrj * Formats the boolean @a v and inserts it into a stream. It does so 208*38fd1498Szrj * by calling num_put::do_put(). 209*38fd1498Szrj * 210*38fd1498Szrj * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or 211*38fd1498Szrj * ctype<CharT>::falsename(). Otherwise formats @a v as an int. 212*38fd1498Szrj * 213*38fd1498Szrj * @param s Stream to write to. 214*38fd1498Szrj * @param io Source of locale and flags. 215*38fd1498Szrj * @param fill Char_type to use for filling. 216*38fd1498Szrj * @param v Value to format and insert. 217*38fd1498Szrj * @return Iterator after writing. 218*38fd1498Szrj iter_type 219*38fd1498Szrj put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const 220*38fd1498Szrj { return this->do_put(__s, __f, __fill, __v); } 221*38fd1498Szrj */ 222*38fd1498Szrj 223*38fd1498Szrj /* 224*38fd1498Szrj template<typename _CharT, typename _OutIter> 225*38fd1498Szrj _OutIter 226*38fd1498Szrj num_put<_CharT, _OutIter>:: 227*38fd1498Szrj do_put(iter_type __s, ios_base& __io, char_type __fill, bool_set __v) const 228*38fd1498Szrj { 229*38fd1498Szrj const ios_base::fmtflags __flags = __io.flags(); 230*38fd1498Szrj if ((__flags & ios_base::boolalpha) == 0) 231*38fd1498Szrj { 232*38fd1498Szrj const long __l = __v; 233*38fd1498Szrj __s = _M_insert_int(__s, __io, __fill, __l); 234*38fd1498Szrj } 235*38fd1498Szrj else 236*38fd1498Szrj { 237*38fd1498Szrj typedef __numpunct_cache<_CharT> __cache_type; 238*38fd1498Szrj __use_cache<__cache_type> __uc; 239*38fd1498Szrj const locale& __loc = __io._M_getloc(); 240*38fd1498Szrj const __cache_type* __lc = __uc(__loc); 241*38fd1498Szrj 242*38fd1498Szrj const _CharT* __name = __v ? __lc->_M_truename 243*38fd1498Szrj : __lc->_M_falsename; 244*38fd1498Szrj int __len = __v ? __lc->_M_truename_size 245*38fd1498Szrj : __lc->_M_falsename_size; 246*38fd1498Szrj 247*38fd1498Szrj const streamsize __w = __io.width(); 248*38fd1498Szrj if (__w > static_cast<streamsize>(__len)) 249*38fd1498Szrj { 250*38fd1498Szrj const streamsize __plen = __w - __len; 251*38fd1498Szrj _CharT* __ps 252*38fd1498Szrj = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 253*38fd1498Szrj * __plen)); 254*38fd1498Szrj 255*38fd1498Szrj char_traits<_CharT>::assign(__ps, __plen, __fill); 256*38fd1498Szrj __io.width(0); 257*38fd1498Szrj 258*38fd1498Szrj if ((__flags & ios_base::adjustfield) == ios_base::left) 259*38fd1498Szrj { 260*38fd1498Szrj __s = std::__write(__s, __name, __len); 261*38fd1498Szrj __s = std::__write(__s, __ps, __plen); 262*38fd1498Szrj } 263*38fd1498Szrj else 264*38fd1498Szrj { 265*38fd1498Szrj __s = std::__write(__s, __ps, __plen); 266*38fd1498Szrj __s = std::__write(__s, __name, __len); 267*38fd1498Szrj } 268*38fd1498Szrj return __s; 269*38fd1498Szrj } 270*38fd1498Szrj __io.width(0); 271*38fd1498Szrj __s = std::__write(__s, __name, __len); 272*38fd1498Szrj } 273*38fd1498Szrj return __s; 274*38fd1498Szrj } 275*38fd1498Szrj */ 276*38fd1498Szrj 277*38fd1498Szrj #endif // _GLIBCXX_TR2_BOOL_SET_TCC 278