00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cctype>
00044 #include "extended_string.h"
00045
00046
00047
00048 namespace lass
00049 {
00050 namespace stde
00051 {
00052 namespace impl
00053 {
00054
00055
00056
00057
00058 template <typename Char, typename Traits>
00059 void eat_whitespace(std::basic_istream<Char, Traits>& stream)
00060 {
00061 Char c = 0;
00062 while (stream.get(c))
00063 {
00064 if (!std::isspace(c))
00065 {
00066 stream.putback(c);
00067 break;
00068 }
00069 }
00070 }
00071
00072
00073
00074
00075 struct sequence_traits
00076 {
00077 template <typename Container, typename T>
00078 static void push(Container& container, const T& value)
00079 {
00080 container.push_back(value);
00081 }
00082 template <typename Container>
00083 static void temp_to_output(Container& temp, Container& output)
00084 {
00085 temp.swap(output);
00086 }
00087 };
00088
00089
00090
00091
00092 struct set_traits
00093 {
00094 template <typename Container, typename T>
00095 static void push(Container& container, const T& value)
00096 {
00097 container.insert(value);
00098 }
00099 template <typename Container>
00100 static void temp_to_output(Container& temp, Container& output)
00101 {
00102 temp.swap(output);
00103 }
00104 };
00105
00106
00107
00108
00109
00110 struct value_traits
00111 {
00112 template <typename Char, typename Traits, typename T>
00113 static bool read(
00114 std::basic_istream<Char, Traits>& stream, T& value,
00115 Char inter_seperator, Char , Char closer)
00116 {
00117 eat_whitespace(stream);
00118
00119
00120
00121 std::basic_string<Char, Traits> buffer;
00122 Char c = 0;
00123 while (stream.get(c))
00124 {
00125 if (c == inter_seperator || c == closer)
00126 {
00127 stream.putback(c);
00128 break;
00129 }
00130 buffer += c;
00131 }
00132
00133
00134
00135 return cast(buffer, value);
00136
00137 }
00138 private:
00139 static bool cast(const std::string& buffer, std::string& value)
00140 {
00141 value = rstrip(buffer);
00142 return true;
00143 }
00144 template <typename T>
00145 static bool cast(const std::string& buffer, T& value)
00146 {
00147 std::stringstream buffer_stream(buffer);
00148 if (std::numeric_limits<T>::is_specialized)
00149 {
00150 buffer_stream.precision(std::numeric_limits<T>::digits10 + 1);
00151 }
00152 return buffer_stream >> value && (buffer_stream >> std::ws).eof();
00153 }
00154 };
00155
00156
00157
00158
00159
00160 struct pair_traits
00161 {
00162 template <typename Char, typename Traits, typename T, typename U>
00163 static bool read(
00164 std::basic_istream<Char, Traits>& stream, std::pair<T, U>& value,
00165 Char inter_seperator, Char intra_seperator, Char closer)
00166 {
00167 if (!value_traits::read<Char>(stream, value.first, intra_seperator, 0, intra_seperator))
00168 {
00169 return false;
00170 }
00171 stream.ignore();
00172 if (!value_traits::read<Char>(stream, value.second, inter_seperator, 0, closer))
00173 {
00174 return false;
00175 }
00176 return true;
00177 }
00178 };
00179
00180
00181
00182
00183 template <typename Iterator, typename Char, typename Traits>
00184 std::basic_ostream<Char, Traits>& print_sequence(
00185 std::basic_ostream<Char, Traits>& stream, Iterator begin, Iterator end,
00186 const Char* opener, const Char* seperator, const Char* closer)
00187 {
00188 std::basic_ostringstream<Char, Traits> buffer;
00189 buffer.copyfmt(stream);
00190 buffer.width(0);
00191
00192 buffer << opener;
00193 for (Iterator i = begin; i != end; ++i)
00194 {
00195 if (i != begin)
00196 {
00197 buffer << seperator;
00198 }
00199 buffer << *i;
00200 }
00201 buffer << closer;
00202
00203 LASS_ENFORCE_STREAM(stream) << buffer.str();
00204 return stream;
00205 }
00206
00207
00208
00209
00210 template <typename Char, typename Traits, typename Iterator>
00211 std::basic_ostream<Char, Traits>& print_map(
00212 std::basic_ostream<Char, Traits>& stream, Iterator begin, Iterator end,
00213 const Char* opener, const Char* seperator_1, const Char* seperator_2, const Char* closer)
00214 {
00215 std::basic_ostringstream<Char, Traits> buffer;
00216 buffer.copyfmt(stream);
00217 buffer.width(0);
00218
00219 buffer << opener;
00220 for (Iterator i = begin; i != end; ++i)
00221 {
00222 if (i != begin)
00223 {
00224 buffer << seperator_1;
00225 }
00226 buffer << i->first << seperator_2 << i->second;
00227 }
00228 buffer << closer;
00229
00230 LASS_ENFORCE_STREAM(stream) << buffer.str();
00231 return stream;
00232 }
00233
00234
00235
00236
00237 template
00238 <
00239 typename ContainerTraits, typename DataTraits, typename T,
00240 typename Char, typename Traits,
00241 typename Container
00242 >
00243 std::basic_istream<Char, Traits>& read_container(
00244 std::basic_istream<Char, Traits>& stream, Container& container,
00245 Char opener, Char inter_seperator, Char intra_seperator, Char closer)
00246 {
00247 Container result;
00248
00249 bool good = true;
00250 Char c = 0;
00251 eat_whitespace(stream);
00252 if (stream.get(c))
00253 {
00254 if (c == opener)
00255 {
00256 T temp;
00257 good = DataTraits::read(stream, temp, inter_seperator, intra_seperator, closer);
00258 if (good)
00259 {
00260 ContainerTraits::push(result, temp);
00261 }
00262 }
00263 else
00264 {
00265 stream.putback(c);
00266 good = false;
00267 }
00268 }
00269 else
00270 {
00271 good = false;
00272 }
00273
00274 while (good && stream.get(c) && c != closer)
00275 {
00276 if (c == inter_seperator)
00277 {
00278 T temp;
00279 good = DataTraits::read(stream, temp, inter_seperator, intra_seperator, closer);
00280 if (good)
00281 {
00282 ContainerTraits::push(result, temp);
00283 }
00284 }
00285 else
00286 {
00287 stream.putback(c);
00288 good = false;
00289 }
00290 }
00291
00292 if (good)
00293 {
00294 ContainerTraits::temp_to_output(result, container);
00295 }
00296 else
00297 {
00298 stream.clear(std::ios::failbit);
00299 }
00300
00301 return stream;
00302 }
00303
00304 }
00305
00306 }
00307
00308 }
00309
00310
00311
00312 namespace std
00313 {
00314
00315
00316
00317
00318
00319 template <typename T1, typename T2, typename Char, typename Traits>
00320 std::basic_ostream<Char, Traits>& operator<<(
00321 std::basic_ostream<Char, Traits>& stream, const std::pair<T1, T2>& x)
00322 {
00323 std::basic_ostringstream<Char, Traits> buffer;
00324 buffer.copyfmt(stream);
00325 buffer.width(0);
00326 buffer << "(" << x.first << ", " << x.second << ")";
00327 LASS_ENFORCE_STREAM(stream) << buffer.str();
00328 return stream;
00329 }
00330
00331
00332
00333 template <typename T, typename Alloc, typename Char, typename Traits>
00334 std::basic_ostream<Char, Traits>& operator<<(
00335 std::basic_ostream<Char, Traits>& stream, const std::vector<T, Alloc>& container)
00336 {
00337 return lass::stde::impl::print_sequence(
00338 stream, container.begin(), container.end(), "[", ", ", "]");
00339 }
00340
00341
00342
00343 template <typename T, typename Alloc, typename Char, typename Traits>
00344 std::basic_ostream<Char, Traits>& operator<<(
00345 std::basic_ostream<Char, Traits>& stream, const std::list<T, Alloc>& container)
00346 {
00347 return lass::stde::impl::print_sequence(
00348 stream, container.begin(), container.end(), "[", ", ", "]");
00349 }
00350
00351
00352
00353 template <typename T, typename Alloc, typename Char, typename Traits>
00354 std::basic_ostream<Char, Traits>& operator<<(
00355 std::basic_ostream<Char, Traits>& stream, const std::deque<T, Alloc>& container)
00356 {
00357 return lass::stde::impl::print_sequence(
00358 stream, container.begin(), container.end(), "[", ", ", "]");
00359 }
00360
00361
00362
00363 template <typename Key, typename Data, typename Comp, typename Alloc, typename Char, typename Traits>
00364 std::basic_ostream<Char, Traits>& operator<<(
00365 std::basic_ostream<Char, Traits>& stream,
00366 const std::map<Key, Data, Comp, Alloc>& container)
00367 {
00368 return lass::stde::impl::print_map<Char>(
00369 stream, container.begin(), container.end(), "{", ", ", ": ", "}");
00370 }
00371
00372
00373
00374 template <typename Key, typename Data, typename Comp, typename Alloc, typename Char, typename Traits>
00375 std::basic_ostream<Char, Traits>& operator<<(
00376 std::basic_ostream<Char, Traits>& stream,
00377 const std::multimap<Key, Data, Comp, Alloc>& container)
00378 {
00379 return lass::stde::impl::print_map<Char>(
00380 stream, container.begin(), container.end(), "{", ", ", ": ", "}");
00381 }
00382
00383
00384
00385 template <typename Key, typename Comp, typename Alloc, typename Char, typename Traits>
00386 std::basic_ostream<Char, Traits>& operator<<(
00387 std::basic_ostream<Char, Traits>& stream,
00388 const std::set<Key, Comp, Alloc>& container)
00389 {
00390 return lass::stde::impl::print_sequence(
00391 stream, container.begin(), container.end(), "{", ", ", "}");
00392 }
00393
00394
00395
00396 template <typename Key, typename Comp, typename Alloc, typename Char, typename Traits>
00397 std::basic_ostream<Char, Traits>& operator<<(
00398 std::basic_ostream<Char, Traits>& stream,
00399 const std::multiset<Key, Comp, Alloc>& container)
00400 {
00401 return lass::stde::impl::print_sequence(
00402 stream, container.begin(), container.end(), "{", ", ", "}");
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 template <typename Char, typename Traits, typename T1, typename T2>
00412 std::basic_istream<Char, Traits>& operator>>(
00413 std::basic_istream<Char, Traits>& stream, std::pair<T1, T2>& x)
00414 {
00415 using namespace lass::stde;
00416
00417 Char c = 0;
00418 if (stream.get(c))
00419 {
00420 if (c == '(')
00421 {
00422 std::pair<T1, T2> temp;
00423 if (impl::pair_traits::read<Char>(stream, temp, ')', ',', ')'))
00424 {
00425 x = temp;
00426 stream.ignore();
00427 }
00428 }
00429 else
00430 {
00431 stream.putback(c);
00432 stream.clear(std::ios::failbit);
00433 }
00434 }
00435 else
00436 {
00437 stream.clear(std::ios::failbit);
00438 }
00439
00440 return stream;
00441 }
00442
00443
00444
00445
00446
00447 template <typename Char, typename Traits, typename T, typename Alloc>
00448 std::basic_istream<Char, Traits>& operator>>(
00449 std::basic_istream<Char, Traits>& stream, std::vector<T, Alloc>& container)
00450 {
00451 return ::lass::stde::impl::read_container<
00452 ::lass::stde::impl::sequence_traits,
00453 ::lass::stde::impl::value_traits,
00454 T, Char>(
00455 stream, container, '[', ',', 0, ']');
00456 }
00457
00458
00459
00460
00461
00462 template <typename Char, typename Traits, typename T, typename Alloc>
00463 std::basic_istream<Char, Traits>& operator>>(
00464 std::basic_istream<Char, Traits>& stream, std::list<T, Alloc>& container)
00465 {
00466 return ::lass::stde::impl::read_container<
00467 ::lass::stde::impl::sequence_traits,
00468 ::lass::stde::impl::value_traits,
00469 T, Char>(
00470 stream, container, '[', ',', 0, ']');
00471 }
00472
00473
00474
00475
00476
00477 template <typename Char, typename Traits, typename T, typename Alloc>
00478 std::basic_istream<Char, Traits>& operator>>(
00479 std::basic_istream<Char, Traits>& stream, std::deque<T, Alloc>& container)
00480 {
00481 return ::lass::stde::impl::read_container<
00482 ::lass::stde::impl::sequence_traits,
00483 ::lass::stde::impl::value_traits,
00484 T, Char>(
00485 stream, container, '[', ',', 0, ']');
00486 }
00487
00488
00489
00490
00491
00492 template <typename Char, typename Traits, typename Key, typename Data, typename Comp, typename Alloc>
00493 std::basic_istream<Char, Traits>& operator>>(
00494 std::basic_istream<Char, Traits>& stream, std::map<Key, Data, Comp, Alloc>& container)
00495 {
00496 return ::lass::stde::impl::read_container<
00497 ::lass::stde::impl::set_traits,
00498 ::lass::stde::impl::pair_traits,
00499 std::pair<Key, Data>, Char>(
00500 stream, container, '{', ',', ':', '}');
00501 }
00502
00503
00504
00505
00506
00507 template <typename Char, typename Traits, typename Key, typename Data, typename Comp, typename Alloc>
00508 std::basic_istream<Char, Traits>& operator>>(
00509 std::basic_istream<Char, Traits>& stream,
00510 std::multimap<Key, Data, Comp, Alloc>& container)
00511 {
00512 return ::lass::stde::impl::read_container<
00513 ::lass::stde::impl::set_traits,
00514 ::lass::stde::impl::pair_traits,
00515 std::pair<Key, Data>, Char>(
00516 stream, container, '{', ',', ':', '}');
00517 }
00518
00519
00520
00521
00522
00523 template <typename Char, typename Traits, typename Key, typename Comp, typename Alloc>
00524 std::basic_istream<Char, Traits>& operator>>(
00525 std::basic_istream<Char, Traits>& stream, std::set<Key, Comp, Alloc>& container)
00526 {
00527 return ::lass::stde::impl::read_container<
00528 ::lass::stde::impl::set_traits,
00529 ::lass::stde::impl::value_traits,
00530 Key, Char>(
00531 stream, container, '{', ',', 0, '}');
00532 }
00533
00534
00535
00536
00537
00538 template <typename Char, typename Traits, typename Key, typename Comp, typename Alloc>
00539 std::basic_istream<Char, Traits>& operator>>(
00540 std::basic_istream<Char, Traits>& stream, std::multiset<Key, Comp, Alloc>& container)
00541 {
00542 return ::lass::stde::impl::read_container<
00543 ::lass::stde::impl::set_traits,
00544 ::lass::stde::impl::value_traits,
00545 Key, Char>(
00546 stream, container, '{', ',', 0, '}');
00547 }
00548
00549
00550
00551 }
00552
00553