MySQL  8.0.21
Source Code Documentation
string_view.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License, version 2.0,
6  as published by the Free Software Foundation.
7 
8  This program is also distributed with certain software (including
9  but not limited to OpenSSL) that is licensed under separate terms,
10  as designated in a particular file or component or in included license
11  documentation. The authors of MySQL hereby grant you an additional
12  permission to link the program and your derivative works with the
13  separately licensed software that they have included with MySQL.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24 
25 #ifndef MYSQL_HARNESS_STDX_STRING_VIEW_INCLUDED
26 #define MYSQL_HARNESS_STDX_STRING_VIEW_INCLUDED
27 
28 #include <algorithm> // copy_n
29 #include <cstddef> // ptrdiff_t
30 #include <functional> // hash
31 #include <ostream>
32 #include <stdexcept> // out_of_range
33 #include <string>
34 
35 namespace stdx {
36 
37 // implementation of C++17's std::string_view on C++11:
38 //
39 // see http://wg21.link/N3762
40 //
41 // missing features:
42 //
43 // - most of the find_xxx() methods
44 // - padding support for ostream
45 
46 #ifndef __has_builtin
47 #define __has_builtin(x) 0
48 #endif
49 
50 #ifndef __has_cpp_attribute
51 #define __has_cpp_attribute(x) 0
52 #endif
53 
54 #if __has_cpp_attribute(gnu::nonnull)
55 #define STDX_NONNULL [[gnu::nonnull]]
56 #else
57 #define STDX_NONNULL
58 #endif
59 
60 namespace impl {
61 // constexpr variant of std::char_traits<charT>::length()
62 template <class charT>
63 constexpr size_t char_traits_length(const charT *s) noexcept;
64 
65 template <class charT>
66 constexpr size_t char_traits_length(const charT *s) noexcept {
67  size_t len{};
68  for (; *s; ++s, ++len)
69  ;
70  return len;
71 }
72 
73 #if __has_builtin(__builtin_strlen) || defined(__GNUC__)
74 // strlen() isn't constexpr, but __builtin_strlen() is with GCC and clang.
75 // MSVC has __builtin_strlen() too ... but how to detect that?
76 template <>
77 constexpr size_t char_traits_length(const char *s) noexcept {
78  return __builtin_strlen(s);
79 }
80 #endif
81 
82 #if __has_builtin(__builtin_wcslen)
83 // wcslen() isn't constexpr, but __builtin_wcslen() is with clang.
84 template <>
85 constexpr size_t char_traits_length(const wchar_t *s) noexcept {
86  return __builtin_wcslen(s);
87 }
88 #endif
89 
90 // constexpr variant of c::std::char_traits<charT>::compare()
91 template <class charT, class traits = std::char_traits<charT>>
92 constexpr int char_traits_compare(const charT *a, const charT *b,
93  size_t len) noexcept;
94 
95 template <class charT, class traits>
96 STDX_NONNULL constexpr int char_traits_compare(const charT *a, const charT *b,
97  size_t len) noexcept {
98  for (size_t ndx{}; ndx < len; ++ndx) {
99  if (traits::lt(a[ndx], b[ndx])) return -1;
100  if (traits::lt(b[ndx], a[ndx])) return 1;
101  }
102 
103  return 0;
104 }
105 
106 #if __has_builtin(__builtin_memcmp) || defined(__GNUC__)
107 // in case of charT == char and and traits std::char_traits<char> we can
108 // optimize by falling back to __builtin_memcmp() if it exists
109 //
110 // compare() isn't constexpr, but __builtin_memcmp() is with GCC and clang.
111 // MSVC has __builtin_memcmp() too ... but how to detect that?
112 template <>
113 STDX_NONNULL constexpr int char_traits_compare<char, std::char_traits<char>>(
114  const char *a, const char *b, size_t len) noexcept {
115  if (len == 0) return 0;
116 
117  return __builtin_memcmp(a, b, len);
118 }
119 #endif
120 
121 #if __has_builtin(__builtin_wmemcmp)
122 // in case of charT == wchar_t and and traits std::char_traits<wchar_t> we can
123 // optimize by falling back to __builtin_wmemcmp() if it exists
124 //
125 // compare() isn't constexpr, but __builtin_wmemcmp() is with clang.
126 template <>
127 STDX_NONNULL constexpr int
128 char_traits_compare<wchar_t, std::char_traits<wchar_t>>(const wchar_t *a,
129  const wchar_t *b,
130  size_t len) noexcept {
131  if (len == 0) return 0;
132 
133  return __builtin_wmemcmp(a, b, len);
134 }
135 #endif
136 
137 /**
138  * find first occurence of needle in a haystack.
139  *
140  * @param haystack string of character to search needle in
141  * @param haystack_len length of haystack in characters
142  * @param needle string of characters for find in haystack
143  * @param needle_len length of needle in characters
144  * @returns pointer to the position where needle is found in the haystack
145  * @retval nullptr if needle wasn't found
146  */
147 template <class charT, class traits = std::char_traits<charT>>
148 STDX_NONNULL const charT *memmatch(const charT *haystack, size_t haystack_len,
149  const charT *needle, size_t needle_len) {
150  // a empty needle
151  if (needle_len == 0) return haystack;
152 
153  const charT *haystack_end = haystack + haystack_len;
154  const charT *needle_start = needle;
155  const charT *needle_end = needle + needle_len;
156 
157  for (; haystack < haystack_end; ++haystack) {
158  if (traits::eq(*haystack, *needle)) {
159  if (++needle == needle_end) {
160  // end of needle reached, all characters matched.
161  return haystack + 1 - needle_len;
162  }
163  } else if (needle != needle_start) {
164  // rewind haystack to before the needle which started the match
165  haystack -= needle - needle_start;
166 
167  // reset the needle to its initial value
168  needle = needle_start;
169  }
170  }
171 
172  return nullptr;
173 }
174 
175 template <class T>
176 using identity = std::decay_t<T>;
177 
178 } // namespace impl
179 
180 template <class charT, class traits = std::char_traits<charT>>
182  public:
183  using traits_type = traits;
184  using value_type = charT;
185  using pointer = const value_type *;
186  using const_pointer = const value_type *;
187  using reference = const value_type &;
188  using const_reference = const value_type &;
189  using const_iterator = const value_type *;
191  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
193 
194  using size_type = size_t;
195  using difference_type = ptrdiff_t;
196  // in C++17 we can do:
197  //
198  // static constexpr size_t npos = size_type(-1);
199  //
200  // which needs a definition in a .cc file. Using a enum should do the trick
201  // too in C++11 without a .cc file.
202  enum : size_type { npos = size_type(-1) };
203 
204  constexpr basic_string_view() noexcept : ptr_(nullptr), length_(0) {}
205  constexpr basic_string_view(const basic_string_view &rhs) noexcept = default;
206  constexpr basic_string_view &operator=(const basic_string_view &) noexcept =
207  default;
208 
209  template <typename Allocator>
210  constexpr basic_string_view(
211  const std::basic_string<value_type, traits_type, Allocator> &str) noexcept
212  : ptr_{str.data()}, length_{str.size()} {}
213 
215  : ptr_{data}, length_{impl::char_traits_length(data)} {}
216 
218  : ptr_{data}, length_{len} {}
219 
220  // [string.view.iterators]
221  constexpr const_iterator begin() const noexcept { return ptr_; }
222  constexpr const_iterator end() const noexcept { return ptr_ + length_; }
223  constexpr const_iterator cbegin() const noexcept { return begin(); }
224  constexpr const_iterator cend() const noexcept { return end(); }
225 
226  constexpr const_reverse_iterator rbegin() const noexcept {
227  return const_reverse_iterator(end());
228  }
229  constexpr const_reverse_iterator rend() const noexcept {
230  return const_reverse_iterator(begin());
231  }
232  constexpr const_reverse_iterator crbegin() const noexcept {
233  return const_reverse_iterator(end());
234  }
235  constexpr const_reverse_iterator crend() const noexcept {
236  return const_reverse_iterator(begin());
237  }
238 
239  // [string.view.capacity]
240  constexpr size_type size() const noexcept { return length_; }
241  constexpr size_type length() const noexcept { return length_; }
242  constexpr size_type max_size() const noexcept {
243  return (npos - sizeof(size_type)) / sizeof(value_type);
244  }
245  constexpr bool empty() const noexcept { return length_ == 0; }
246 
247  // [string.view.access]
248  constexpr const_reference operator[](size_type pos) const noexcept {
249  return ptr_[pos];
250  }
251  constexpr const_reference at(size_type pos) const {
252  // we may throw if pos > length
253  return ptr_[pos];
254  }
255 
256  /**
257  * first element.
258  *
259  * - Requires: !empty()
260  *
261  * @returns ref to first element
262  */
263  constexpr const_reference front() const noexcept { return ptr_[0]; }
264 
265  /**
266  * last element.
267  *
268  * - Requires: !empty()
269  *
270  * @returns ref to last element
271  */
272  constexpr const_reference back() const noexcept { return ptr_[length_ - 1]; }
273 
274  /**
275  * pointer to underlaying data.
276  *
277  * may not be null-terminated.
278  */
279  constexpr const_pointer data() const noexcept { return ptr_; }
280 
281  // [string.view.modifiers]
282  void clear() noexcept { *this = basic_string_view(); }
283 
284  // requires: n <= size()
285  void remove_prefix(size_type n) { *this = substr(n, npos); }
286 
287  // requires: n <= size()
288  void remove_suffix(size_type n) { *this = substr(0, size() - n); }
289 
290  void swap(basic_string_view &s) noexcept {
291  auto tmp = *this;
292  *this = s;
293  s = tmp;
294  }
295 
296  // [string.view.ops]
297  template <class Allocator>
298  explicit operator std::basic_string<charT, traits, Allocator>() const {
299  return {begin(), end()};
300  }
301 
302  /**
303  * copy into external buffer.
304  *
305  * if n > characters available: rest of string
306  *
307  * @param s pointer to start of destination
308  * @param n character-length of s
309  * @param pos start position
310  * @throws std::out_of_range if pos > size()
311  */
312  size_type copy(charT *s, size_type n, size_type pos = 0) const {
313  if (pos > size()) throw std::out_of_range("...");
314 
315  size_t rlen = std::min(n, size() - pos);
316 
317  std::copy_n(begin() + pos, rlen, s);
318 
319  return rlen;
320  }
321 
322  /**
323  * get substring of a string_view.
324  *
325  * if n > characters available: rest of string
326  *
327  * @param pos start position
328  * @param n length of substring from start position
329  * @throws std::out_of_range if pos > size()
330  */
332  size_type n = npos) const {
333  if (pos > size()) throw std::out_of_range("...");
334 
335  size_t rlen = std::min(n, size() - pos);
336 
337  return {data() + pos, rlen};
338  }
339 
340  constexpr int compare(basic_string_view s) const noexcept {
341  size_t rlen = std::min(size(), s.size());
342 
343  if (rlen > 0) {
344  int res =
345  impl::char_traits_compare<charT, traits_type>(data(), s.data(), rlen);
346  if (res != 0) return res;
347  }
348 
349  return size() - s.size();
350  }
351 
352  constexpr int compare(size_t pos1, size_type n1, basic_string_view s) const {
353  return substr(pos1, n1).compare(s);
354  }
355 
356  constexpr int compare(size_t pos1, size_type n1, basic_string_view s,
357  size_type pos2, size_type n2) const {
358  return substr(pos1, n1).compare(s.substr(pos2, n2));
359  }
360 
361  constexpr int compare(const value_type *s) const {
362  return compare(basic_string_view(s));
363  }
364  constexpr int compare(size_t pos1, size_type n1, const value_type *s) const {
365  return compare(pos1, n1, basic_string_view(s));
366  }
367  constexpr int compare(size_t pos1, size_type n1, const value_type *s,
368  size_type pos2, size_type n2) const {
369  return compare(pos1, n1, basic_string_view(s), pos2, n2);
370  }
371 
372  // [string.view.find]
373 
374  size_type find(basic_string_view str, size_type pos = 0) const noexcept {
375  if (empty() || pos > length()) {
376  if (empty() && pos == 0 && str.empty()) return 0;
377 
378  return npos;
379  }
380 
381  if (const charT *result = impl::memmatch<charT, traits_type>(
382  ptr_ + pos, length_ - pos, str.data(), str.size())) {
383  return result - ptr_;
384  }
385 
386  return npos;
387  }
388 
389  private:
390  const value_type *ptr_;
392 };
393 
394 // ==
395 template <class charT, class traits>
398  return a.compare(b) == 0;
399 }
400 
401 #if defined(_MSC_VER)
402 // workaround a limitation in the MSVC name mangling which results in:
403 //
404 // definition with same mangled name
405 // '??$?8_WU?$char_traits@_W@std@@@stdx@@YA_NV?$basic_string_view@_WU?$char_traits@_W@std@@@0@0@Z'
406 // as another definition
407 //
408 // msvc CRT marks the operators with: TRANSITION, VSO#409326
409 #define MSVC_ORDER(x) , int = x
410 #else
411 #define MSVC_ORDER(x) /*, int = x */
412 #endif
413 
414 template <class charT, class traits MSVC_ORDER(1)>
415 constexpr bool operator==(
418  return a.compare(b) == 0;
419 }
420 
421 template <class charT, class traits MSVC_ORDER(2)>
424  return a.compare(b) == 0;
425 }
426 
427 // !=
428 template <class charT, class traits>
431  return a.compare(b) != 0;
432 }
433 
434 template <class charT, class traits MSVC_ORDER(1)>
435 constexpr bool operator!=(
438  return a.compare(b) != 0;
439 }
440 
441 template <class charT, class traits MSVC_ORDER(2)>
444  return a.compare(b) != 0;
445 }
446 
447 // >
448 template <class charT, class traits>
451  return a.compare(b) > 0;
452 }
453 
454 template <class charT, class traits MSVC_ORDER(1)>
455 constexpr bool operator>(
458  return a.compare(b) > 0;
459 }
460 
461 template <class charT, class traits MSVC_ORDER(2)>
464  return a.compare(b) > 0;
465 }
466 
467 // <
468 template <class charT, class traits>
469 constexpr bool operator<(basic_string_view<charT, traits> a,
471  return a.compare(b) < 0;
472 }
473 
474 template <class charT, class traits MSVC_ORDER(1)>
475 constexpr bool operator<(
478  return a.compare(b) < 0;
479 }
480 
481 template <class charT, class traits MSVC_ORDER(2)>
482 constexpr bool operator<(impl::identity<basic_string_view<charT, traits>> a,
484  return a.compare(b) < 0;
485 }
486 
487 // <=
488 template <class charT, class traits>
489 constexpr bool operator<=(basic_string_view<charT, traits> a,
491  return a.compare(b) <= 0;
492 }
493 
494 template <class charT, class traits MSVC_ORDER(1)>
495 constexpr bool operator<=(
498  return a.compare(b) <= 0;
499 }
500 
501 template <class charT, class traits MSVC_ORDER(2)>
502 constexpr bool operator<=(impl::identity<basic_string_view<charT, traits>> a,
504  return a.compare(b) <= 0;
505 }
506 
507 // =>
508 template <class charT, class traits>
511  return a.compare(b) >= 0;
512 }
513 
514 template <class charT, class traits MSVC_ORDER(1)>
515 constexpr bool operator>=(
518  return a.compare(b) >= 0;
519 }
520 
521 template <class charT, class traits MSVC_ORDER(2)>
524  return a.compare(b) >= 0;
525 }
526 
527 #undef MSVC_ORDER
528 
529 template <class charT, class traits = std::char_traits<charT>,
530  class Allocator = std::allocator<charT>>
531 std::basic_string<charT, traits, Allocator> to_string(
532  basic_string_view<charT, traits> str, const Allocator &a = Allocator()) {
533  return {str.begin(), str.end(), a};
534 }
535 
536 template <class charT, class traits>
537 std::basic_ostream<charT, traits> &operator<<(
538  std::basic_ostream<charT, traits> &o, basic_string_view<charT, traits> sv) {
539  typename std::basic_ostream<charT, traits>::sentry sentry(o);
540 
541  if (sentry) {
542  o.write(sv.data(), sv.size());
543  o.width(0);
544  }
545 
546  return o;
547 }
548 
549 inline namespace literals {
550 inline namespace string_view_literals {
551 inline constexpr basic_string_view<char> operator""_sv(const char *str,
552  size_t len) noexcept {
553  return basic_string_view<char>{str, len};
554 }
555 inline constexpr basic_string_view<wchar_t> operator""_sv(const wchar_t *str,
556  size_t len) noexcept {
557  return basic_string_view<wchar_t>{str, len};
558 }
559 inline constexpr basic_string_view<char16_t> operator""_sv(
560  const char16_t *str, size_t len) noexcept {
561  return basic_string_view<char16_t>{str, len};
562 }
563 inline constexpr basic_string_view<char32_t> operator""_sv(
564  const char32_t *str, size_t len) noexcept {
565  return basic_string_view<char32_t>{str, len};
566 }
567 } // namespace string_view_literals
568 } // namespace literals
569 
574 
575 } // namespace stdx
576 
577 namespace std {
578 // [string.view.hash]
579 template <>
581  size_t operator()(stdx::string_view s) const noexcept {
582  return std::hash<std::string>()(std::string{s.data(), s.size()});
583  }
584 };
585 template <>
587  size_t operator()(stdx::wstring_view s) const noexcept {
588  return std::hash<std::wstring>()(std::wstring{s.data(), s.size()});
589  }
590 };
591 
592 template <>
594  size_t operator()(stdx::u16string_view s) const noexcept {
595  return std::hash<std::u16string>()(std::u16string{s.data(), s.size()});
596  }
597 };
598 template <>
600  size_t operator()(stdx::u32string_view s) const noexcept {
601  return std::hash<std::u32string>()(std::u32string{s.data(), s.size()});
602  }
603 };
604 } // namespace std
605 
606 #endif
Definition: result.h:29
constexpr bool operator<=(basic_string_view< charT, traits > a, basic_string_view< charT, traits > b) noexcept
Definition: string_view.h:489
constexpr size_t char_traits_length(const charT *s) noexcept
Definition: string_view.h:66
constexpr basic_string_view(const std::basic_string< value_type, traits_type, Allocator > &str) noexcept
Definition: string_view.h:210
size_type length_
Definition: string_view.h:391
constexpr int char_traits_compare(const charT *a, const charT *b, size_t len) noexcept
Definition: string_view.h:96
constexpr const_reference at(size_type pos) const
Definition: string_view.h:251
std::enable_if_t< impl::is_to_stream_writable< std::ostream, T >::value &&impl::is_to_stream_writable< std::ostream, E >::value, std::ostream & > operator<<(std::ostream &os, const stdx::expected< T, E > &res)
write stdx::expected<T, E> to std::ostream.
Definition: expected_ostream.h:65
constexpr const_iterator cbegin() const noexcept
Definition: string_view.h:223
constexpr int compare(size_t pos1, size_type n1, basic_string_view s, size_type pos2, size_type n2) const
Definition: string_view.h:356
constexpr const_pointer data() const noexcept
pointer to underlaying data.
Definition: string_view.h:279
Definition: string_view.h:181
charT value_type
Definition: string_view.h:184
basic_string_view< char32_t > u32string_view
Definition: string_view.h:573
size_type copy(charT *s, size_type n, size_type pos=0) const
copy into external buffer.
Definition: string_view.h:312
constexpr const_iterator end() const noexcept
Definition: string_view.h:222
constexpr int compare(size_t pos1, size_type n1, basic_string_view s) const
Definition: string_view.h:352
Definition: authentication.cc:36
constexpr size_type length() const noexcept
Definition: string_view.h:241
constexpr int compare(size_t pos1, size_type n1, const value_type *s) const
Definition: string_view.h:364
basic_string_view< wchar_t > wstring_view
Definition: string_view.h:571
Definition: varlen_sort.h:182
constexpr size_type size() const noexcept
Definition: string_view.h:240
constexpr int compare(basic_string_view s) const noexcept
Definition: string_view.h:340
constexpr const_reference back() const noexcept
last element.
Definition: string_view.h:272
constexpr const_reference front() const noexcept
first element.
Definition: string_view.h:263
constexpr const_iterator begin() const noexcept
Definition: string_view.h:221
STDX_NONNULL constexpr basic_string_view(const_pointer data)
Definition: string_view.h:214
uint16_t value_type
Definition: vt100.h:182
basic_string_view< char > string_view
Definition: string_view.h:570
const_reverse_iterator reverse_iterator
Definition: string_view.h:192
char * pos
Definition: do_ctype.cc:76
#define STDX_NONNULL
Definition: string_view.h:57
constexpr bool operator>=(basic_string_view< charT, traits > a, basic_string_view< charT, traits > b) noexcept
Definition: string_view.h:509
void swap(basic_string_view &s) noexcept
Definition: string_view.h:290
const value_type & reference
Definition: string_view.h:187
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:188
constexpr const_reverse_iterator crend() const noexcept
Definition: string_view.h:235
constexpr const_reference operator[](size_type pos) const noexcept
Definition: string_view.h:248
basic_string_view< char16_t > u16string_view
Definition: string_view.h:572
constexpr int compare(const value_type *s) const
Definition: string_view.h:361
const value_type * const_iterator
Definition: string_view.h:189
constexpr int compare(size_t pos1, size_type n1, const value_type *s, size_type pos2, size_type n2) const
Definition: string_view.h:367
std::basic_string< charT, traits, Allocator > to_string(basic_string_view< charT, traits > str, const Allocator &a=Allocator())
Definition: string_view.h:531
traits traits_type
Definition: string_view.h:183
const value_type * ptr_
Definition: string_view.h:390
bool operator!=(const unexpected< E1 > &a, const unexpected< E2 > &b)
Definition: expected.h:1080
uint32_t hash(const void *key, size_t length, const uint32_t initval)
Definition: hash.c:121
constexpr basic_string_view() noexcept
Definition: string_view.h:204
STDX_NONNULL constexpr basic_string_view(const_pointer data, size_type len)
Definition: string_view.h:217
STDX_NONNULL const charT * memmatch(const charT *haystack, size_t haystack_len, const charT *needle, size_t needle_len)
find first occurence of needle in a haystack.
Definition: string_view.h:148
constexpr const_reverse_iterator rend() const noexcept
Definition: string_view.h:229
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: string_view.h:191
const value_type * pointer
Definition: string_view.h:185
size_t size_type
Definition: string_view.h:194
const value_type * const_pointer
Definition: string_view.h:186
size_t operator()(stdx::u32string_view s) const noexcept
Definition: string_view.h:600
void remove_suffix(size_type n)
Definition: string_view.h:288
constexpr bool operator>(basic_string_view< charT, traits > a, basic_string_view< charT, traits > b) noexcept
Definition: string_view.h:449
constexpr const_reverse_iterator crbegin() const noexcept
Definition: string_view.h:232
size_t operator()(stdx::u16string_view s) const noexcept
Definition: string_view.h:594
constexpr bool empty() const noexcept
Definition: string_view.h:245
Definition: bit.h:33
int n
Definition: xcom_base.cc:442
void clear() noexcept
Definition: string_view.h:282
size_type find(basic_string_view str, size_type pos=0) const noexcept
Definition: string_view.h:374
const_iterator iterator
Definition: string_view.h:190
constexpr bool operator<(basic_string_view< charT, traits > a, basic_string_view< charT, traits > b) noexcept
Definition: string_view.h:469
size_t operator()(stdx::wstring_view s) const noexcept
Definition: string_view.h:587
const value_type & const_reference
Definition: string_view.h:188
std::decay_t< T > identity
Definition: string_view.h:176
ptrdiff_t difference_type
Definition: string_view.h:195
bool operator==(const unexpected< E1 > &a, const unexpected< E2 > &b)
Definition: expected.h:1069
constexpr const_iterator cend() const noexcept
Definition: string_view.h:224
constexpr const_reverse_iterator rbegin() const noexcept
Definition: string_view.h:226
constexpr size_type max_size() const noexcept
Definition: string_view.h:242
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
static int compare(size_t a, size_t b)
Function to compare two size_t integers for their relative order.
Definition: rpl_utility.cc:103
size_t operator()(stdx::string_view s) const noexcept
Definition: string_view.h:581
void remove_prefix(size_type n)
Definition: string_view.h:285
constexpr basic_string_view substr(size_type pos=0, size_type n=npos) const
get substring of a string_view.
Definition: string_view.h:331