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