Logo ROOT   6.14/05
Reference Guide
RWrap_libcpp_string_view.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 // Author: Philippe Canal, March 2015
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //===---------------------wrap string_view ----------------------------===//
13 // Wrapper header adapting the snapshot of sring_view.h to build without
14 // the libc++ infrastructure header files.
15 
16 #ifndef RWrap_libcpp_string_view_h
17 #define RWrap_libcpp_string_view_h
18 
19 #ifndef RStringView_H
20 #error "Do not use RWrap_libcpp_string_view.h directly. #include \"ROOT/RStringView.hxx\" instead."
21 #endif // RStringView_H
22 
23 // In case we are connected with a libc++ which defines those, we need
24 // to include it first, so we avoid being silently over-ridden.
25 
26 // To import a new version of the original file do:
27 //
28 /*
29  svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
30 
31  cat original/string_view | \
32  sed -e 's:_LIBCPP_BEGIN_NAMESPACE_LFTS:_ROOT_LIBCPP_BEGIN_NAMESPACE_LFTS:' \
33  -e 's:_LIBCPP_END_NAMESPACE_LFTS:_ROOT_LIBCPP_END_NAMESPACE_LFTS:' \
34  -e 's:#include <__debug>://#include <__debug>:' \
35  -e 's:#include <experimental/__config>://#include <experimental/__config>:' \
36  -e 's:__put_character_sequence:R__put_character_sequence:g' \
37  > core/base/inc/libcpp_string_view.h
38 */
39 
40 #include <string>
41 #include <algorithm>
42 #include <iterator>
43 #include <ostream>
44 #include <iomanip>
45 #include <stdexcept>
46 
47 #ifndef R__WIN32
48 
49 #define _ROOT_LIBCPP_BEGIN_NAMESPACE_LFTS \
50 namespace std { \
51 namespace experimental { inline namespace __ROOT {
52 #define _ROOT_LIBCPP_END_NAMESPACE_LFTS } } }
53 #else
54 
55 // Microsoft compiler does not support inline namespace yet.
56 #define _ROOT_LIBCPP_BEGIN_NAMESPACE_LFTS \
57 namespace std { \
58 namespace experimental { namespace __ROOT {
59 #define _ROOT_LIBCPP_END_NAMESPACE_LFTS } using namespace __ROOT; } }
60 
61 #endif
62 
63 
64 #ifndef _LIBCPP_BEGIN_NAMESPACE_STD
65 #define _LOCAL_LIBCPP_BEGIN_NAMESPACE_STD
66 #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
67 #define _LIBCPP_END_NAMESPACE_STD }
68 #endif
69 
70 #ifndef _LIBCPP_CONSTEXPR
71 #define _LOCAL_LIBCPP_CONSTEXPR
72 #define _LIBCPP_CONSTEXPR constexpr
73 #endif
74 
75 #ifndef _VSTD
76 #define _LOCAL_VSTD
77 #define _VSTD ::std
78 #endif
79 
80 #ifndef _LIBCPP_INLINE_VISIBILITY
81 #define _LOCAL_LIBCPP_INLINE_VISIBILITY
82 #define _LIBCPP_INLINE_VISIBILITY inline
83 #endif
84 
85 #ifndef _LIBCPP_EXPLICIT
86 #define _LOCAL_LIBCPP_EXPLICIT
87 #define _LIBCPP_EXPLICIT explicit
88 #endif
89 
90 //#ifndef _LIBCPP_CONSTEXPR_AFTER_CXX11
91 //#define _LOCAL_LIBCPP_CONSTEXPR_AFTER_CXX11
92 //#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
93 //#endif
94 
95 #ifdef _LIBCPP_STD_VER
96 #define _LOCAL_LIBCPP_STD_VER
97 #define _LIBCPP_STD_VER 11
98 #endif
99 
100 #ifndef _LIBCPP_TYPE_VIS_ONLY
101 #define _LOCAL_LIBCPP_TYPE_VIS_ONLY
102 #define _LIBCPP_TYPE_VIS_ONLY
103 #endif
104 
105 #ifndef _LIBCPP_CONSTEXPR_AFTER_CXX11
106 #define _LOCAL_LIBCPP_CONSTEXPR_AFTER_CXX11
107 #define _LIBCPP_CONSTEXPR_AFTER_CXX11
108 #endif
109 
110 #ifndef _NOEXCEPT
111 #define _LOCAL_NOEXCEPT
112 #define _NOEXCEPT
113 #endif
114 
115 #ifndef _LIBCPP_ASSERT
116 #define _LOCAL_LIBCPP_ASSERT
117 #define _LIBCPP_ASSERT(X,Y) ((void)0)
118 #endif
119 
120 /* Also used:
121  _LIBCPP_TYPE_VIS_ONLY
122  _LIBCPP_CONSTEXPR_AFTER_CXX11
123  */
124 
125 namespace std {
126 #ifdef _LOCAL_VSTD
127 inline namespace __ROOT {
128 #else
129 // libC++ wins.
130 inline namespace __1 {
131 #endif
132 
133  // template <class _Traits>
134  // struct _LIBCPP_HIDDEN __traits_eq
135  // {
136  // typedef typename _Traits::char_type char_type;
137  // _LIBCPP_INLINE_VISIBILITY
138  // bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
139  // {return _Traits::eq(__x, __y);}
140  // };
141  template <class _CharT, class _OutputIterator>
142  _OutputIterator
143  __pad_and_output(_OutputIterator __s,
144  const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
145  ios_base& __iob, _CharT __fl)
146  {
147  streamsize __sz = __oe - __ob;
148  streamsize __ns = __iob.width();
149  if (__ns > __sz)
150  __ns -= __sz;
151  else
152  __ns = 0;
153  for (;__ob < __op; ++__ob, ++__s)
154  *__s = *__ob;
155  for (; __ns; --__ns, ++__s)
156  *__s = __fl;
157  for (; __ob < __oe; ++__ob, ++__s)
158  *__s = *__ob;
159  __iob.width(0);
160  return __s;
161  }
162 
163  template<class _CharT, class _Traits>
164  basic_ostream<_CharT, _Traits>&
165  R__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
166  const _CharT* __str, size_t __len)
167  {
168 #if 0
169 //#ifndef _LIBCPP_NO_EXCEPTIONS
170  try
171  {
172 #endif // _LIBCPP_NO_EXCEPTIONS
173  typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
174  if (__s)
175  {
176  typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
177  if (__pad_and_output(_Ip(__os),
178  __str,
179  (__os.flags() & ios_base::adjustfield) == ios_base::left ?
180  __str + __len :
181  __str,
182  __str + __len,
183  __os,
184  __os.fill()).failed())
185  __os.setstate(ios_base::badbit | ios_base::failbit);
186  }
187 #if 0
188 //#ifndef _LIBCPP_NO_EXCEPTIONS
189  }
190  catch (...)
191  {
192  __os.__set_badbit_and_consider_rethrow();
193  }
194 #endif // _LIBCPP_NO_EXCEPTIONS
195  return __os;
196  }
197 
198 #ifdef _LOCAL_VSTD
199  // search
200 
201  template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
202  _ForwardIterator1
203  __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
204  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
205  forward_iterator_tag, forward_iterator_tag)
206  {
207  if (__first2 == __last2)
208  return __first1; // Everything matches an empty sequence
209  while (true)
210  {
211  // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
212  while (true)
213  {
214  if (__first1 == __last1) // return __last1 if no element matches *__first2
215  return __last1;
216  if (__pred(*__first1, *__first2))
217  break;
218  ++__first1;
219  }
220  // *__first1 matches *__first2, now match elements after here
221  _ForwardIterator1 __m1 = __first1;
222  _ForwardIterator2 __m2 = __first2;
223  while (true)
224  {
225  if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
226  return __first1;
227  if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
228  return __last1;
229  if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
230  {
231  ++__first1;
232  break;
233  } // else there is a match, check next elements
234  }
235  }
236  }
237 
238  template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
239  _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
240  __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
241  _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
242  random_access_iterator_tag, random_access_iterator_tag)
243  {
244  typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1;
245  typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2;
246  // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
247  _D2 __len2 = __last2 - __first2;
248  if (__len2 == 0)
249  return __first1;
250  _D1 __len1 = __last1 - __first1;
251  if (__len1 < __len2)
252  return __last1;
253  const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here
254  while (true)
255  {
256 #if !_LIBCPP_UNROLL_LOOPS
257  while (true)
258  {
259  if (__first1 == __s)
260  return __last1;
261  if (__pred(*__first1, *__first2))
262  break;
263  ++__first1;
264  }
265 #else // !_LIBCPP_UNROLL_LOOPS
266  for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll)
267  {
268  if (__pred(*__first1, *__first2))
269  goto __phase2;
270  if (__pred(*++__first1, *__first2))
271  goto __phase2;
272  if (__pred(*++__first1, *__first2))
273  goto __phase2;
274  if (__pred(*++__first1, *__first2))
275  goto __phase2;
276  ++__first1;
277  }
278  switch (__s - __first1)
279  {
280  case 3:
281  if (__pred(*__first1, *__first2))
282  break;
283  ++__first1;
284  case 2:
285  if (__pred(*__first1, *__first2))
286  break;
287  ++__first1;
288  case 1:
289  if (__pred(*__first1, *__first2))
290  break;
291  case 0:
292  return __last1;
293  }
294  __phase2:
295 #endif // !_LIBCPP_UNROLL_LOOPS
296  _RandomAccessIterator1 __m1 = __first1;
297  _RandomAccessIterator2 __m2 = __first2;
298 #if !_LIBCPP_UNROLL_LOOPS
299  while (true)
300  {
301  if (++__m2 == __last2)
302  return __first1;
303  ++__m1; // no need to check range on __m1 because __s guarantees we have enough source
304  if (!__pred(*__m1, *__m2))
305  {
306  ++__first1;
307  break;
308  }
309  }
310 #else // !_LIBCPP_UNROLL_LOOPS
311  ++__m2;
312  ++__m1;
313  for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll)
314  {
315  if (!__pred(*__m1, *__m2))
316  goto __continue;
317  if (!__pred(*++__m1, *++__m2))
318  goto __continue;
319  if (!__pred(*++__m1, *++__m2))
320  goto __continue;
321  if (!__pred(*++__m1, *++__m2))
322  goto __continue;
323  ++__m1;
324  ++__m2;
325  }
326  switch (__last2 - __m2)
327  {
328  case 3:
329  if (!__pred(*__m1, *__m2))
330  break;
331  ++__m1;
332  ++__m2;
333  case 2:
334  if (!__pred(*__m1, *__m2))
335  break;
336  ++__m1;
337  ++__m2;
338  case 1:
339  if (!__pred(*__m1, *__m2))
340  break;
341  case 0:
342  return __first1;
343  }
344  __continue:
345  ++__first1;
346 #endif // !_LIBCPP_UNROLL_LOOPS
347  }
348  }
349 
350 #endif // _LOCAL_VSTD for __search
351 
352  template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
353  _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1
354  __find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
355  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
356  {
357  for (; __first1 != __last1; ++__first1)
358  for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
359  if (__pred(*__first1, *__j))
360  return __first1;
361  return __last1;
362  }
363 
364  // __str_find
365  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
367  __str_find(const _CharT *__p, _SizeT __sz,
368  _CharT __c, _SizeT __pos) _NOEXCEPT
369  {
370  if (__pos >= __sz)
371  return __npos;
372  const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
373  if (__r == 0)
374  return __npos;
375  return static_cast<_SizeT>(__r - __p);
376 }
377 
378  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
380  __str_find(const _CharT *__p, _SizeT __sz,
381  const _CharT* __s, _SizeT __pos, _SizeT __n)
382  {
383  if (__pos > __sz || __sz - __pos < __n)
384  return __npos;
385  if (__n == 0)
386  return __pos;
387  const _CharT* __r =
388  _VSTD::__search(__p + __pos, __p + __sz,
389  __s, __s + __n, _Traits::eq,
390  random_access_iterator_tag(), random_access_iterator_tag());
391  if (__r == __p + __sz)
392  return __npos;
393  return static_cast<_SizeT>(__r - __p);
394  }
395 
396 
397  // __str_rfind
398 
399  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
401  __str_rfind(const _CharT *__p, _SizeT __sz,
402  _CharT __c, _SizeT __pos)
403  {
404  if (__sz < 1)
405  return __npos;
406  if (__pos < __sz)
407  ++__pos;
408  else
409  __pos = __sz;
410  for (const _CharT* __ps = __p + __pos; __ps != __p;)
411  {
412  if (_Traits::eq(*--__ps, __c))
413  return static_cast<_SizeT>(__ps - __p);
414  }
415  return __npos;
416  }
417 
418  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
420  __str_rfind(const _CharT *__p, _SizeT __sz,
421  const _CharT* __s, _SizeT __pos, _SizeT __n)
422  {
423  __pos = _VSTD::min(__pos, __sz);
424  if (__n < __sz - __pos)
425  __pos += __n;
426  else
427  __pos = __sz;
428  const _CharT* __r = _VSTD::__find_end(
429  __p, __p + __pos, __s, __s + __n, _Traits::eq,
430  random_access_iterator_tag(), random_access_iterator_tag());
431  if (__n > 0 && __r == __p + __pos)
432  return __npos;
433  return static_cast<_SizeT>(__r - __p);
434  }
435 
436  // __str_find_first_of
437  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
439  __str_find_first_of(const _CharT *__p, _SizeT __sz,
440  const _CharT* __s, _SizeT __pos, _SizeT __n)
441  {
442  if (__pos >= __sz || __n == 0)
443  return __npos;
444  const _CharT* __r = _VSTD::__find_first_of_ce
445  (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
446  if (__r == __p + __sz)
447  return __npos;
448  return static_cast<_SizeT>(__r - __p);
449  }
450 
451 
452  // __str_find_last_of
453  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
455  __str_find_last_of(const _CharT *__p, _SizeT __sz,
456  const _CharT* __s, _SizeT __pos, _SizeT __n)
457  {
458  if (__n != 0)
459  {
460  if (__pos < __sz)
461  ++__pos;
462  else
463  __pos = __sz;
464  for (const _CharT* __ps = __p + __pos; __ps != __p;)
465  {
466  const _CharT* __r = _Traits::find(__s, __n, *--__ps);
467  if (__r)
468  return static_cast<_SizeT>(__ps - __p);
469  }
470  }
471  return __npos;
472  }
473 
474 
475  // __str_find_first_not_of
476  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
478  __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
479  const _CharT* __s, _SizeT __pos, _SizeT __n)
480  {
481  if (__pos < __sz)
482  {
483  const _CharT* __pe = __p + __sz;
484  for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
485  if (_Traits::find(__s, __n, *__ps) == 0)
486  return static_cast<_SizeT>(__ps - __p);
487  }
488  return __npos;
489  }
490 
491 
492  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
494  __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
495  _CharT __c, _SizeT __pos)
496  {
497  if (__pos < __sz)
498  {
499  const _CharT* __pe = __p + __sz;
500  for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
501  if (!_Traits::eq(*__ps, __c))
502  return static_cast<_SizeT>(__ps - __p);
503  }
504  return __npos;
505  }
506 
507 
508  // __str_find_last_not_of
509  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
511  __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
512  const _CharT* __s, _SizeT __pos, _SizeT __n)
513  {
514  if (__pos < __sz)
515  ++__pos;
516  else
517  __pos = __sz;
518  for (const _CharT* __ps = __p + __pos; __ps != __p;)
519  if (_Traits::find(__s, __n, *--__ps) == 0)
520  return static_cast<_SizeT>(__ps - __p);
521  return __npos;
522  }
523 
524 
525  template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
527  __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
528  _CharT __c, _SizeT __pos)
529  {
530  if (__pos < __sz)
531  ++__pos;
532  else
533  __pos = __sz;
534  for (const _CharT* __ps = __p + __pos; __ps != __p;)
535  if (!_Traits::eq(*--__ps, __c))
536  return static_cast<_SizeT>(__ps - __p);
537  return __npos;
538  }
539 
540 } // namespace __1 or __ROOT
541 
542 } // namespace std
543 
544 // Now include the main meat
545 #include "libcpp_string_view.h"
546 
547 
548 // And undo
549 #ifdef _LOCAL_LIBCPP_BEGIN_NAMESPACE_LFTS
550 #undef _LIBCPP_BEGIN_NAMESPACE_LFTS
551 #undef _LIBCPP_END_NAMESPACE_LFTS
552 #endif
553 
554 #ifdef _LOCAL_LIBCPP_BEGIN_NAMESPACE_STD
555 #undef _LIBCPP_BEGIN_NAMESPACE_STD
556 #undef _LIBCPP_END_NAMESPACE_STD
557 #endif
558 
559 #ifdef _LOCAL_LIBCPP_CONSTEXPR
560 #undef _LIBCPP_CONSTEXPR
561 #endif
562 
563 #ifdef _LOCAL_VSTD
564 #undef _VSTD
565 #endif
566 
567 #ifdef _LOCAL_LIBCPP_INLINE_VISIBILITY
568 #undef _LIBCPP_INLINE_VISIBILITY
569 #endif
570 
571 #ifdef _LOCAL_LIBCPP_STD_VER
572 #undef _LIBCPP_STD_VER
573 #endif
574 
575 #ifdef _LOCAL_LIBCPP_TYPE_VIS_ONLY
576 #undef _LIBCPP_TYPE_VIS_ONLY
577 #endif
578 
579 #ifdef _LOCAL_LIBCPP_CONSTEXPR_AFTER_CXX11
580 #undef _LIBCPP_CONSTEXPR_AFTER_CXX11
581 #endif
582 
583 #ifdef _LOCAL_NOEXCEPT
584 #undef _NOEXCEPT
585 #endif
586 
587 #ifdef _LOCAL_LIBCPP_ASSERT
588 #undef _LIBCPP_ASSERT
589 #endif
590 
591 #endif // RWrap_libcpp_string_view_h
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_not_of(const _CharT *__p, _SizeT __sz, const _CharT *__s, _SizeT __pos, _SizeT __n)
#define _LIBCPP_CONSTEXPR_AFTER_CXX11
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_rfind(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos)
_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag)
STL namespace.
_OutputIterator __pad_and_output(_OutputIterator __s, const _CharT *__ob, const _CharT *__op, const _CharT *__oe, ios_base &__iob, _CharT __fl)
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_of(const _CharT *__p, _SizeT __sz, const _CharT *__s, _SizeT __pos, _SizeT __n)
#define _LIBCPP_INLINE_VISIBILITY
_ForwardIterator1 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag)
_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
#define _NOEXCEPT
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_of(const _CharT *__p, _SizeT __sz, const _CharT *__s, _SizeT __pos, _SizeT __n)
basic_ostream< _CharT, _Traits > & R__put_character_sequence(basic_ostream< _CharT, _Traits > &__os, const _CharT *__str, size_t __len)
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT
_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_not_of(const _CharT *__p, _SizeT __sz, const _CharT *__s, _SizeT __pos, _SizeT __n)