annotate DEPENDENCIES/generic/include/boost/logic/tribool_io.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // Three-state boolean logic library
Chris@16 2
Chris@16 3 // Copyright Douglas Gregor 2002-2004. Use, modification and
Chris@16 4 // distribution is subject to the Boost Software License, Version
Chris@16 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 #ifndef BOOST_LOGIC_TRIBOOL_IO_HPP
Chris@16 8 #define BOOST_LOGIC_TRIBOOL_IO_HPP
Chris@16 9
Chris@16 10 #include <boost/logic/tribool.hpp>
Chris@16 11 #include <boost/detail/workaround.hpp>
Chris@16 12 #include <boost/noncopyable.hpp>
Chris@16 13
Chris@16 14 #if BOOST_WORKAROUND(_MSC_VER, >= 1200)
Chris@16 15 # pragma once
Chris@16 16 #endif
Chris@16 17
Chris@16 18 #ifndef BOOST_NO_STD_LOCALE
Chris@16 19 # include <locale>
Chris@16 20 #endif
Chris@16 21
Chris@16 22 #include <string>
Chris@16 23 #include <iostream>
Chris@16 24
Chris@16 25 namespace boost { namespace logic {
Chris@16 26
Chris@16 27 #ifdef BOOST_NO_STD_LOCALE
Chris@16 28
Chris@16 29 /**
Chris@16 30 * \brief Returns a string containing the default name for the \c
Chris@16 31 * false value of a tribool with the given character type T.
Chris@16 32 *
Chris@16 33 * This function only exists when the C++ standard library
Chris@16 34 * implementation does not support locales.
Chris@16 35 */
Chris@16 36 template<typename T> std::basic_string<T> default_false_name();
Chris@16 37
Chris@16 38 /**
Chris@16 39 * \brief Returns the character string "false".
Chris@16 40 *
Chris@16 41 * This function only exists when the C++ standard library
Chris@16 42 * implementation does not support locales.
Chris@16 43 */
Chris@16 44 template<>
Chris@16 45 inline std::basic_string<char> default_false_name<char>()
Chris@16 46 { return "false"; }
Chris@16 47
Chris@16 48 # ifndef BOOST_NO_WCHAR_T
Chris@16 49 /**
Chris@16 50 * \brief Returns the wide character string L"false".
Chris@16 51 *
Chris@16 52 * This function only exists when the C++ standard library
Chris@16 53 * implementation does not support locales.
Chris@16 54 */
Chris@16 55 template<>
Chris@16 56 inline std::basic_string<wchar_t> default_false_name<wchar_t>()
Chris@16 57 { return L"false"; }
Chris@16 58 # endif
Chris@16 59
Chris@16 60 /**
Chris@16 61 * \brief Returns a string containing the default name for the \c true
Chris@16 62 * value of a tribool with the given character type T.
Chris@16 63 *
Chris@16 64 * This function only exists when the C++ standard library
Chris@16 65 * implementation does not support locales.
Chris@16 66 */
Chris@16 67 template<typename T> std::basic_string<T> default_true_name();
Chris@16 68
Chris@16 69 /**
Chris@16 70 * \brief Returns the character string "true".
Chris@16 71 *
Chris@16 72 * This function only exists when the C++ standard library
Chris@16 73 * implementation does not support locales.
Chris@16 74 */
Chris@16 75 template<>
Chris@16 76 inline std::basic_string<char> default_true_name<char>()
Chris@16 77 { return "true"; }
Chris@16 78
Chris@16 79 # ifndef BOOST_NO_WCHAR_T
Chris@16 80 /**
Chris@16 81 * \brief Returns the wide character string L"true".
Chris@16 82 *
Chris@16 83 * This function only exists * when the C++ standard library
Chris@16 84 * implementation does not support * locales.
Chris@16 85 */
Chris@16 86 template<>
Chris@16 87 inline std::basic_string<wchar_t> default_true_name<wchar_t>()
Chris@16 88 { return L"true"; }
Chris@16 89 # endif
Chris@16 90 #endif
Chris@16 91
Chris@16 92 /**
Chris@16 93 * \brief Returns a string containing the default name for the indeterminate
Chris@16 94 * value of a tribool with the given character type T.
Chris@16 95 *
Chris@16 96 * This routine is used by the input and output streaming operators
Chris@16 97 * for tribool when there is no locale support or the stream's locale
Chris@16 98 * does not contain the indeterminate_name facet.
Chris@16 99 */
Chris@16 100 template<typename T> std::basic_string<T> get_default_indeterminate_name();
Chris@16 101
Chris@16 102 /// Returns the character string "indeterminate".
Chris@16 103 template<>
Chris@16 104 inline std::basic_string<char> get_default_indeterminate_name<char>()
Chris@16 105 { return "indeterminate"; }
Chris@16 106
Chris@16 107 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
Chris@16 108 // VC++ 6.0 chokes on the specialization below, so we're stuck without
Chris@16 109 // wchar_t support. What a pain. TODO: it might just need a the template
Chris@16 110 // parameter as function parameter...
Chris@16 111 #else
Chris@16 112 # ifndef BOOST_NO_WCHAR_T
Chris@16 113 /// Returns the wide character string L"indeterminate".
Chris@16 114 template<>
Chris@16 115 inline std::basic_string<wchar_t> get_default_indeterminate_name<wchar_t>()
Chris@16 116 { return L"indeterminate"; }
Chris@16 117 # endif
Chris@16 118 #endif
Chris@16 119
Chris@16 120 // http://www.cantrip.org/locale.html
Chris@16 121
Chris@16 122 #ifndef BOOST_NO_STD_LOCALE
Chris@16 123 /**
Chris@16 124 * \brief A locale facet specifying the name of the indeterminate
Chris@16 125 * value of a tribool.
Chris@16 126 *
Chris@16 127 * The facet is used to perform I/O on tribool values when \c
Chris@16 128 * std::boolalpha has been specified. This class template is only
Chris@16 129 * available if the C++ standard library implementation supports
Chris@16 130 * locales.
Chris@16 131 */
Chris@16 132 template<typename CharT>
Chris@16 133 class indeterminate_name : public std::locale::facet, private boost::noncopyable
Chris@16 134 {
Chris@16 135 public:
Chris@16 136 typedef CharT char_type;
Chris@16 137 typedef std::basic_string<CharT> string_type;
Chris@16 138
Chris@16 139 /// Construct the facet with the default name
Chris@16 140 indeterminate_name() : name_(get_default_indeterminate_name<CharT>()) {}
Chris@16 141
Chris@16 142 /// Construct the facet with the given name for the indeterminate value
Chris@16 143 explicit indeterminate_name(const string_type& initial_name)
Chris@16 144 : name_(initial_name) {}
Chris@16 145
Chris@16 146 /// Returns the name for the indeterminate value
Chris@16 147 string_type name() const { return name_; }
Chris@16 148
Chris@16 149 /// Uniquily identifies this facet with the locale.
Chris@16 150 static std::locale::id id;
Chris@16 151
Chris@16 152 private:
Chris@16 153 string_type name_;
Chris@16 154 };
Chris@16 155
Chris@16 156 template<typename CharT> std::locale::id indeterminate_name<CharT>::id;
Chris@16 157 #endif
Chris@16 158
Chris@16 159 /**
Chris@16 160 * \brief Writes the value of a tribool to a stream.
Chris@16 161 *
Chris@16 162 * When the value of @p x is either \c true or \c false, this routine
Chris@16 163 * is semantically equivalent to:
Chris@16 164 * \code out << static_cast<bool>(x); \endcode
Chris@16 165 *
Chris@16 166 * When @p x has an indeterminate value, it outputs either the integer
Chris@16 167 * value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>)
Chris@16 168 * or the name of the indeterminate value. The name of the
Chris@16 169 * indeterminate value comes from the indeterminate_name facet (if it
Chris@16 170 * is defined in the output stream's locale), or from the
Chris@16 171 * get_default_indeterminate_name function (if it is not defined in the
Chris@16 172 * locale or if the C++ standard library implementation does not
Chris@16 173 * support locales).
Chris@16 174 *
Chris@16 175 * \returns @p out
Chris@16 176 */
Chris@16 177 template<typename CharT, typename Traits>
Chris@16 178 inline std::basic_ostream<CharT, Traits>&
Chris@16 179 operator<<(std::basic_ostream<CharT, Traits>& out, tribool x)
Chris@16 180 {
Chris@16 181 if (!indeterminate(x)) {
Chris@16 182 out << static_cast<bool>(x);
Chris@16 183 } else {
Chris@16 184 typename std::basic_ostream<CharT, Traits>::sentry cerberus(out);
Chris@16 185 if (cerberus) {
Chris@16 186 if (out.flags() & std::ios_base::boolalpha) {
Chris@16 187 #ifndef BOOST_NO_STD_LOCALE
Chris@16 188 if (BOOST_HAS_FACET(indeterminate_name<CharT>, out.getloc())) {
Chris@16 189 const indeterminate_name<CharT>& facet =
Chris@16 190 BOOST_USE_FACET(indeterminate_name<CharT>, out.getloc());
Chris@16 191 out << facet.name();
Chris@16 192 } else {
Chris@16 193 out << get_default_indeterminate_name<CharT>();
Chris@16 194 }
Chris@16 195 #else
Chris@16 196 out << get_default_indeterminate_name<CharT>();
Chris@16 197 #endif
Chris@16 198 }
Chris@16 199 else
Chris@16 200 out << 2;
Chris@16 201 }
Chris@16 202 }
Chris@16 203 return out;
Chris@16 204 }
Chris@16 205
Chris@16 206 /**
Chris@16 207 * \brief Writes the indeterminate tribool value to a stream.
Chris@16 208 *
Chris@16 209 * This routine outputs either the integer
Chris@16 210 * value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>)
Chris@16 211 * or the name of the indeterminate value. The name of the
Chris@16 212 * indeterminate value comes from the indeterminate_name facet (if it
Chris@16 213 * is defined in the output stream's locale), or from the
Chris@16 214 * get_default_indeterminate_name function (if it is not defined in the
Chris@16 215 * locale or if the C++ standard library implementation does not
Chris@16 216 * support locales).
Chris@16 217 *
Chris@16 218 * \returns @p out
Chris@16 219 */
Chris@16 220 template<typename CharT, typename Traits>
Chris@16 221 inline std::basic_ostream<CharT, Traits>&
Chris@16 222 operator<<(std::basic_ostream<CharT, Traits>& out,
Chris@16 223 bool (*)(tribool, detail::indeterminate_t))
Chris@16 224 { return out << tribool(indeterminate); }
Chris@16 225
Chris@16 226 /**
Chris@16 227 * \brief Reads a tribool value from a stream.
Chris@16 228 *
Chris@16 229 * When <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>, this
Chris@16 230 * function reads a \c long value from the input stream @p in and
Chris@16 231 * converts that value to a tribool. If that value is 0, @p x becomes
Chris@16 232 * \c false; if it is 1, @p x becomes \c true; if it is 2, @p becomes
Chris@16 233 * \c indetermine; otherwise, the operation fails (and the fail bit is
Chris@16 234 * set on the input stream @p in).
Chris@16 235 *
Chris@16 236 * When <tt>(out.flags() & std::ios_base::boolalpha) != 0</tt>, this
Chris@16 237 * function first determines the names of the false, true, and
Chris@16 238 * indeterminate values. The false and true names are extracted from
Chris@16 239 * the \c std::numpunct facet of the input stream's locale (if the C++
Chris@16 240 * standard library implementation supports locales), or from the \c
Chris@16 241 * default_false_name and \c default_true_name functions (if there is
Chris@16 242 * no locale support). The indeterminate name is extracted from the
Chris@16 243 * appropriate \c indeterminate_name facet (if it is available in the
Chris@16 244 * input stream's locale), or from the \c get_default_indeterminate_name
Chris@16 245 * function (if the C++ standard library implementation does not
Chris@16 246 * support locales, or the \c indeterminate_name facet is not
Chris@16 247 * specified for this locale object). The input is then matched to
Chris@16 248 * each of these names, and the tribool @p x is assigned the value
Chris@16 249 * corresponding to the longest name that matched. If no name is
Chris@16 250 * matched or all names are empty, the operation fails (and the fail
Chris@16 251 * bit is set on the input stream @p in).
Chris@16 252 *
Chris@16 253 * \returns @p in
Chris@16 254 */
Chris@16 255 template<typename CharT, typename Traits>
Chris@16 256 inline std::basic_istream<CharT, Traits>&
Chris@16 257 operator>>(std::basic_istream<CharT, Traits>& in, tribool& x)
Chris@16 258 {
Chris@16 259 if (in.flags() & std::ios_base::boolalpha) {
Chris@16 260 typename std::basic_istream<CharT, Traits>::sentry cerberus(in);
Chris@16 261 if (cerberus) {
Chris@16 262 typedef std::basic_string<CharT> string_type;
Chris@16 263
Chris@16 264 #ifndef BOOST_NO_STD_LOCALE
Chris@16 265 const std::numpunct<CharT>& numpunct_facet =
Chris@16 266 BOOST_USE_FACET(std::numpunct<CharT>, in.getloc());
Chris@16 267
Chris@16 268 string_type falsename = numpunct_facet.falsename();
Chris@16 269 string_type truename = numpunct_facet.truename();
Chris@16 270
Chris@16 271 string_type othername;
Chris@16 272 if (BOOST_HAS_FACET(indeterminate_name<CharT>, in.getloc())) {
Chris@16 273 othername =
Chris@16 274 BOOST_USE_FACET(indeterminate_name<CharT>, in.getloc()).name();
Chris@16 275 } else {
Chris@16 276 othername = get_default_indeterminate_name<CharT>();
Chris@16 277 }
Chris@16 278 #else
Chris@16 279 string_type falsename = default_false_name<CharT>();
Chris@16 280 string_type truename = default_true_name<CharT>();
Chris@16 281 string_type othername = get_default_indeterminate_name<CharT>();
Chris@16 282 #endif
Chris@16 283
Chris@16 284 typename string_type::size_type pos = 0;
Chris@16 285 bool falsename_ok = true, truename_ok = true, othername_ok = true;
Chris@16 286
Chris@16 287 // Modeled after the code from Library DR 17
Chris@16 288 while (falsename_ok && pos < falsename.size()
Chris@16 289 || truename_ok && pos < truename.size()
Chris@16 290 || othername_ok && pos < othername.size()) {
Chris@16 291 typename Traits::int_type c = in.get();
Chris@16 292 if (c == Traits::eof())
Chris@16 293 return in;
Chris@16 294
Chris@16 295 bool matched = false;
Chris@16 296 if (falsename_ok && pos < falsename.size()) {
Chris@16 297 if (Traits::eq(Traits::to_char_type(c), falsename[pos]))
Chris@16 298 matched = true;
Chris@16 299 else
Chris@16 300 falsename_ok = false;
Chris@16 301 }
Chris@16 302
Chris@16 303 if (truename_ok && pos < truename.size()) {
Chris@16 304 if (Traits::eq(Traits::to_char_type(c), truename[pos]))
Chris@16 305 matched = true;
Chris@16 306 else
Chris@16 307 truename_ok = false;
Chris@16 308 }
Chris@16 309
Chris@16 310 if (othername_ok && pos < othername.size()) {
Chris@16 311 if (Traits::eq(Traits::to_char_type(c), othername[pos]))
Chris@16 312 matched = true;
Chris@16 313 else
Chris@16 314 othername_ok = false;
Chris@16 315 }
Chris@16 316
Chris@16 317 if (matched) { ++pos; }
Chris@16 318 if (pos > falsename.size()) falsename_ok = false;
Chris@16 319 if (pos > truename.size()) truename_ok = false;
Chris@16 320 if (pos > othername.size()) othername_ok = false;
Chris@16 321 }
Chris@16 322
Chris@16 323 if (pos == 0)
Chris@16 324 in.setstate(std::ios_base::failbit);
Chris@16 325 else {
Chris@16 326 if (falsename_ok) x = false;
Chris@16 327 else if (truename_ok) x = true;
Chris@16 328 else if (othername_ok) x = indeterminate;
Chris@16 329 else in.setstate(std::ios_base::failbit);
Chris@16 330 }
Chris@16 331 }
Chris@16 332 } else {
Chris@16 333 long value;
Chris@16 334 if (in >> value) {
Chris@16 335 switch (value) {
Chris@16 336 case 0: x = false; break;
Chris@16 337 case 1: x = true; break;
Chris@16 338 case 2: x = indeterminate; break;
Chris@16 339 default: in.setstate(std::ios_base::failbit); break;
Chris@16 340 }
Chris@16 341 }
Chris@16 342 }
Chris@16 343
Chris@16 344 return in;
Chris@16 345 }
Chris@16 346
Chris@16 347 } } // end namespace boost::logic
Chris@16 348
Chris@16 349 #endif // BOOST_LOGIC_TRIBOOL_IO_HPP