iutest  1.17.99.14
iutest_string_stream.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_STRING_STREAM_HPP_F446E84B_1C7D_49C4_9A2D_5002CCE3F486_
16 #define INCG_IRIS_IUTEST_STRING_STREAM_HPP_F446E84B_1C7D_49C4_9A2D_5002CCE3F486_
17 
18 //======================================================================
19 // include
20 // IWYU pragma: begin_exports
21 #include "iutest_string.hpp"
22 
23 #if IUTEST_HAS_STRINGSTREAM
24 # include <sstream>
25 #elif IUTEST_HAS_STRSTREAM
26 # include <strstream>
27 #endif
28 #if IUTEST_HAS_IOMANIP
29 # include <iomanip>
30 #endif
31 #if IUTEST_HAS_EXCEPTIONS
32 # include <stdexcept>
33 #endif
34 // IWYU pragma: end_exports
35 
36 namespace iutest
37 {
38 
39 namespace detail
40 {
41 
42 template<typename T>
43 bool StringToValue(const ::std::string& s, T& out)
44 {
45 #if IUTEST_HAS_STRINGSTREAM
46  ::std::istringstream strm(s);
47  if( strm >> out )
48  {
49  return true;
50  }
51  return false;
52 #elif IUTEST_HAS_STD_STR_TO_VALUE
53  out = static_cast<T>(::std::stoull(s));
54  return true;
55 #else
56  char* endptr=NULL;
57  const char* p = s.c_str();
58  errno = 0;
59  const unsigned long long v = strtoull(p, &endptr, 10);
60  if(p == endptr)
61  {
62 #if IUTEST_HAS_EXCEPTIONS
63  throw ::std::invalid_argument(p);
64 #else
65  return false;
66 #endif
67  }
68  if(errno == ERANGE)
69  {
70 #if IUTEST_HAS_EXCEPTIONS
71  throw ::std::out_of_range(p);
72 #else
73  return false;
74 #endif
75  }
76  out = static_cast<T>(v);
77  return true;
78 #endif
79 }
80 
81 inline bool StringToValue(const ::std::string& s, float& out)
82 {
83 #if IUTEST_HAS_STD_STR_TO_VALUE
84  out = ::std::stof(s);
85 #else
86  char* endptr=NULL;
87  const char* p = s.c_str();
88  errno = 0;
89 #if !defined(IUTEST_OS_WINDOWS_MINGW) || !defined(__STRICT_ANSI__)
90  const floating_point<float> v = strtof(p, &endptr);
91 #else
92  const floating_point<float> v = static_cast<float>(strtod(p, &endptr));
93 #endif
94  if(p == endptr)
95  {
96 #if IUTEST_HAS_EXCEPTIONS
97  throw ::std::invalid_argument(p);
98 #else
99  return false;
100 #endif
101  }
102  if((errno == ERANGE) || v.is_inf() )
103  {
104 #if IUTEST_HAS_EXCEPTIONS
105  throw ::std::out_of_range(p);
106 #else
107  return false;
108 #endif
109  }
110  out = v;
111 #endif
112  return true;
113 }
114 
115 inline bool StringToValue(const ::std::string& s, double& out)
116 {
117 #if IUTEST_HAS_STD_STR_TO_VALUE
118  out = ::std::stod(s);
119 #else
120  char* endptr=NULL;
121  const char* p = s.c_str();
122  errno = 0;
123  const floating_point<double> v = strtod(p, &endptr);
124  if(p == endptr)
125  {
126 #if IUTEST_HAS_EXCEPTIONS
127  throw ::std::invalid_argument(p);
128 #else
129  return false;
130 #endif
131  }
132  if((errno == ERANGE) || v.is_inf() )
133  {
134 #if IUTEST_HAS_EXCEPTIONS
135  throw ::std::out_of_range(p);
136 #else
137  return false;
138 #endif
139  }
140  out = v;
141 #endif
142  return true;
143 }
144 
145 #if IUTEST_HAS_LONG_DOUBLE
146 
147 inline bool StringToValue(const ::std::string& s, long double& out)
148 {
149 #if IUTEST_HAS_STD_STR_TO_VALUE
150  out = ::std::stold(s);
151 #else
152  char* endptr=NULL;
153  const char* p = s.c_str();
154  errno = 0;
155  const floating_point<long double> v = strtold(p, &endptr);
156  if(p == endptr)
157  {
158 #if IUTEST_HAS_EXCEPTIONS
159  throw ::std::invalid_argument(p);
160 #else
161  return false;
162 #endif
163  }
164  if((errno == ERANGE) || v.is_inf() )
165  {
166 #if IUTEST_HAS_EXCEPTIONS
167  throw ::std::out_of_range(p);
168 #else
169  return false;
170 #endif
171  }
172  out = v;
173 #endif
174  return true;
175 }
176 
177 #endif
178 
179 #if !IUTEST_HAS_STRINGSTREAM && !IUTEST_HAS_STRSTREAM
180 
181 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
182 
183 //======================================================================
184 // class
185 
186 template<class _Elem, class _Traits>
187 class iu_basic_ostream
188 {
189  typedef iu_basic_ostream<_Elem, _Traits> _Myt;
190  //typedef ::std::basic_streambuf<_Elem, _Traits> streambuf;
191  //typedef ::std::basic_ostream<_Elem, _Traits> ostream;
192  typedef ::std::basic_string<_Elem, _Traits> string;
193  string s;
194 
195  template<typename T>
196  struct xcs
197  {
198  private:
199  template<typename TMP, typename TN>
200  struct impl_select
201  {
202  template<typename TA, typename TB>
203  static const TA constant(const TA a, const TB b)
204  {
205  (void)b;
206  return a;
207  }
208  };
209  template<typename TMP>
210  struct impl_select<TMP, wchar_t>
211  {
212  template<typename TA, typename TB>
213  static const TB constant(const TA a, const TB b)
214  {
215  (void)a;
216  return b;
217  }
218  };
219 
220  public:
221  typedef impl_select<void, T> select;
222  };
223 #define IIUT_PP_XCS(txt_) xcs<_Elem>::select::constant(txt_, L##txt_)
224 
225 IUTEST_PRAGMA_WARN_PUSH()
226 IUTEST_PRAGMA_WARN_DISABLE_FORMAT_NONLITERAL()
227  struct impl
228  {
229  template<typename E>
230  static int vastring(E* dst, const E* fmt, va_list va);
231  static int vastring(char* dst, size_t len, const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(3, 0)
232  {
233  (void)len;
234  return vsprintf(dst, fmt, va);
235  }
236  static int vastring(wchar_t* dst, size_t len, const wchar_t* fmt, va_list va)
237  {
238 #ifdef IUTEST_OS_WINDOWS_MINGW
239  return _vsnwprintf(dst, len, fmt, va);
240 #else
241  return vswprintf(dst, len, fmt, va);
242 #endif
243  }
244 
245  template<typename E>
246  static int tostring(E* dst, size_t len, const E* fmt, ...)
247  {
248  va_list va;
249  va_start(va, fmt);
250  const int ret = vastring(dst, len, fmt, va);
251  va_end(va);
252  return ret;
253  }
254  };
255 IUTEST_PRAGMA_WARN_POP()
256 
257 public:
258  iu_basic_ostream() {}
259  explicit iu_basic_ostream(const char* str) : s(str) {}
260  explicit iu_basic_ostream(const ::std::string& str) : s(str) {}
261 
262 public:
263  inline _Myt& operator<< (char v)
264  {
265  s += v;
266  return *this;
267  }
268  inline _Myt& operator<< (signed char v)
269  {
270  s += static_cast<char>(v);
271  return *this;
272  }
273  inline _Myt& operator<< (unsigned char v)
274  {
275  s += static_cast<char>(v);
276  return *this;
277  }
278  inline _Myt& operator<< (const _Elem* v)
279  {
280  s += v;
281  return *this;
282  }
283  //inline _Myt& operator<< (const signed _Elem* v)
284  //{
285  // s += v;
286  // return *this;
287  //}
288  //inline _Myt& operator<< (const unsigned _Elem* v)
289  //{
290  // s += v;
291  // return *this;
292  //}
293  inline _Myt& operator<< (bool v)
294  {
295 #if 0
296  _Elem a[16];
297  impl::tostring(a, 16, IIUT_PP_XCS("%i"), v);
298  s += a;
299 #else
300  s += (v ? IIUT_PP_XCS("true") : IIUT_PP_XCS("false"));
301 #endif
302  return *this;
303  }
304  inline _Myt& operator<< (short v)
305  {
306  _Elem a[64];
307  impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
308  s += a;
309  return *this;
310  }
311  inline _Myt& operator<< (unsigned short v)
312  {
313  _Elem a[64];
314  impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
315  s += a;
316  return *this;
317  }
318  inline _Myt& operator<< (int v)
319  {
320  _Elem a[64];
321  impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
322  s += a;
323  return *this;
324  }
325  inline _Myt& operator<< (unsigned int v)
326  {
327  _Elem a[64];
328  impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
329  s += a;
330  return *this;
331  }
332  inline _Myt& operator<< (long v)
333  {
334  _Elem a[64];
335  impl::tostring(a, 64, IIUT_PP_XCS("%i"), v);
336  s += a;
337  return *this;
338  }
339  inline _Myt& operator<< (unsigned long v)
340  {
341  _Elem a[64];
342  impl::tostring(a, 64, IIUT_PP_XCS("%u"), v);
343  s += a;
344  return *this;
345  }
346  inline _Myt& operator<< (long long int v)
347  {
348  _Elem a[64];
349  impl::tostring(a, 64, IIUT_PP_XCS("%lld"), v);
350  s += a;
351  return *this;
352  }
353  inline _Myt& operator<< (unsigned long long int v)
354  {
355  _Elem a[64];
356  impl::tostring(a, 64, IIUT_PP_XCS("%llu"), v);
357  s += a;
358  return *this;
359  }
360  inline _Myt& operator<< (float v)
361  {
362  _Elem a[64];
363 IUTEST_PRAGMA_WARN_PUSH()
364 IUTEST_PRAGMA_WARN_DISABLE_DOUBLE_PROMOTION()
365  impl::tostring(a, 64, IIUT_PP_XCS("%f"), v);
366 IUTEST_PRAGMA_WARN_POP()
367  s += a;
368  return *this;
369  }
370  inline _Myt& operator<< (double v)
371  {
372  _Elem a[64];
373  impl::tostring(a, 64, IIUT_PP_XCS("%lf"), v);
374  s += a;
375  return *this;
376  }
377 #if IUTEST_HAS_LONG_DOUBLE
378  inline _Myt& operator<< (long double v)
379  {
380  _Elem a[64];
381  impl::tostring(a, 64, IIUT_PP_XCS("%Lf"), v);
382  s += a;
383  return *this;
384  }
385 #endif
386 #if IUTEST_HAS_FLOAT128
387  inline _Myt& operator<< (internal::Float128::Float v)
388  {
389  _Elem a[64];
390  const double d = static_cast<double>(v);
391  impl::tostring(a, 64, IIUT_PP_XCS("%L"), d);
392  s += a;
393  return *this;
394  }
395 #endif
396  inline _Myt& operator<< (const void* v)
397  {
398  _Elem a[64];
399  impl::tostring(a, 64, IIUT_PP_XCS("%t"), v);
400  s += a;
401  return *this;
402  }
403  inline _Myt& operator<< (const ::std::string& v)
404  {
405  s += v;
406  return *this;
407  }
408 public:
409  const string& str() const { return s; }
410  void copyfmt(const _Myt&) {}
411 };
412 
413 #undef IIUT_PP_XCS
414 
415 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
416 
417 #endif
418 
419 //======================================================================
420 // declare
421 #if IUTEST_HAS_STRINGSTREAM
422 
423 typedef ::std::stringstream stlstream;
424 
425 #elif IUTEST_HAS_STRSTREAM
426 
427 IUTEST_PRAGMA_MSC_WARN_PUSH()
428 IUTEST_PRAGMA_MSC_WARN_DISABLE(4250)
429 class stlstream : public ::std::strstream
430 {
431  char buf[512];
432 public:
433  stlstream()
434  : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
435  {}
436  explicit stlstream(const char* str)
437  : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
438  {
439  *this << str;
440  }
441  explicit stlstream(const ::std::string& str)
442  : ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
443  {
444  *this << str;
445  }
446 public:
447  ::std::string str() const
448  {
449  return const_cast<stlstream*>(this)->str();
450  }
451  virtual ::std::string str()
452  {
453  *this << ::std::ends;
454  ::std::string str = ::std::strstream::str();
455  return str;
456  }
457 };
458 
459 IUTEST_PRAGMA_MSC_WARN_POP()
460 
461 #endif
462 
463 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
464 
465 } // end of namespace detail
466 
467 #if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
468 
469 typedef ::std::ostream iu_ostream;
470 typedef detail::stlstream iu_stringstream;
471 
472 #else
473 
474 typedef detail::iu_basic_ostream<char, ::std::char_traits<char> > iu_ostream;
475 typedef detail::iu_basic_ostream<wchar_t, ::std::char_traits<wchar_t> > iu_wostream;
476 typedef iu_ostream iu_stringstream;
477 
478 #endif
479 
480 #if IUTEST_HAS_IOMANIP
481 typedef iu_ostream& (*iu_basic_iomanip)(iu_ostream&);
482 #endif
483 
484 #if !defined(IUTEST_HAS_BIGGESTINT_OSTREAM)
485 # if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
486 # if (defined(_STLPORT_VERSION) && !defined(_STLP_LONG_LONG)) || (defined(_MSC_VER) && _MSC_VER < 1310)
487 # define IUTEST_HAS_BIGGESTINT_OSTREAM 0
488 # endif
489 # endif
490 #endif
491 
492 #if !defined(IUTEST_HAS_BIGGESTINT_OSTREAM)
493 # define IUTEST_HAS_BIGGESTINT_OSTREAM 1
494 #endif
495 
496 } // end of namespace iutest
497 
498 #endif // INCG_IRIS_IUTEST_STRING_STREAM_HPP_F446E84B_1C7D_49C4_9A2D_5002CCE3F486_
iris unit test string utilities
iutest root namespace
Definition: iutest_charcode.hpp:33