All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
getline.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_IO_GETLINE_HPP
23 #define GEARS_IO_GETLINE_HPP
24 
25 #include <iosfwd>
26 #include <string>
27 
28 namespace gears {
29 namespace io {
45 template<typename CharT, typename Traits, typename Alloc, typename Pred>
46 inline auto getline_until(std::basic_istream<CharT, Traits>& in, std::basic_string<CharT, Traits, Alloc>& str, Pred p) -> decltype(in) {
47  std::ios_base::iostate state = std::ios_base::goodbit;
48  bool extracted = false;
49  const typename std::basic_istream<CharT, Traits>::sentry s(in, true);
50  if(s) {
51  try {
52  str.erase();
53  typename Traits::int_type ch = in.rdbuf()->sgetc();
54  for(; ; ch = in.rdbuf()->snextc()) {
55  if(Traits::eq_int_type(ch, Traits::eof())) {
56  // eof spotted, quit
57  state |= std::ios_base::eofbit;
58  break;
59  }
60  else if(p(Traits::to_char_type(ch))) {
61  // predicate met, discard and quit
62  extracted = true;
63  in.rdbuf()->sbumpc();
64  break;
65  }
66  else if(str.max_size() <= str.size()) {
67  // string too big
68  state |= std::ios_base::failbit;
69  break;
70  }
71  else {
72  // character valid
73  str.push_back(Traits::to_char_type(ch));
74  extracted = true;
75  }
76  }
77  }
78  catch(...) {
79  in.setstate(std::ios_base::badbit);
80  }
81  }
82 
83  if(!extracted) {
84  state |= std::ios_base::failbit;
85  }
86 
87  in.setstate(state);
88  return in;
89 }
90 } // io
91 } // gears
92 
93 #endif // GEARS_IO_GETLINE_HPP