annotate DEPENDENCIES/generic/include/boost/tuple/tuple_io.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // tuple_io.hpp --------------------------------------------------------------
Chris@16 2
Chris@16 3 // Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
Chris@16 4 // 2001 Gary Powell (gary.powell@sierra.com)
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 7 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 // For more information, see http://www.boost.org
Chris@16 10
Chris@16 11 // ----------------------------------------------------------------------------
Chris@16 12
Chris@16 13 #ifndef BOOST_TUPLE_IO_HPP
Chris@16 14 #define BOOST_TUPLE_IO_HPP
Chris@16 15
Chris@16 16 #include <istream>
Chris@16 17 #include <ostream>
Chris@16 18
Chris@16 19 #include <sstream>
Chris@16 20
Chris@16 21 #include "boost/tuple/tuple.hpp"
Chris@16 22
Chris@16 23 // This is ugly: one should be using twoargument isspace since whitspace can
Chris@16 24 // be locale dependent, in theory at least.
Chris@16 25 // not all libraries implement have the two-arg version, so we need to
Chris@16 26 // use the one-arg one, which one should get with <cctype> but there seem
Chris@16 27 // to be exceptions to this.
Chris@16 28
Chris@16 29 #if !defined (BOOST_NO_STD_LOCALE)
Chris@16 30
Chris@16 31 #include <locale> // for two-arg isspace
Chris@16 32
Chris@16 33 #else
Chris@16 34
Chris@16 35 #include <cctype> // for one-arg (old) isspace
Chris@16 36 #include <ctype.h> // Metrowerks does not find one-arg isspace from cctype
Chris@16 37
Chris@16 38 #endif
Chris@16 39
Chris@16 40 namespace boost {
Chris@16 41 namespace tuples {
Chris@16 42
Chris@16 43 namespace detail {
Chris@16 44
Chris@16 45 class format_info {
Chris@16 46 public:
Chris@16 47
Chris@16 48 enum manipulator_type { open, close, delimiter };
Chris@16 49 BOOST_STATIC_CONSTANT(int, number_of_manipulators = delimiter + 1);
Chris@16 50 private:
Chris@16 51
Chris@16 52 static int get_stream_index (int m)
Chris@16 53 {
Chris@16 54 static const int stream_index[number_of_manipulators]
Chris@16 55 = { std::ios::xalloc(), std::ios::xalloc(), std::ios::xalloc() };
Chris@16 56
Chris@16 57 return stream_index[m];
Chris@16 58 }
Chris@16 59
Chris@16 60 format_info(const format_info&);
Chris@16 61 format_info();
Chris@16 62
Chris@16 63
Chris@16 64 public:
Chris@16 65
Chris@16 66 template<class CharType, class CharTrait>
Chris@16 67 static CharType get_manipulator(std::basic_ios<CharType, CharTrait>& i,
Chris@16 68 manipulator_type m) {
Chris@16 69 // The manipulators are stored as long.
Chris@16 70 // A valid instanitation of basic_stream allows CharType to be any POD,
Chris@16 71 // hence, the static_cast may fail (it fails if long is not convertible
Chris@16 72 // to CharType
Chris@16 73 CharType c = static_cast<CharType>(i.iword(get_stream_index(m)) );
Chris@16 74 // parentheses and space are the default manipulators
Chris@16 75 if (!c) {
Chris@16 76 switch(m) {
Chris@16 77 case detail::format_info::open : c = i.widen('('); break;
Chris@16 78 case detail::format_info::close : c = i.widen(')'); break;
Chris@16 79 case detail::format_info::delimiter : c = i.widen(' '); break;
Chris@16 80 }
Chris@16 81 }
Chris@16 82 return c;
Chris@16 83 }
Chris@16 84
Chris@16 85
Chris@16 86 template<class CharType, class CharTrait>
Chris@16 87 static void set_manipulator(std::basic_ios<CharType, CharTrait>& i,
Chris@16 88 manipulator_type m, CharType c) {
Chris@16 89 // The manipulators are stored as long.
Chris@16 90 // A valid instanitation of basic_stream allows CharType to be any POD,
Chris@16 91 // hence, the static_cast may fail (it fails if CharType is not
Chris@16 92 // convertible long.
Chris@16 93 i.iword(get_stream_index(m)) = static_cast<long>(c);
Chris@16 94 }
Chris@16 95 };
Chris@16 96
Chris@16 97 } // end of namespace detail
Chris@16 98
Chris@16 99 template<class CharType>
Chris@16 100 class tuple_manipulator {
Chris@16 101 const detail::format_info::manipulator_type mt;
Chris@16 102 CharType f_c;
Chris@16 103 public:
Chris@16 104 explicit tuple_manipulator(detail::format_info::manipulator_type m,
Chris@16 105 const char c = 0)
Chris@16 106 : mt(m), f_c(c) {}
Chris@16 107
Chris@16 108 template<class CharTrait>
Chris@16 109 void set(std::basic_ios<CharType, CharTrait> &io) const {
Chris@16 110 detail::format_info::set_manipulator(io, mt, f_c);
Chris@16 111 }
Chris@16 112 };
Chris@16 113
Chris@16 114
Chris@16 115 template<class CharType, class CharTrait>
Chris@16 116 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 117 operator<<(std::basic_ostream<CharType, CharTrait>& o, const tuple_manipulator<CharType>& m) {
Chris@16 118 m.set(o);
Chris@16 119 return o;
Chris@16 120 }
Chris@16 121
Chris@16 122 template<class CharType, class CharTrait>
Chris@16 123 inline std::basic_istream<CharType, CharTrait>&
Chris@16 124 operator>>(std::basic_istream<CharType, CharTrait>& i, const tuple_manipulator<CharType>& m) {
Chris@16 125 m.set(i);
Chris@16 126 return i;
Chris@16 127 }
Chris@16 128
Chris@16 129
Chris@16 130 template<class CharType>
Chris@16 131 inline tuple_manipulator<CharType> set_open(const CharType c) {
Chris@16 132 return tuple_manipulator<CharType>(detail::format_info::open, c);
Chris@16 133 }
Chris@16 134
Chris@16 135 template<class CharType>
Chris@16 136 inline tuple_manipulator<CharType> set_close(const CharType c) {
Chris@16 137 return tuple_manipulator<CharType>(detail::format_info::close, c);
Chris@16 138 }
Chris@16 139
Chris@16 140 template<class CharType>
Chris@16 141 inline tuple_manipulator<CharType> set_delimiter(const CharType c) {
Chris@16 142 return tuple_manipulator<CharType>(detail::format_info::delimiter, c);
Chris@16 143 }
Chris@16 144
Chris@16 145
Chris@16 146
Chris@16 147
Chris@16 148
Chris@16 149 // -------------------------------------------------------------
Chris@16 150 // printing tuples to ostream in format (a b c)
Chris@16 151 // parentheses and space are defaults, but can be overriden with manipulators
Chris@16 152 // set_open, set_close and set_delimiter
Chris@16 153
Chris@16 154 namespace detail {
Chris@16 155
Chris@16 156 // Note: The order of the print functions is critical
Chris@16 157 // to let a conforming compiler find and select the correct one.
Chris@16 158
Chris@16 159
Chris@16 160 template<class CharType, class CharTrait, class T1>
Chris@16 161 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 162 print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, null_type>& t) {
Chris@16 163 return o << t.head;
Chris@16 164 }
Chris@16 165
Chris@16 166
Chris@16 167 template<class CharType, class CharTrait>
Chris@16 168 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 169 print(std::basic_ostream<CharType, CharTrait>& o, const null_type&) {
Chris@16 170 return o;
Chris@16 171 }
Chris@16 172
Chris@16 173 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 174 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 175 print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
Chris@16 176
Chris@16 177 const CharType d = format_info::get_manipulator(o, format_info::delimiter);
Chris@16 178
Chris@16 179 o << t.head;
Chris@16 180
Chris@16 181 o << d;
Chris@16 182
Chris@16 183 return print(o, t.tail);
Chris@16 184 }
Chris@16 185
Chris@16 186 template<class CharT, class Traits, class T>
Chris@16 187 inline bool handle_width(std::basic_ostream<CharT, Traits>& o, const T& t) {
Chris@16 188 std::streamsize width = o.width();
Chris@16 189 if(width == 0) return false;
Chris@16 190
Chris@16 191 std::basic_ostringstream<CharT, Traits> ss;
Chris@16 192
Chris@16 193 ss.copyfmt(o);
Chris@16 194 ss.tie(0);
Chris@16 195 ss.width(0);
Chris@16 196
Chris@16 197 ss << t;
Chris@16 198 o << ss.str();
Chris@16 199
Chris@16 200 return true;
Chris@16 201 }
Chris@16 202
Chris@16 203
Chris@16 204 } // namespace detail
Chris@16 205
Chris@16 206
Chris@16 207 template<class CharType, class CharTrait>
Chris@16 208 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 209 operator<<(std::basic_ostream<CharType, CharTrait>& o,
Chris@16 210 const null_type& t) {
Chris@16 211 if (!o.good() ) return o;
Chris@16 212 if (detail::handle_width(o, t)) return o;
Chris@16 213
Chris@16 214 const CharType l =
Chris@16 215 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 216 const CharType r =
Chris@16 217 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 218
Chris@16 219 o << l;
Chris@16 220 o << r;
Chris@16 221
Chris@16 222 return o;
Chris@16 223 }
Chris@16 224
Chris@16 225 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 226 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 227 operator<<(std::basic_ostream<CharType, CharTrait>& o,
Chris@16 228 const cons<T1, T2>& t) {
Chris@16 229 if (!o.good() ) return o;
Chris@16 230 if (detail::handle_width(o, t)) return o;
Chris@16 231
Chris@16 232 const CharType l =
Chris@16 233 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 234 const CharType r =
Chris@16 235 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 236
Chris@16 237 o << l;
Chris@16 238
Chris@16 239 detail::print(o, t);
Chris@16 240
Chris@16 241 o << r;
Chris@16 242
Chris@16 243 return o;
Chris@16 244 }
Chris@16 245
Chris@16 246
Chris@16 247 // -------------------------------------------------------------
Chris@16 248 // input stream operators
Chris@16 249
Chris@16 250 namespace detail {
Chris@16 251
Chris@16 252
Chris@16 253 template<class CharType, class CharTrait>
Chris@16 254 inline std::basic_istream<CharType, CharTrait>&
Chris@16 255 extract_and_check_delimiter(
Chris@16 256 std::basic_istream<CharType, CharTrait> &is, format_info::manipulator_type del)
Chris@16 257 {
Chris@16 258 const CharType d = format_info::get_manipulator(is, del);
Chris@16 259
Chris@16 260 #if defined (BOOST_NO_STD_LOCALE)
Chris@16 261 const bool is_delimiter = !isspace(d);
Chris@16 262 #elif defined ( __BORLANDC__ )
Chris@16 263 const bool is_delimiter = !std::use_facet< std::ctype< CharType > >
Chris@16 264 (is.getloc() ).is( std::ctype_base::space, d);
Chris@16 265 #else
Chris@16 266 const bool is_delimiter = (!std::isspace(d, is.getloc()) );
Chris@16 267 #endif
Chris@16 268
Chris@16 269 CharType c;
Chris@16 270 if (is_delimiter) {
Chris@16 271 is >> c;
Chris@16 272 if (is.good() && c!=d) {
Chris@16 273 is.setstate(std::ios::failbit);
Chris@16 274 }
Chris@16 275 } else {
Chris@16 276 is >> std::ws;
Chris@16 277 }
Chris@16 278 return is;
Chris@16 279 }
Chris@16 280
Chris@16 281
Chris@16 282 template<class CharType, class CharTrait, class T1>
Chris@16 283 inline std::basic_istream<CharType, CharTrait> &
Chris@16 284 read (std::basic_istream<CharType, CharTrait> &is, cons<T1, null_type>& t1) {
Chris@16 285
Chris@16 286 if (!is.good()) return is;
Chris@16 287
Chris@16 288 return is >> t1.head;
Chris@16 289 }
Chris@16 290
Chris@16 291 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 292 inline std::basic_istream<CharType, CharTrait>&
Chris@16 293 read(std::basic_istream<CharType, CharTrait> &is, cons<T1, T2>& t1) {
Chris@16 294
Chris@16 295 if (!is.good()) return is;
Chris@16 296
Chris@16 297 is >> t1.head;
Chris@16 298
Chris@16 299
Chris@16 300 extract_and_check_delimiter(is, format_info::delimiter);
Chris@16 301
Chris@16 302 return read(is, t1.tail);
Chris@16 303 }
Chris@16 304
Chris@16 305 } // end namespace detail
Chris@16 306
Chris@16 307
Chris@16 308 template<class CharType, class CharTrait>
Chris@16 309 inline std::basic_istream<CharType, CharTrait>&
Chris@16 310 operator>>(std::basic_istream<CharType, CharTrait> &is, null_type&) {
Chris@16 311
Chris@16 312 if (!is.good() ) return is;
Chris@16 313
Chris@16 314 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 315 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 316
Chris@16 317 return is;
Chris@16 318 }
Chris@16 319
Chris@16 320 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 321 inline std::basic_istream<CharType, CharTrait>&
Chris@16 322 operator>>(std::basic_istream<CharType, CharTrait>& is, cons<T1, T2>& t1) {
Chris@16 323
Chris@16 324 if (!is.good() ) return is;
Chris@16 325
Chris@16 326 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 327
Chris@16 328 detail::read(is, t1);
Chris@16 329
Chris@16 330 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 331
Chris@16 332 return is;
Chris@16 333 }
Chris@16 334
Chris@16 335
Chris@16 336 } // end of namespace tuples
Chris@16 337 } // end of namespace boost
Chris@16 338
Chris@16 339 #endif // BOOST_TUPLE_IO_HPP
Chris@16 340
Chris@16 341