annotate DEPENDENCIES/generic/include/boost/tuple/tuple_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 // 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
Chris@16 17 // add to boost/config.hpp
Chris@16 18 // for now
Chris@16 19 # if defined __GNUC__
Chris@16 20 # if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97)
Chris@16 21 #define BOOST_NO_TEMPLATED_STREAMS
Chris@16 22 #endif
Chris@16 23 #endif // __GNUC__
Chris@16 24
Chris@16 25 #if defined BOOST_NO_TEMPLATED_STREAMS
Chris@16 26 #include <iostream>
Chris@16 27 #else
Chris@16 28 #include <istream>
Chris@16 29 #include <ostream>
Chris@16 30 #endif
Chris@16 31
Chris@16 32 #include <sstream>
Chris@16 33
Chris@16 34 #include "boost/tuple/tuple.hpp"
Chris@16 35
Chris@16 36 // This is ugly: one should be using twoargument isspace since whitspace can
Chris@16 37 // be locale dependent, in theory at least.
Chris@16 38 // not all libraries implement have the two-arg version, so we need to
Chris@16 39 // use the one-arg one, which one should get with <cctype> but there seem
Chris@16 40 // to be exceptions to this.
Chris@16 41
Chris@16 42 #if !defined (BOOST_NO_STD_LOCALE)
Chris@16 43
Chris@16 44 #include <locale> // for two-arg isspace
Chris@16 45
Chris@16 46 #else
Chris@16 47
Chris@16 48 #include <cctype> // for one-arg (old) isspace
Chris@16 49 #include <ctype.h> // Metrowerks does not find one-arg isspace from cctype
Chris@16 50
Chris@16 51 #endif
Chris@16 52
Chris@16 53 namespace boost {
Chris@16 54 namespace tuples {
Chris@16 55
Chris@16 56 namespace detail {
Chris@16 57
Chris@16 58 class format_info {
Chris@16 59 public:
Chris@16 60
Chris@16 61 enum manipulator_type { open, close, delimiter };
Chris@16 62 BOOST_STATIC_CONSTANT(int, number_of_manipulators = delimiter + 1);
Chris@16 63 private:
Chris@16 64
Chris@16 65 static int get_stream_index (int m)
Chris@16 66 {
Chris@16 67 static const int stream_index[number_of_manipulators]
Chris@16 68 = { std::ios::xalloc(), std::ios::xalloc(), std::ios::xalloc() };
Chris@16 69
Chris@16 70 return stream_index[m];
Chris@16 71 }
Chris@16 72
Chris@16 73 format_info(const format_info&);
Chris@16 74 format_info();
Chris@16 75
Chris@16 76
Chris@16 77 public:
Chris@16 78
Chris@16 79 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 80 static char get_manipulator(std::ios& i, manipulator_type m) {
Chris@16 81 char c = static_cast<char>(i.iword(get_stream_index(m)));
Chris@16 82
Chris@16 83 // parentheses and space are the default manipulators
Chris@16 84 if (!c) {
Chris@16 85 switch(m) {
Chris@16 86 case detail::format_info::open : c = '('; break;
Chris@16 87 case detail::format_info::close : c = ')'; break;
Chris@16 88 case detail::format_info::delimiter : c = ' '; break;
Chris@16 89 }
Chris@16 90 }
Chris@16 91 return c;
Chris@16 92 }
Chris@16 93
Chris@16 94 static void set_manipulator(std::ios& i, manipulator_type m, char c) {
Chris@16 95 i.iword(get_stream_index(m)) = static_cast<long>(c);
Chris@16 96 }
Chris@16 97 #else
Chris@16 98 template<class CharType, class CharTrait>
Chris@16 99 static CharType get_manipulator(std::basic_ios<CharType, CharTrait>& i,
Chris@16 100 manipulator_type m) {
Chris@16 101 // The manipulators are stored as long.
Chris@16 102 // A valid instanitation of basic_stream allows CharType to be any POD,
Chris@16 103 // hence, the static_cast may fail (it fails if long is not convertible
Chris@16 104 // to CharType
Chris@16 105 CharType c = static_cast<CharType>(i.iword(get_stream_index(m)) );
Chris@16 106 // parentheses and space are the default manipulators
Chris@16 107 if (!c) {
Chris@16 108 switch(m) {
Chris@16 109 case detail::format_info::open : c = i.widen('('); break;
Chris@16 110 case detail::format_info::close : c = i.widen(')'); break;
Chris@16 111 case detail::format_info::delimiter : c = i.widen(' '); break;
Chris@16 112 }
Chris@16 113 }
Chris@16 114 return c;
Chris@16 115 }
Chris@16 116
Chris@16 117
Chris@16 118 template<class CharType, class CharTrait>
Chris@16 119 static void set_manipulator(std::basic_ios<CharType, CharTrait>& i,
Chris@16 120 manipulator_type m, CharType c) {
Chris@16 121 // The manipulators are stored as long.
Chris@16 122 // A valid instanitation of basic_stream allows CharType to be any POD,
Chris@16 123 // hence, the static_cast may fail (it fails if CharType is not
Chris@16 124 // convertible long.
Chris@16 125 i.iword(get_stream_index(m)) = static_cast<long>(c);
Chris@16 126 }
Chris@16 127 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 128 };
Chris@16 129
Chris@16 130 } // end of namespace detail
Chris@16 131
Chris@16 132 template<class CharType>
Chris@16 133 class tuple_manipulator {
Chris@16 134 const detail::format_info::manipulator_type mt;
Chris@16 135 CharType f_c;
Chris@16 136 public:
Chris@16 137 explicit tuple_manipulator(detail::format_info::manipulator_type m,
Chris@16 138 const char c = 0)
Chris@16 139 : mt(m), f_c(c) {}
Chris@16 140
Chris@16 141 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 142 void set(std::ios &io) const {
Chris@16 143 detail::format_info::set_manipulator(io, mt, f_c);
Chris@16 144 }
Chris@16 145 #else
Chris@16 146 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 147 template<class CharType2, class CharTrait>
Chris@16 148 void set(std::basic_ios<CharType2, CharTrait> &io) const {
Chris@16 149 detail::format_info::set_manipulator(io, mt, f_c);
Chris@16 150 }
Chris@16 151 #else
Chris@16 152 template<class CharTrait>
Chris@16 153 void set(std::basic_ios<CharType, CharTrait> &io) const {
Chris@16 154 detail::format_info::set_manipulator(io, mt, f_c);
Chris@16 155 }
Chris@16 156 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 157 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 158 };
Chris@16 159
Chris@16 160 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 161 inline std::ostream&
Chris@16 162 operator<<(std::ostream& o, const tuple_manipulator<char>& m) {
Chris@16 163 m.set(o);
Chris@16 164 return o;
Chris@16 165 }
Chris@16 166
Chris@16 167 inline std::istream&
Chris@16 168 operator>>(std::istream& i, const tuple_manipulator<char>& m) {
Chris@16 169 m.set(i);
Chris@16 170 return i;
Chris@16 171 }
Chris@16 172
Chris@16 173 #else
Chris@16 174
Chris@16 175 template<class CharType, class CharTrait>
Chris@16 176 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 177 operator<<(std::basic_ostream<CharType, CharTrait>& o, const tuple_manipulator<CharType>& m) {
Chris@16 178 m.set(o);
Chris@16 179 return o;
Chris@16 180 }
Chris@16 181
Chris@16 182 template<class CharType, class CharTrait>
Chris@16 183 inline std::basic_istream<CharType, CharTrait>&
Chris@16 184 operator>>(std::basic_istream<CharType, CharTrait>& i, const tuple_manipulator<CharType>& m) {
Chris@16 185 m.set(i);
Chris@16 186 return i;
Chris@16 187 }
Chris@16 188
Chris@16 189 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 190
Chris@16 191 template<class CharType>
Chris@16 192 inline tuple_manipulator<CharType> set_open(const CharType c) {
Chris@16 193 return tuple_manipulator<CharType>(detail::format_info::open, c);
Chris@16 194 }
Chris@16 195
Chris@16 196 template<class CharType>
Chris@16 197 inline tuple_manipulator<CharType> set_close(const CharType c) {
Chris@16 198 return tuple_manipulator<CharType>(detail::format_info::close, c);
Chris@16 199 }
Chris@16 200
Chris@16 201 template<class CharType>
Chris@16 202 inline tuple_manipulator<CharType> set_delimiter(const CharType c) {
Chris@16 203 return tuple_manipulator<CharType>(detail::format_info::delimiter, c);
Chris@16 204 }
Chris@16 205
Chris@16 206
Chris@16 207
Chris@16 208
Chris@16 209
Chris@16 210 // -------------------------------------------------------------
Chris@16 211 // printing tuples to ostream in format (a b c)
Chris@16 212 // parentheses and space are defaults, but can be overriden with manipulators
Chris@16 213 // set_open, set_close and set_delimiter
Chris@16 214
Chris@16 215 namespace detail {
Chris@16 216
Chris@16 217 // Note: The order of the print functions is critical
Chris@16 218 // to let a conforming compiler find and select the correct one.
Chris@16 219
Chris@16 220 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 221
Chris@16 222 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 223 template<class T1>
Chris@16 224 inline std::ostream& print(std::ostream& o, const cons<T1, null_type>& t) {
Chris@16 225 return o << t.head;
Chris@16 226 }
Chris@16 227 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 228
Chris@16 229 inline std::ostream& print(std::ostream& o, const null_type&) { return o; }
Chris@16 230
Chris@16 231 template<class T1, class T2>
Chris@16 232 inline std::ostream&
Chris@16 233 print(std::ostream& o, const cons<T1, T2>& t) {
Chris@16 234
Chris@16 235 const char d = format_info::get_manipulator(o, format_info::delimiter);
Chris@16 236
Chris@16 237 o << t.head;
Chris@16 238
Chris@16 239 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 240 if (tuples::length<T2>::value == 0)
Chris@16 241 return o;
Chris@16 242 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 243 o << d;
Chris@16 244
Chris@16 245 return print(o, t.tail );
Chris@16 246
Chris@16 247 }
Chris@16 248
Chris@16 249 template<class T>
Chris@16 250 inline bool handle_width(std::ostream& o, const T& t) {
Chris@16 251 std::streamsize width = o.width();
Chris@16 252 if(width == 0) return false;
Chris@16 253
Chris@16 254 std::ostringstream ss;
Chris@16 255
Chris@16 256 ss.copyfmt(o);
Chris@16 257 ss.tie(0);
Chris@16 258 ss.width(0);
Chris@16 259
Chris@16 260 ss << t;
Chris@16 261 o << ss.str();
Chris@16 262
Chris@16 263 return true;
Chris@16 264 }
Chris@16 265
Chris@16 266
Chris@16 267 #else
Chris@16 268
Chris@16 269 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 270 template<class CharType, class CharTrait, class T1>
Chris@16 271 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 272 print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, null_type>& t) {
Chris@16 273 return o << t.head;
Chris@16 274 }
Chris@16 275 #endif // !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 276
Chris@16 277
Chris@16 278 template<class CharType, class CharTrait>
Chris@16 279 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 280 print(std::basic_ostream<CharType, CharTrait>& o, const null_type&) {
Chris@16 281 return o;
Chris@16 282 }
Chris@16 283
Chris@16 284 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 285 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 286 print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
Chris@16 287
Chris@16 288 const CharType d = format_info::get_manipulator(o, format_info::delimiter);
Chris@16 289
Chris@16 290 o << t.head;
Chris@16 291
Chris@16 292 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 293 if (tuples::length<T2>::value == 0)
Chris@16 294 return o;
Chris@16 295 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 296 o << d;
Chris@16 297
Chris@16 298 return print(o, t.tail);
Chris@16 299 }
Chris@16 300
Chris@16 301 template<class CharT, class Traits, class T>
Chris@16 302 inline bool handle_width(std::basic_ostream<CharT, Traits>& o, const T& t) {
Chris@16 303 std::streamsize width = o.width();
Chris@16 304 if(width == 0) return false;
Chris@16 305
Chris@16 306 std::basic_ostringstream<CharT, Traits> ss;
Chris@16 307
Chris@16 308 ss.copyfmt(o);
Chris@16 309 ss.tie(0);
Chris@16 310 ss.width(0);
Chris@16 311
Chris@16 312 ss << t;
Chris@16 313 o << ss.str();
Chris@16 314
Chris@16 315 return true;
Chris@16 316 }
Chris@16 317
Chris@16 318 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 319
Chris@16 320 } // namespace detail
Chris@16 321
Chris@16 322 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 323
Chris@16 324 inline std::ostream& operator<<(std::ostream& o, const null_type& t) {
Chris@16 325 if (!o.good() ) return o;
Chris@16 326 if (detail::handle_width(o, t)) return o;
Chris@16 327
Chris@16 328 const char l =
Chris@16 329 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 330 const char r =
Chris@16 331 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 332
Chris@16 333 o << l;
Chris@16 334 o << r;
Chris@16 335
Chris@16 336 return o;
Chris@16 337 }
Chris@16 338
Chris@16 339 template<class T1, class T2>
Chris@16 340 inline std::ostream& operator<<(std::ostream& o, const cons<T1, T2>& t) {
Chris@16 341 if (!o.good() ) return o;
Chris@16 342 if (detail::handle_width(o, t)) return o;
Chris@16 343
Chris@16 344 const char l =
Chris@16 345 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 346 const char r =
Chris@16 347 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 348
Chris@16 349 o << l;
Chris@16 350
Chris@16 351 detail::print(o, t);
Chris@16 352
Chris@16 353 o << r;
Chris@16 354
Chris@16 355 return o;
Chris@16 356 }
Chris@16 357
Chris@16 358 #else
Chris@16 359
Chris@16 360 template<class CharType, class CharTrait>
Chris@16 361 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 362 operator<<(std::basic_ostream<CharType, CharTrait>& o,
Chris@16 363 const null_type& t) {
Chris@16 364 if (!o.good() ) return o;
Chris@16 365 if (detail::handle_width(o, t)) return o;
Chris@16 366
Chris@16 367 const CharType l =
Chris@16 368 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 369 const CharType r =
Chris@16 370 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 371
Chris@16 372 o << l;
Chris@16 373 o << r;
Chris@16 374
Chris@16 375 return o;
Chris@16 376 }
Chris@16 377
Chris@16 378 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 379 inline std::basic_ostream<CharType, CharTrait>&
Chris@16 380 operator<<(std::basic_ostream<CharType, CharTrait>& o,
Chris@16 381 const cons<T1, T2>& t) {
Chris@16 382 if (!o.good() ) return o;
Chris@16 383 if (detail::handle_width(o, t)) return o;
Chris@16 384
Chris@16 385 const CharType l =
Chris@16 386 detail::format_info::get_manipulator(o, detail::format_info::open);
Chris@16 387 const CharType r =
Chris@16 388 detail::format_info::get_manipulator(o, detail::format_info::close);
Chris@16 389
Chris@16 390 o << l;
Chris@16 391
Chris@16 392 detail::print(o, t);
Chris@16 393
Chris@16 394 o << r;
Chris@16 395
Chris@16 396 return o;
Chris@16 397 }
Chris@16 398 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 399
Chris@16 400
Chris@16 401 // -------------------------------------------------------------
Chris@16 402 // input stream operators
Chris@16 403
Chris@16 404 namespace detail {
Chris@16 405
Chris@16 406 #if defined (BOOST_NO_TEMPLATED_STREAMS)
Chris@16 407
Chris@16 408 inline std::istream&
Chris@16 409 extract_and_check_delimiter(
Chris@16 410 std::istream& is, format_info::manipulator_type del)
Chris@16 411 {
Chris@16 412 const char d = format_info::get_manipulator(is, del);
Chris@16 413
Chris@16 414 #if defined (BOOST_NO_STD_LOCALE)
Chris@16 415 const bool is_delimiter = !isspace(d);
Chris@16 416 #else
Chris@16 417 const bool is_delimiter = (!std::isspace(d, is.getloc()) );
Chris@16 418 #endif
Chris@16 419
Chris@16 420 char c;
Chris@16 421 if (is_delimiter) {
Chris@16 422 is >> c;
Chris@16 423 if (is.good() && c!=d) {
Chris@16 424 is.setstate(std::ios::failbit);
Chris@16 425 }
Chris@16 426 } else {
Chris@16 427 is >> std::ws;
Chris@16 428 }
Chris@16 429 return is;
Chris@16 430 }
Chris@16 431
Chris@16 432
Chris@16 433 // Note: The order of the read functions is critical to let a
Chris@16 434 // (conforming?) compiler find and select the correct one.
Chris@16 435
Chris@16 436 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 437 template<class T1>
Chris@16 438 inline std::istream &
Chris@16 439 read (std::istream &is, cons<T1, null_type>& t1) {
Chris@16 440
Chris@16 441 if (!is.good()) return is;
Chris@16 442
Chris@16 443 return is >> t1.head ;
Chris@16 444 }
Chris@16 445 #else
Chris@16 446 inline std::istream& read(std::istream& i, const null_type&) { return i; }
Chris@16 447 #endif // !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 448
Chris@16 449 template<class T1, class T2>
Chris@16 450 inline std::istream&
Chris@16 451 read(std::istream &is, cons<T1, T2>& t1) {
Chris@16 452
Chris@16 453 if (!is.good()) return is;
Chris@16 454
Chris@16 455 is >> t1.head;
Chris@16 456
Chris@16 457 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 458 if (tuples::length<T2>::value == 0)
Chris@16 459 return is;
Chris@16 460 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 461
Chris@16 462 extract_and_check_delimiter(is, format_info::delimiter);
Chris@16 463
Chris@16 464 return read(is, t1.tail);
Chris@16 465 }
Chris@16 466
Chris@16 467 } // end namespace detail
Chris@16 468
Chris@16 469 inline std::istream&
Chris@16 470 operator>>(std::istream &is, null_type&) {
Chris@16 471
Chris@16 472 if (!is.good() ) return is;
Chris@16 473
Chris@16 474 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 475 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 476
Chris@16 477 return is;
Chris@16 478 }
Chris@16 479
Chris@16 480
Chris@16 481 template<class T1, class T2>
Chris@16 482 inline std::istream&
Chris@16 483 operator>>(std::istream& is, cons<T1, T2>& t1) {
Chris@16 484
Chris@16 485 if (!is.good() ) return is;
Chris@16 486
Chris@16 487 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 488
Chris@16 489 detail::read(is, t1);
Chris@16 490
Chris@16 491 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 492
Chris@16 493 return is;
Chris@16 494 }
Chris@16 495
Chris@16 496
Chris@16 497
Chris@16 498 #else
Chris@16 499
Chris@16 500 template<class CharType, class CharTrait>
Chris@16 501 inline std::basic_istream<CharType, CharTrait>&
Chris@16 502 extract_and_check_delimiter(
Chris@16 503 std::basic_istream<CharType, CharTrait> &is, format_info::manipulator_type del)
Chris@16 504 {
Chris@16 505 const CharType d = format_info::get_manipulator(is, del);
Chris@16 506
Chris@16 507 #if defined (BOOST_NO_STD_LOCALE)
Chris@16 508 const bool is_delimiter = !isspace(d);
Chris@16 509 #elif defined ( __BORLANDC__ )
Chris@16 510 const bool is_delimiter = !std::use_facet< std::ctype< CharType > >
Chris@16 511 (is.getloc() ).is( std::ctype_base::space, d);
Chris@16 512 #else
Chris@16 513 const bool is_delimiter = (!std::isspace(d, is.getloc()) );
Chris@16 514 #endif
Chris@16 515
Chris@16 516 CharType c;
Chris@16 517 if (is_delimiter) {
Chris@16 518 is >> c;
Chris@16 519 if (is.good() && c!=d) {
Chris@16 520 is.setstate(std::ios::failbit);
Chris@16 521 }
Chris@16 522 } else {
Chris@16 523 is >> std::ws;
Chris@16 524 }
Chris@16 525 return is;
Chris@16 526 }
Chris@16 527
Chris@16 528
Chris@16 529 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 530 template<class CharType, class CharTrait, class T1>
Chris@16 531 inline std::basic_istream<CharType, CharTrait> &
Chris@16 532 read (std::basic_istream<CharType, CharTrait> &is, cons<T1, null_type>& t1) {
Chris@16 533
Chris@16 534 if (!is.good()) return is;
Chris@16 535
Chris@16 536 return is >> t1.head;
Chris@16 537 }
Chris@16 538 #else
Chris@16 539 template<class CharType, class CharTrait>
Chris@16 540 inline std::basic_istream<CharType, CharTrait>&
Chris@16 541 read(std::basic_istream<CharType, CharTrait>& i, const null_type&) { return i; }
Chris@16 542
Chris@16 543 #endif // !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 544
Chris@16 545 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 546 inline std::basic_istream<CharType, CharTrait>&
Chris@16 547 read(std::basic_istream<CharType, CharTrait> &is, cons<T1, T2>& t1) {
Chris@16 548
Chris@16 549 if (!is.good()) return is;
Chris@16 550
Chris@16 551 is >> t1.head;
Chris@16 552
Chris@16 553 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 554 if (tuples::length<T2>::value == 0)
Chris@16 555 return is;
Chris@16 556 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 557
Chris@16 558 extract_and_check_delimiter(is, format_info::delimiter);
Chris@16 559
Chris@16 560 return read(is, t1.tail);
Chris@16 561 }
Chris@16 562
Chris@16 563 } // end namespace detail
Chris@16 564
Chris@16 565
Chris@16 566 template<class CharType, class CharTrait>
Chris@16 567 inline std::basic_istream<CharType, CharTrait>&
Chris@16 568 operator>>(std::basic_istream<CharType, CharTrait> &is, null_type&) {
Chris@16 569
Chris@16 570 if (!is.good() ) return is;
Chris@16 571
Chris@16 572 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 573 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 574
Chris@16 575 return is;
Chris@16 576 }
Chris@16 577
Chris@16 578 template<class CharType, class CharTrait, class T1, class T2>
Chris@16 579 inline std::basic_istream<CharType, CharTrait>&
Chris@16 580 operator>>(std::basic_istream<CharType, CharTrait>& is, cons<T1, T2>& t1) {
Chris@16 581
Chris@16 582 if (!is.good() ) return is;
Chris@16 583
Chris@16 584 detail::extract_and_check_delimiter(is, detail::format_info::open);
Chris@16 585
Chris@16 586 detail::read(is, t1);
Chris@16 587
Chris@16 588 detail::extract_and_check_delimiter(is, detail::format_info::close);
Chris@16 589
Chris@16 590 return is;
Chris@16 591 }
Chris@16 592
Chris@16 593 #endif // BOOST_NO_TEMPLATED_STREAMS
Chris@16 594
Chris@16 595 } // end of namespace tuples
Chris@16 596 } // end of namespace boost
Chris@16 597
Chris@16 598 #endif // BOOST_TUPLE_IO_HPP
Chris@16 599
Chris@16 600