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