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