File indexing completed on 2025-01-18 09:39:30
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_LOGIC_TRIBOOL_IO_HPP
0008 #define BOOST_LOGIC_TRIBOOL_IO_HPP
0009
0010 #include <boost/logic/tribool.hpp>
0011 #include <boost/detail/workaround.hpp>
0012 #include <boost/noncopyable.hpp>
0013
0014 #if defined(_MSC_VER)
0015 # pragma once
0016 #endif
0017
0018 #ifndef BOOST_NO_STD_LOCALE
0019 # include <locale>
0020 #endif
0021
0022 #include <string>
0023 #include <iostream>
0024
0025 namespace boost { namespace logic {
0026
0027 #ifdef BOOST_NO_STD_LOCALE
0028
0029
0030
0031
0032
0033
0034
0035
0036 template<typename T> std::basic_string<T> default_false_name();
0037
0038
0039
0040
0041
0042
0043
0044 template<>
0045 inline std::basic_string<char> default_false_name<char>()
0046 { return "false"; }
0047
0048 # if !defined(BOOST_NO_CWCHAR)
0049
0050
0051
0052
0053
0054
0055 template<>
0056 inline std::basic_string<wchar_t> default_false_name<wchar_t>()
0057 { return L"false"; }
0058 # endif
0059
0060
0061
0062
0063
0064
0065
0066
0067 template<typename T> std::basic_string<T> default_true_name();
0068
0069
0070
0071
0072
0073
0074
0075 template<>
0076 inline std::basic_string<char> default_true_name<char>()
0077 { return "true"; }
0078
0079 # if !defined(BOOST_NO_CWCHAR)
0080
0081
0082
0083
0084
0085
0086 template<>
0087 inline std::basic_string<wchar_t> default_true_name<wchar_t>()
0088 { return L"true"; }
0089 # endif
0090 #endif
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 template<typename T> std::basic_string<T> get_default_indeterminate_name();
0101
0102
0103 template<>
0104 inline std::basic_string<char> get_default_indeterminate_name<char>()
0105 { return "indeterminate"; }
0106
0107 #if !defined(BOOST_NO_CWCHAR)
0108
0109 template<>
0110 inline std::basic_string<wchar_t> get_default_indeterminate_name<wchar_t>()
0111 { return L"indeterminate"; }
0112 #endif
0113
0114
0115
0116 #ifndef BOOST_NO_STD_LOCALE
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 template<typename CharT>
0127 class indeterminate_name : public std::locale::facet, private boost::noncopyable
0128 {
0129 public:
0130 typedef CharT char_type;
0131 typedef std::basic_string<CharT> string_type;
0132
0133
0134 indeterminate_name() : name_(get_default_indeterminate_name<CharT>()) {}
0135
0136
0137 explicit indeterminate_name(const string_type& initial_name)
0138 : name_(initial_name) {}
0139
0140
0141 string_type name() const { return name_; }
0142
0143
0144 static std::locale::id id;
0145
0146 private:
0147 string_type name_;
0148 };
0149
0150 template<typename CharT> std::locale::id indeterminate_name<CharT>::id;
0151 #endif
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 template<typename CharT, typename Traits>
0172 inline std::basic_ostream<CharT, Traits>&
0173 operator<<(std::basic_ostream<CharT, Traits>& out, tribool x)
0174 {
0175 if (!indeterminate(x)) {
0176 out << static_cast<bool>(x);
0177 } else {
0178 typename std::basic_ostream<CharT, Traits>::sentry cerberus(out);
0179 if (cerberus) {
0180 if (out.flags() & std::ios_base::boolalpha) {
0181 #ifndef BOOST_NO_STD_LOCALE
0182 if (BOOST_HAS_FACET(indeterminate_name<CharT>, out.getloc())) {
0183 const indeterminate_name<CharT>& facet =
0184 BOOST_USE_FACET(indeterminate_name<CharT>, out.getloc());
0185 out << facet.name();
0186 } else {
0187 out << get_default_indeterminate_name<CharT>();
0188 }
0189 #else
0190 out << get_default_indeterminate_name<CharT>();
0191 #endif
0192 }
0193 else
0194 out << 2;
0195 }
0196 }
0197 return out;
0198 }
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 template<typename CharT, typename Traits>
0215 inline std::basic_ostream<CharT, Traits>&
0216 operator<<(std::basic_ostream<CharT, Traits>& out,
0217 bool (*)(tribool, detail::indeterminate_t))
0218 { return out << tribool(indeterminate); }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 template<typename CharT, typename Traits>
0250 inline std::basic_istream<CharT, Traits>&
0251 operator>>(std::basic_istream<CharT, Traits>& in, tribool& x)
0252 {
0253 if (in.flags() & std::ios_base::boolalpha) {
0254 typename std::basic_istream<CharT, Traits>::sentry cerberus(in);
0255 if (cerberus) {
0256 typedef std::basic_string<CharT> string_type;
0257
0258 #ifndef BOOST_NO_STD_LOCALE
0259 const std::numpunct<CharT>& numpunct_facet =
0260 BOOST_USE_FACET(std::numpunct<CharT>, in.getloc());
0261
0262 string_type falsename = numpunct_facet.falsename();
0263 string_type truename = numpunct_facet.truename();
0264
0265 string_type othername;
0266 if (BOOST_HAS_FACET(indeterminate_name<CharT>, in.getloc())) {
0267 othername =
0268 BOOST_USE_FACET(indeterminate_name<CharT>, in.getloc()).name();
0269 } else {
0270 othername = get_default_indeterminate_name<CharT>();
0271 }
0272 #else
0273 string_type falsename = default_false_name<CharT>();
0274 string_type truename = default_true_name<CharT>();
0275 string_type othername = get_default_indeterminate_name<CharT>();
0276 #endif
0277
0278 typename string_type::size_type pos = 0;
0279 bool falsename_ok = true, truename_ok = true, othername_ok = true;
0280
0281
0282 while ((falsename_ok && pos < falsename.size())
0283 || (truename_ok && pos < truename.size())
0284 || (othername_ok && pos < othername.size())) {
0285 typename Traits::int_type c = in.get();
0286 if (c == Traits::eof())
0287 return in;
0288
0289 bool matched = false;
0290 if (falsename_ok && pos < falsename.size()) {
0291 if (Traits::eq(Traits::to_char_type(c), falsename[pos]))
0292 matched = true;
0293 else
0294 falsename_ok = false;
0295 }
0296
0297 if (truename_ok && pos < truename.size()) {
0298 if (Traits::eq(Traits::to_char_type(c), truename[pos]))
0299 matched = true;
0300 else
0301 truename_ok = false;
0302 }
0303
0304 if (othername_ok && pos < othername.size()) {
0305 if (Traits::eq(Traits::to_char_type(c), othername[pos]))
0306 matched = true;
0307 else
0308 othername_ok = false;
0309 }
0310
0311 if (matched) { ++pos; }
0312 if (pos > falsename.size()) falsename_ok = false;
0313 if (pos > truename.size()) truename_ok = false;
0314 if (pos > othername.size()) othername_ok = false;
0315 }
0316
0317 if (pos == 0)
0318 in.setstate(std::ios_base::failbit);
0319 else {
0320 if (falsename_ok) x = false;
0321 else if (truename_ok) x = true;
0322 else if (othername_ok) x = indeterminate;
0323 else in.setstate(std::ios_base::failbit);
0324 }
0325 }
0326 } else {
0327 long value;
0328 if (in >> value) {
0329 switch (value) {
0330 case 0: x = false; break;
0331 case 1: x = true; break;
0332 case 2: x = indeterminate; break;
0333 default: in.setstate(std::ios_base::failbit); break;
0334 }
0335 }
0336 }
0337
0338 return in;
0339 }
0340
0341 } }
0342
0343 #endif