libstdc++
GNU C++ library
Loading...
Searching...
No Matches

◆ _M_extract() [1/2]

template<typename _CharT, typename _InIter>
template<bool _Intl>
_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _InIter std::money_get< _CharT, _InIter >::_M_extract ( iter_type __beg,
iter_type __end,
ios_base & __io,
ios_base::iostate & __err,
string & __units ) const

Definition at line 138 of file locale_facets_nonio.tcc.

141 {
143 typedef typename string_type::size_type size_type;
144 typedef money_base::part part;
146
147 const locale& __loc = __io._M_getloc();
149
151 const __cache_type* __lc = __uc(__loc);
152 const char_type* __lit = __lc->_M_atoms;
153
154 // Deduced sign.
155 bool __negative = false;
156 // Sign size.
158 // True if sign is mandatory.
159 const bool __mandatory_sign = (__lc->_M_positive_sign_size
160 && __lc->_M_negative_sign_size);
161 // String of grouping info from thousands_sep plucked from __units.
162 string __grouping_tmp;
163 if (__lc->_M_use_grouping)
164 __grouping_tmp.reserve(32);
165 // Last position before the decimal point.
166 int __last_pos = 0;
167 // Separator positions, then, possibly, fractional digits.
168 int __n = 0;
169 // If input iterator is in a valid state.
170 bool __testvalid = true;
171 // Flag marking when a decimal point is found.
172 bool __testdecfound = false;
173
174 // The tentative returned string is stored here.
175 string __res;
176 __res.reserve(32);
177
179 const money_base::pattern __p = __lc->_M_neg_format;
180 for (int __i = 0; __i < 4 && __testvalid; ++__i)
181 {
182 const part __which = static_cast<part>(__p.field[__i]);
183 switch (__which)
184 {
186 // According to 22.2.6.1.2, p2, symbol is required
187 // if (__io.flags() & ios_base::showbase), otherwise
188 // is optional and consumed only if other characters
189 // are needed to complete the format.
190 if (__io.flags() & ios_base::showbase || __sign_size > 1
191 || __i == 0
192 || (__i == 1 && (__mandatory_sign
193 || (static_cast<part>(__p.field[0])
195 || (static_cast<part>(__p.field[2])
197 || (__i == 2 && ((static_cast<part>(__p.field[3])
200 && (static_cast<part>(__p.field[3])
201 == money_base::sign)))))
202 {
203 const size_type __len = __lc->_M_curr_symbol_size;
204 size_type __j = 0;
205 for (; __beg != __end && __j < __len
206 && *__beg == __lc->_M_curr_symbol[__j];
207 ++__beg, (void)++__j);
208 if (__j != __len
209 && (__j || __io.flags() & ios_base::showbase))
210 __testvalid = false;
211 }
212 break;
213 case money_base::sign:
214 // Sign might not exist, or be more than one character long.
215 if (__lc->_M_positive_sign_size && __beg != __end
216 && *__beg == __lc->_M_positive_sign[0])
217 {
218 __sign_size = __lc->_M_positive_sign_size;
219 ++__beg;
220 }
221 else if (__lc->_M_negative_sign_size && __beg != __end
222 && *__beg == __lc->_M_negative_sign[0])
223 {
224 __negative = true;
225 __sign_size = __lc->_M_negative_sign_size;
226 ++__beg;
227 }
228 else if (__lc->_M_positive_sign_size
229 && !__lc->_M_negative_sign_size)
230 // "... if no sign is detected, the result is given the sign
231 // that corresponds to the source of the empty string"
232 __negative = true;
233 else if (__mandatory_sign)
234 __testvalid = false;
235 break;
237 // Extract digits, remove and stash away the
238 // grouping of found thousands separators.
239 for (; __beg != __end; ++__beg)
240 {
241 const char_type __c = *__beg;
243 10, __c);
244 if (__q != 0)
245 {
247 ++__n;
248 }
249 else if (__c == __lc->_M_decimal_point
250 && !__testdecfound)
251 {
252 if (__lc->_M_frac_digits <= 0)
253 break;
254
255 __last_pos = __n;
256 __n = 0;
257 __testdecfound = true;
258 }
259 else if (__lc->_M_use_grouping
260 && __c == __lc->_M_thousands_sep
261 && !__testdecfound)
262 {
263 if (__n)
264 {
265 // Mark position for later analysis.
266 __grouping_tmp += static_cast<char>(__n);
267 __n = 0;
268 }
269 else
270 {
271 __testvalid = false;
272 break;
273 }
274 }
275 else
276 break;
277 }
278 if (__res.empty())
279 __testvalid = false;
280 break;
282 // At least one space is required.
283 if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
284 ++__beg;
285 else
286 __testvalid = false;
287 // fallthrough
288 case money_base::none:
289 // Only if not at the end of the pattern.
290 if (__i != 3)
291 for (; __beg != __end
293 break;
294 }
295 }
296
297 // Need to get the rest of the sign characters, if they exist.
298 if (__sign_size > 1 && __testvalid)
299 {
300 const char_type* __sign = __negative ? __lc->_M_negative_sign
301 : __lc->_M_positive_sign;
302 size_type __i = 1;
303 for (; __beg != __end && __i < __sign_size
304 && *__beg == __sign[__i]; ++__beg, (void)++__i);
305
306 if (__i != __sign_size)
307 __testvalid = false;
308 }
309
310 if (__testvalid)
311 {
312 // Strip leading zeros.
313 if (__res.size() > 1)
314 {
315 const size_type __first = __res.find_first_not_of('0');
316 const bool __only_zeros = __first == string::npos;
317 if (__first)
318 __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
319 }
320
321 // 22.2.6.1.2, p4
322 if (__negative && __res[0] != '0')
323 __res.insert(__res.begin(), '-');
324
325 // Test for grouping fidelity.
326 if (__grouping_tmp.size())
327 {
328 // Add the ending grouping.
329 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
330 : __n);
331 if (!std::__verify_grouping(__lc->_M_grouping,
332 __lc->_M_grouping_size,
335 }
336
337 // Iff not enough digits were supplied after the decimal-point.
338 if (__testdecfound && __n != __lc->_M_frac_digits)
339 __testvalid = false;
340 }
341
342 // Iff valid sequence is not recognized.
343 if (!__testvalid)
345 else
346 __units.swap(__res);
347
348 // Iff no more characters are available.
349 if (__beg == __end)
351 return __beg;
352 }
_Alloc_traits::size_type size_type
static const size_type npos
_CharT char_type
Public typedefs.
Primary class template money_get.

References money_get(), std::__verify_grouping(), std::ios_base::_M_getloc(), std::money_base::_S_atoms, std::money_base::_S_zero, std::basic_string< _CharT, _Traits, _Alloc >::begin(), std::basic_string< _CharT, _Traits, _Alloc >::empty(), std::ios_base::eofbit, std::basic_string< _CharT, _Traits, _Alloc >::erase(), std::ios_base::failbit, std::money_base::pattern::field, std::basic_string< _CharT, _Traits, _Alloc >::find_first_not_of(), std::ios_base::flags(), std::basic_string< _CharT, _Traits, _Alloc >::insert(), std::__ctype_abstract_base< _CharT >::is(), std::locale::facet::locale, std::money_base::none, std::basic_string< char >::npos, std::basic_string< _CharT, _Traits, _Alloc >::reserve(), std::ios_base::showbase, std::money_base::sign, std::basic_string< _CharT, _Traits, _Alloc >::size(), std::ctype_base::space, std::money_base::space, std::basic_string< _CharT, _Traits, _Alloc >::swap(), std::money_base::symbol, std::use_facet(), and std::money_base::value.

Here is the call graph for this function: