iutest  1.17.99.14
iutest_string_view.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_STRING_VIEW_HPP_46AEE8A4_996C_4925_ACBA_2A511909B38F_
16 #define INCG_IRIS_IUTEST_STRING_VIEW_HPP_46AEE8A4_996C_4925_ACBA_2A511909B38F_
17 
18 //======================================================================
19 // include
20 // IWYU pragma: begin_exports
21 #include "../iutest_defs.hpp"
22 
23 #if IUTEST_HAS_CXX_HDR_STRING_VIEW
24 # include <string_view>
25 #endif
26 
27 #if IUTEST_HAS_EXCEPTIONS
28 # include <stdexcept>
29 #endif
30 #include <climits>
31 // IWYU pragma: end_exports
32 
33 //======================================================================
34 // class
35 
36 namespace iutest {
37 namespace detail
38 {
39 
40 #if !IUTEST_USE_OWN_STRING_VIEW
41 
42 template<typename CharT, typename Traits = ::std::char_traits<CharT> >
43 using iu_basic_string_view = ::std::basic_string_view<CharT, Traits>;
44 
45 #else
46 
47 template <class CharT, class Traits = ::std::char_traits<CharT> >
48 class iu_basic_string_view;
49 
50 template<typename CharT, typename Traits>
51 class iu_basic_string_view
52 {
53 public:
54  typedef Traits traits_type;
55  typedef CharT value_type;
56  typedef value_type* pointer;
57  typedef const value_type* const_pointer;
58  typedef value_type& reference;
59  typedef const value_type& const_reference;
60  //typedef pointer const_iterator;
61  //typedef const_iterator iterator;
62  //typedef pointer const_reverse_iterator;
63  //typedef const_reverse_iterator reverse_iterator;
64  typedef size_t size_type;
65  typedef ::std::ptrdiff_t difference_type;
66 
67 public:
68  static const size_type npos = static_cast<size_type >(-1);
69 
70 private:
71  static const size_type size_type_max = static_cast<size_type>(
72 #if defined(PTRDIFF_MAX)
73  PTRDIFF_MAX
74 #else
75  INT_MAX
76 #endif
77  );
78 
79 public:
80  IUTEST_CXX_CONSTEXPR iu_basic_string_view() IUTEST_CXX_NOEXCEPT_SPEC
81  : m_data(IUTEST_NULLPTR)
82  , m_size(0)
83  {
84  }
85  IUTEST_CXX_CONSTEXPR iu_basic_string_view(const_pointer str)
86  : m_data(str)
87  , m_size(traits_type::length(str))
88  {
89  }
90  IUTEST_CXX_CONSTEXPR iu_basic_string_view(const_pointer str, size_type len)
91  : m_data(str)
92  , m_size(len)
93  {
94  }
95 #if IUTEST_HAS_DEFAULT_FUNCTIONS
96  IUTEST_CXX_CONSTEXPR iu_basic_string_view(const iu_basic_string_view&) IUTEST_CXX_NOEXCEPT_SPEC = default;
97 #else
98  IUTEST_CXX_CONSTEXPR iu_basic_string_view(const iu_basic_string_view& rhs) IUTEST_CXX_NOEXCEPT_SPEC
99  : m_data(rhs.m_data)
100  , m_size(rhs.m_size)
101  {
102  }
103 #endif
104 
105  template<size_t N>
106  iu_basic_string_view(value_type(&str)[N]) // NOLINT
107  : m_data(str)
108  , m_size(N)
109  {
110  }
111 
112  template<typename Allocator>
113  iu_basic_string_view(const ::std::basic_string<value_type, traits_type, Allocator>& str) // NOLINT
114  : m_data(str.data())
115  , m_size(str.length())
116  {
117  }
118 
119  ~iu_basic_string_view() IUTEST_CXX_DEFAULT_FUNCTION
120 
121 public:
122 #if IUTEST_HAS_DEFAULT_FUNCTIONS
123  iu_basic_string_view& operator=(const iu_basic_string_view&) = default;
124 #if IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION
125  iu_basic_string_view& operator=(iu_basic_string_view&&) = default;
126 #endif
127 #else
128  iu_basic_string_view& operator=(const iu_basic_string_view& rhs)
129  {
130  m_data = rhs.m_data;
131  m_size = rhs.m_size;
132  return *this;
133  }
134 #endif
135 
136 public:
137  IUTEST_CXX_CONSTEXPR size_type size() const IUTEST_CXX_NOEXCEPT_SPEC
138  {
139  return m_size;
140  }
141  IUTEST_CXX_CONSTEXPR size_type length() const IUTEST_CXX_NOEXCEPT_SPEC
142  {
143  return m_size;
144  }
145  IUTEST_CXX_CONSTEXPR size_type max_size() const IUTEST_CXX_NOEXCEPT_SPEC
146  {
147  return (::std::min)(size_type_max, static_cast<size_type>(-1) / sizeof(value_type));
148  }
150  {
151  return m_size == 0;
152  }
153 
154 public:
155  IUTEST_CXX_CONSTEXPR const_reference operator[](size_type pos) const IUTEST_CXX_NOEXCEPT_SPEC
156  {
157  return m_data[pos];
158  }
159  IUTEST_CXX14_CONSTEXPR const_reference at(size_type pos) const
160  {
161  offset_exclusive(pos);
162  return m_data[pos];
163  }
164  IUTEST_CXX_CONSTEXPR const_reference front() const IUTEST_CXX_NOEXCEPT_SPEC
165  {
166  return m_data[0];
167  }
168  IUTEST_CXX_CONSTEXPR const_reference back() const IUTEST_CXX_NOEXCEPT_SPEC
169  {
170  return m_data[0];
171  }
172  IUTEST_CXX_CONSTEXPR const_pointer data() const IUTEST_CXX_NOEXCEPT_SPEC
173  {
174  return m_data;
175  }
176 
177 public:
178 IUTEST_PRAGMA_WARN_PUSH()
179 IUTEST_PRAGMA_WARN_DISABLE_CXX14_CONSTEXPR_NOT_IMPLY_CONST()
180 
181  IUTEST_CXX14_CONSTEXPR void remove_prefix(size_type n) IUTEST_CXX_NOEXCEPT_SPEC
182  {
183  m_data += n;
184  m_size -= n;
185  }
186 
187  IUTEST_CXX14_CONSTEXPR void remove_suffix(size_type n) IUTEST_CXX_NOEXCEPT_SPEC
188  {
189  m_size -= n;
190  }
191 
192  IUTEST_CXX14_CONSTEXPR void swap(iu_basic_string_view & other) IUTEST_CXX_NOEXCEPT_SPEC
193  {
194  const iu_basic_string_view tmp = { other };
195  other = *this;
196  *this = other;
197  }
198 
199 IUTEST_PRAGMA_WARN_POP()
200 
201 public:
202  size_type copy(pointer s, size_type n, size_type pos = 0) const
203  {
204  offset_exclusive(pos);
205  const size_type count = clamp_suffix_size(pos, n);
206  traits_type::copy(s, m_data + pos, count);
207  return count;
208  }
209 
210  IUTEST_CXX14_CONSTEXPR iu_basic_string_view substr(size_type pos = 0, size_type n = npos) const
211  {
212  offset_exclusive(pos);
213  const size_type count = clamp_suffix_size(pos, n);
214  return iu_basic_string_view(m_data + pos, count);
215  }
216 
217 
218 public:
219  IUTEST_CXX_CONSTEXPR bool equal(iu_basic_string_view sv) const IUTEST_CXX_NOEXCEPT_SPEC
220  {
221  return m_size == sv.m_size && (traits_type::compare(m_data, sv.m_data, m_size) == 0);
222  }
223 
224 public:
225  IUTEST_CXX14_CONSTEXPR int compare(iu_basic_string_view sv) const IUTEST_CXX_NOEXCEPT_SPEC
226  {
227  {
228  const size_type count = (::std::min)(m_size, sv.m_size);
229  const int result = traits_type::compare(m_data, sv.m_data, count);
230  if( result != 0 )
231  {
232  return result;
233  }
234  }
235  if( m_size < sv.m_size )
236  {
237  return -1;
238  }
239  if( m_size > sv.m_size )
240  {
241  return 1;
242  }
243  return 0;
244  }
245 
246  IUTEST_CXX_CONSTEXPR int compare(size_type pos1, size_type n1, iu_basic_string_view sv) const
247  {
248  return substr(pos1, n1).compare(sv);
249  }
250 
251  IUTEST_CXX_CONSTEXPR int compare(size_type pos1, size_type n1, iu_basic_string_view sv, size_type pos2, size_type n2) const
252  {
253  return substr(pos1, n1).compare(sv.substr(pos2, n2));
254  }
255 
256  IUTEST_CXX_CONSTEXPR int compare(const_pointer s) const
257  {
258  return compare(basic_string_view(s));
259  }
260 
261  IUTEST_CXX_CONSTEXPR int compare(size_type pos1, size_type n1, const_pointer s) const
262  {
263  return substr(pos1, n1).compare(basic_string_view(s));
264  }
265 
266  IUTEST_CXX_CONSTEXPR int compare(size_type pos1, size_type n1, const_pointer s, size_type n2) const
267  {
268  return substr(pos1, n1).compare(basic_string_view(s, n2));
269  }
270 
271 public:
272  IUTEST_CXX_CONSTEXPR bool starts_with(iu_basic_string_view x) const IUTEST_CXX_NOEXCEPT_SPEC
273  {
274  return compare(0, npos, x) == 0;
275  }
276  IUTEST_CXX_CONSTEXPR bool starts_with(value_type x) const IUTEST_CXX_NOEXCEPT_SPEC
277  {
278  return starts_with(iu_basic_string_view(&x, 1));
279  }
280  IUTEST_CXX_CONSTEXPR bool starts_with(const_pointer x) const
281  {
282  return starts_with(iu_basic_string_view(x));
283  }
284 
285  IUTEST_CXX_CONSTEXPR bool ends_with(iu_basic_string_view x) const IUTEST_CXX_NOEXCEPT_SPEC
286  {
287  return m_size >= x.m_size && compare(m_size - x.m_size, npos, x) == 0;
288  }
289  IUTEST_CXX_CONSTEXPR bool ends_with(value_type x) const IUTEST_CXX_NOEXCEPT_SPEC
290  {
291  return ends_with(iu_basic_string_view(&x, 1));
292  }
293  IUTEST_CXX_CONSTEXPR bool ends_with(const_pointer x) const
294  {
295  return ends_with(iu_basic_string_view(x));
296  }
297 
298 public:
299  IUTEST_CXX14_CONSTEXPR size_type find(iu_basic_string_view sv, size_type pos = 0) const IUTEST_CXX_NOEXCEPT_SPEC
300  {
301  if( (sv.m_size > m_size) || (pos > m_size - sv.m_size) )
302  {
303  return npos;
304  }
305  if( sv.m_size == 0 )
306  {
307  return pos;
308  }
309  const_pointer end = m_data + (m_size - sv.m_size) + 1;
310  for( const_pointer top = m_data + pos; ; ++top )
311  {
312  top = traits_type::find(top, static_cast<size_type>(end - top), sv[0]);
313  if( !top )
314  {
315  return npos;
316  }
317 
318  if( traits_type::compare(top, sv.m_data, sv.m_size) == 0 )
319  {
320  return static_cast<size_type>(top - m_data);
321  }
322  }
323  }
324  IUTEST_CXX14_CONSTEXPR size_type find(value_type c, size_type pos = 0) const IUTEST_CXX_NOEXCEPT_SPEC
325  {
326  if( pos < m_size )
327  {
328  const_pointer find = traits_type::find(m_data + pos, m_size, c);
329  if( find != IUTEST_NULLPTR )
330  {
331  return static_cast<size_type>(find - m_data);
332  }
333  }
334  return npos;
335  }
336 
337  IUTEST_CXX_CONSTEXPR size_type find(const_pointer s, size_type pos, size_type n) const
338  {
339  return find(iu_basic_string_view(s, n), pos);
340  }
341  IUTEST_CXX_CONSTEXPR size_type find(const_pointer s, size_type pos = 0) const
342  {
343  return find(iu_basic_string_view(s), pos);
344  }
345 
346 public:
347  //IUTEST_CXX_CONSTEXPR size_type rfind(iu_basic_string_view s, size_type pos = npos) const IUTEST_CXX_NOEXCEPT_SPEC
348  //{
349  // if( s.m_size == 0 )
350  // {
351  // return (::std::min)(pos, m_size);
352  // }
353  // if( m_size >= sv.m_size )
354  // {
355  // }
356  // return npos;
357  //}
358  //IUTEST_CXX_CONSTEXPR size_type rfind(value_type c, size_type pos = npos) const IUTEST_CXX_NOEXCEPT_SPEC;
359  //IUTEST_CXX_CONSTEXPR size_type rfind(const_pointer s, size_type pos, size_type n) const
360  //{
361  // return rfind(iu_basic_string_view(s, n), pos);
362  //}
363  //IUTEST_CXX_CONSTEXPR size_type rfind(const_pointer s, size_type pos = npos) const
364  //{
365  // return rfind(iu_basic_string_view(s), pos);
366  //}
367 
368 private:
369  size_type clamp_suffix_size(size_type pos, size_type n) const
370  {
371  return (::std::min)(n, m_size - pos);
372  }
373 
374  void offset_exclusive(size_type pos) const
375  {
376  if( pos >= m_size )
377  {
378  out_of_range();
379  }
380  }
381 
382  void out_of_range() const
383  {
384 #if IUTEST_HAS_EXCEPTIONS
385  throw new ::std::out_of_range("invalid string_view position");
386 #endif
387  }
388 
389 public:
390  friend bool operator == (const iu_basic_string_view lhs, const iu_basic_string_view& rhs)
391  {
392  return lhs.equal(rhs);
393  }
394  friend bool operator != (const iu_basic_string_view lhs, const iu_basic_string_view& rhs)
395  {
396  return !lhs.equal(rhs);
397  }
398 
399 private:
400  const_pointer m_data;
401  size_type m_size;
402 };
403 
404 #endif
405 
406 template<typename CharT, typename Traits = ::std::char_traits<CharT> >
407 class iu_nullable_basic_string_view : public iu_basic_string_view<CharT, Traits>
408 {
409 public:
410  typedef iu_basic_string_view<CharT, Traits> _Mybase;
411  typedef Traits traits_type;
412  typedef CharT value_type;
413  typedef value_type* pointer;
414  typedef const value_type* const_pointer;
415  typedef size_t size_type;
416 public:
418 #if IUTEST_HAS_NULLPTR
419  IUTEST_CXX_CONSTEXPR iu_nullable_basic_string_view(::std::nullptr_t)
420  : _Mybase(IUTEST_NULLPTR, 0)
421  {
422  }
423 #endif
424  IUTEST_CXX_CONSTEXPR iu_nullable_basic_string_view(const_pointer str)
425  : _Mybase(str, str ? traits_type::length(str) : 0)
426  {
427  }
428  IUTEST_CXX_CONSTEXPR iu_nullable_basic_string_view(const_pointer str, size_type len)
429  : _Mybase(str, len)
430  {
431  }
432 #if IUTEST_HAS_DEFAULT_FUNCTIONS
433  IUTEST_CXX_CONSTEXPR iu_nullable_basic_string_view(const iu_nullable_basic_string_view&) IUTEST_CXX_NOEXCEPT_SPEC = default;
434 #else
435  IUTEST_CXX_CONSTEXPR iu_nullable_basic_string_view(const iu_nullable_basic_string_view& rhs) IUTEST_CXX_NOEXCEPT_SPEC
436  : _Mybase(rhs)
437  {
438  }
439 #endif
440 
441  template<size_t N>
442  iu_nullable_basic_string_view(value_type(&str)[N]) // NOLINT
443  : _Mybase(str, N)
444  {
445  }
446 
447  iu_nullable_basic_string_view(const _Mybase& str_view) // NOLINT
448  : _Mybase(str_view)
449  {
450  }
451 
452  template<typename Allocator>
453  iu_nullable_basic_string_view(const ::std::basic_string<value_type, traits_type, Allocator>& str) // NOLINT
454  : _Mybase(str.data(), str.length())
455  {
456  }
457 };
458 
459 
460 typedef iu_basic_string_view<char> iu_string_view;
461 typedef iu_basic_string_view<wchar_t> iu_wstring_view;
462 
463 
464 } // end of namespace detail
465 } // end of namespace iutest
466 
467 #endif // INCG_IRIS_IUTEST_STRING_VIEW_HPP_46AEE8A4_996C_4925_ACBA_2A511909B38F_
#define IUTEST_CXX_CONSTEXPR
constexpr
Definition: iutest_compiler.hpp:372
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:811
#define IUTEST_CXX_DEFAULT_FUNCTION
default function
Definition: iutest_compiler.hpp:494
iutest root namespace
Definition: iutest_charcode.hpp:33