source: mainline/uspace/lib/cpp/include/__bits/string_io.hpp@ 8a8a9273

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8a8a9273 was 8a8a9273, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: renamed bits/string.hpp and bits/list.hpp to avoid future name clashes

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_BITS_STRING_IO
30#define LIBCPP_BITS_STRING_IO
31
32#include <ios>
33#include <string>
34
35namespace std
36{
37 /**
38 * 21.4.8.9, inserters and extractors:
39 */
40
41 template<class Char, class Traits, class Allocator>
42 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
43 basic_string<Char, Traits, Allocator>& str)
44 {
45 using sentry = typename basic_istream<Char, Traits>::sentry;
46 sentry sen{is, false};
47
48 if (sen)
49 {
50 str.erase();
51
52 auto max_size = is.width();
53 if (max_size <= 0)
54 max_size = static_cast<streamsize>(str.max_size());
55
56 streamsize i{};
57 for(; i < max_size; ++i)
58 {
59 auto ic = is.rdbuf()->sgetc();
60 if (Traits::eq_int_type(ic, Traits::eof()))
61 {
62 is.setstate(ios_base::eofbit);
63 break;
64 }
65
66 auto c = Traits::to_char_type(ic);
67 if(isspace(c, is.getloc()))
68 break;
69
70 str.push_back(c);
71 is.rdbuf()->sbumpc();
72 }
73
74 if (i == 0)
75 is.setstate(ios_base::failbit);
76 }
77 else
78 is.setstate(ios_base::failbit);
79
80 return is;
81 }
82
83 template<class Char, class Traits, class Allocator>
84 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
85 const basic_string<Char, Traits, Allocator>& str)
86 {
87 // TODO: determine padding as described in 27.7.3.6.1
88 using sentry = typename basic_ostream<Char, Traits>::sentry;
89 sentry sen{os};
90
91 if (sen)
92 {
93 auto width = os.width();
94 auto size = str.size();
95
96 size_t to_pad{};
97 if (width > 0)
98 to_pad = (static_cast<size_t>(width) - size);
99
100 if (to_pad > 0)
101 {
102 if ((os.flags() & ios_base::adjustfield) != ios_base::left)
103 {
104 for (std::size_t i = 0; i < to_pad; ++i)
105 os.put(os.fill());
106 }
107
108 os.rdbuf()->sputn(str.data(), size);
109
110 if ((os.flags() & ios_base::adjustfield) == ios_base::left)
111 {
112 for (std::size_t i = 0; i < to_pad; ++i)
113 os.put(os.fill());
114 }
115 }
116 else
117 os.rdbuf()->sputn(str.data(), size);
118
119 os.width(0);
120 }
121
122 return os;
123 }
124
125 template<class Char, class Traits, class Allocator>
126 basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
127 basic_string<Char, Traits, Allocator>& str,
128 Char delim)
129 {
130 typename basic_istream<Char, Traits>::sentry sen{is, true};
131
132 if (sen)
133 {
134 str.clear();
135 streamsize count{};
136
137 while (true)
138 {
139 auto ic = is.rdbuf()->sbumpc();
140 if (Traits::eq_int_type(ic, Traits::eof()))
141 {
142 is.setstate(ios_base::eofbit);
143 break;
144 }
145
146 auto c = Traits::to_char_type(ic);
147 if (Traits::eq(c, delim))
148 break;
149
150 str.push_back(c);
151 ++count;
152
153 if (count >= static_cast<streamsize>(str.max_size()))
154 {
155 is.setstate(ios_base::failbit);
156 break;
157 }
158 }
159
160 if (count == 0)
161 is.setstate(ios_base::failbit);
162 }
163 else
164 is.setstate(ios_base::failbit);
165
166 return is;
167 }
168
169 template<class Char, class Traits, class Allocator>
170 basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
171 basic_string<Char, Traits, Allocator>& str,
172 Char delim)
173 {
174 return getline(is, str, delim);
175 }
176
177 template<class Char, class Traits, class Allocator>
178 basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
179 basic_string<Char, Traits, Allocator>& str)
180 {
181 return getline(is, str, is.widen('\n'));
182 }
183
184 template<class Char, class Traits, class Allocator>
185 basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
186 basic_string<Char, Traits, Allocator>& str)
187 {
188 return getline(is, str, is.widen('\n'));
189 }
190}
191
192#endif
Note: See TracBrowser for help on using the repository browser.