rapidyaml 0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
c4::basic_substring< C > Struct Template Reference

a non-owning string-view, consisting of a character pointer and a length. More...

#include <substr.hpp>

Classes

struct  first_of_any_result

Public Member Functions

Default construction and assignment
constexpr basic_substring () noexcept
 basic_substring (basic_substring const &) noexcept=default
 basic_substring (basic_substring &&) noexcept=default
 basic_substring (std::nullptr_t) noexcept
basic_substringoperator= (basic_substring const &) noexcept=default
basic_substringoperator= (basic_substring &&) noexcept=default
basic_substringoperator= (std::nullptr_t) noexcept
void clear () noexcept
Construction and assignment from characters with the same type
template<size_t N>
constexpr basic_substring (C(&s_)[N]) noexcept
 Construct from an array.
 basic_substring (C *s_, size_t len_) noexcept
 Construct from a pointer and length.
 basic_substring (C *beg_, C *end_) noexcept
 Construct from two pointers.
template<class CharPtr, typename std::enable_if< can_borrow_char_ptr< CharPtr, C >::value, int >::type = 0>
 basic_substring (CharPtr s_) noexcept
 Construct from a C-string (zero-terminated string).
template<size_t N>
void assign (C(&s_)[N]) noexcept
 Assign from an array.
void assign (C *s_, size_t len_) noexcept
 Assign from a pointer and length.
void assign (C *beg_, C *end_) noexcept
 Assign from two pointers.
template<class CharPtr, typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type = 0>
void assign (CharPtr s_) noexcept
 Assign from a C-string (zero-terminated string of type const C* or C*).
template<size_t N>
basic_substringoperator= (C(&s_)[N]) noexcept
 Assign from an array.
template<class CharPtr, typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type = 0>
basic_substringoperator= (CharPtr s_) noexcept
 Assign from a C-string (zero-terminated string of type const C* or C*).
Standard accessor methods
bool has_str () const noexcept
bool empty () const noexcept
bool not_empty () const noexcept
size_t size () const noexcept
iterator begin () noexcept
iterator end () noexcept
const_iterator begin () const noexcept
const_iterator end () const noexcept
C * data () noexcept
C const * data () const noexcept
C & operator[] (size_t i) noexcept
C const & operator[] (size_t i) const noexcept
C & front () noexcept
C const & front () const noexcept
C & back () noexcept
C const & back () const noexcept
Comparison methods
int compare (C const c) const noexcept
int compare (C const *that, size_t sz) const noexcept
template<class CharPtr>
auto compare (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class U>
int compare (basic_substring< U > const that) const noexcept
bool operator== (std::nullptr_t) const noexcept
bool operator!= (std::nullptr_t) const noexcept
bool operator== (C const c) const noexcept
bool operator!= (C const c) const noexcept
bool operator< (C const c) const noexcept
bool operator> (C const c) const noexcept
bool operator<= (C const c) const noexcept
bool operator>= (C const c) const noexcept
template<class U>
bool operator== (basic_substring< U > const that) const noexcept
template<class U>
bool operator!= (basic_substring< U > const that) const noexcept
template<class U>
bool operator< (basic_substring< U > const that) const noexcept
template<class U>
bool operator> (basic_substring< U > const that) const noexcept
template<class U>
bool operator<= (basic_substring< U > const that) const noexcept
template<class U>
bool operator>= (basic_substring< U > const that) const noexcept
template<size_t N>
bool operator== (const char(&arr)[N]) const noexcept
template<size_t N>
bool operator!= (const char(&arr)[N]) const noexcept
template<size_t N>
bool operator< (const char(&arr)[N]) const noexcept
template<size_t N>
bool operator> (const char(&arr)[N]) const noexcept
template<size_t N>
bool operator<= (const char(&arr)[N]) const noexcept
template<size_t N>
bool operator>= (const char(&arr)[N]) const noexcept
template<class CharPtr>
auto operator== (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class CharPtr>
auto operator!= (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class CharPtr>
auto operator< (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class CharPtr>
auto operator> (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class CharPtr>
auto operator<= (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
template<class CharPtr>
auto operator>= (CharPtr c_str) const noexcept -> typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
Sub-selection methods
bool is_sub (ro_substr const that) const noexcept
 true if *this is a substring of that (ie, from the same buffer)
bool is_super (ro_substr const that) const noexcept
 true if that is a substring of *this (ie, from the same buffer)
bool overlaps (ro_substr const that) const noexcept
 true if there is overlap of at least one element between that and *this
basic_substring sub (size_t first) const noexcept
 return [first,len[
basic_substring sub (size_t first, size_t num) const noexcept
 return [first,first+num[.
basic_substring range (size_t first, size_t last=npos) const noexcept
 return [first,last[.
basic_substring first (size_t num) const noexcept
 return the first num elements: [0,num[
basic_substring last (size_t num) const noexcept
 return the last num elements: [len-num,len[
basic_substring offs (size_t left, size_t right) const noexcept
 offset from the ends: return [left,len-right[ ; ie, trim a number of characters from the left and right.
basic_substring left_of (size_t pos) const noexcept
 return [0, pos[ .
basic_substring left_of (size_t pos, bool include_pos) const noexcept
 return [0, pos+include_pos[ .
basic_substring right_of (size_t pos) const noexcept
 return [pos+1, len[
basic_substring right_of (size_t pos, bool include_pos) const noexcept
 return [pos+!include_pos, len[
basic_substring left_of (ro_substr const subs) const noexcept
 given subs a substring of the current string, get the portion of the current string to the left of it
basic_substring right_of (ro_substr const subs) const noexcept
 given subs a substring of the current string, get the portion of the current string to the right of it
Removing characters (trim()) / patterns (strip()) from the tips of the string
basic_substring triml (const C c) const
 trim left
basic_substring triml (ro_substr chars) const
 trim left ANY of the characters.
basic_substring trimr (const C c) const
 trim the character c from the right
basic_substring trimr (ro_substr chars) const
 trim right ANY of the characters
basic_substring trim (const C c) const
 trim the character c left and right
basic_substring trim (ro_substr const chars) const
 trim left and right ANY of the characters
basic_substring stripl (ro_substr pattern) const
 remove a pattern from the left
basic_substring stripr (ro_substr pattern) const
 remove a pattern from the right
Lookup methods
size_t find (const C c, size_t start_pos=0) const
size_t find (ro_substr pattern, size_t start_pos=0) const
size_t count (const C c, size_t pos=0) const
 count the number of occurrences of c
size_t count (ro_substr c, size_t pos=0) const
 count the number of occurrences of s
basic_substring select (const C c, size_t pos=0) const
 get the substr consisting of the first occurrence of c after pos, or an empty substr if none occurs
basic_substring select (ro_substr pattern, size_t pos=0) const
 get the substr consisting of the first occurrence of pattern after pos, or an empty substr if none occurs
first_of_any_result first_of_any (ro_substr s0, ro_substr s1) const
first_of_any_result first_of_any (ro_substr s0, ro_substr s1, ro_substr s2) const
first_of_any_result first_of_any (ro_substr s0, ro_substr s1, ro_substr s2, ro_substr s3) const
first_of_any_result first_of_any (ro_substr s0, ro_substr s1, ro_substr s2, ro_substr s3, ro_substr s4) const
template<class It>
first_of_any_result first_of_any_iter (It first_span, It last_span) const
bool begins_with (const C c) const noexcept
 true if the first character of the string is c
bool begins_with (const C c, size_t num) const noexcept
 true if the first num characters of the string are c
bool begins_with (ro_substr pattern) const noexcept
 true if the string begins with the given pattern
bool begins_with_any (ro_substr chars) const noexcept
 true if the first character of the string is any of the given chars
bool ends_with (const C c) const noexcept
 true if the last character of the string is c
bool ends_with (const C c, const size_t num) const noexcept
 true if the last num characters of the string are c
bool ends_with (ro_substr pattern) const noexcept
 true if the string ends with the given pattern
bool ends_with_any (ro_substr chars) const noexcept
 true if the last character of the string is any of the given chars
size_t first_of (const C c, size_t start=0) const
size_t last_of (const C c, size_t start=npos) const
size_t first_of (ro_substr chars, size_t start=0) const
size_t last_of (ro_substr chars, size_t start=npos) const
size_t first_not_of (const C c) const
size_t first_not_of (const C c, size_t start) const
size_t last_not_of (const C c) const
size_t last_not_of (const C c, size_t start) const
size_t first_not_of (ro_substr chars) const
size_t first_not_of (ro_substr chars, size_t start) const
size_t last_not_of (ro_substr chars) const
size_t last_not_of (ro_substr chars, size_t start) const
Range lookup methods
basic_substring pair_range (CC open, CC close) const
 get the range delimited by an open-close pair of characters.
basic_substring pair_range_esc (CC open_close, CC escape=CC('\\'))
 get the range delimited by a single open-close character (eg, quotes).
basic_substring pair_range_nested (CC open, CC close) const
 get the range delimited by an open-close pair of characters, with possibly nested occurrences.
basic_substring unquoted () const
Path-like manipulation methods
basic_substring basename (C sep=C('/')) const
basic_substring dirname (C sep=C('/')) const
basic_substring name_wo_extshort () const
basic_substring name_wo_extlong () const
basic_substring extshort () const
basic_substring extlong () const
Content-modification methods (only for non-const C)
template<typename U = C>
auto toupper () -> typename std::enable_if< ! std::is_const< U >::value, void >::type
 convert the string to upper-case
template<typename U = C>
auto tolower () -> typename std::enable_if< !std::is_const< U >::value, void >::type
 convert the string to lower-case
template<typename U = C>
auto fill (C val) -> typename std::enable_if< !std::is_const< U >::value, void >::type
 fill the entire contents with the given val
template<typename U = C>
auto copy_from (ro_substr that) -> typename std::enable_if< !std::is_const< U >::value, void >::type
 copy a string to this substr, starting at 0
template<typename U = C>
auto copy_from (ro_substr that, size_t ifirst, size_t num=npos) -> typename std::enable_if< !std::is_const< U >::value, void >::type
 copy a string to this substr, starting at a specified given position
template<typename U = C>
auto reverse () -> typename std::enable_if< !std::is_const< U >::value, void >::type
 reverse in place
template<typename U = C>
auto reverse_sub (size_t ifirst, size_t num) -> typename std::enable_if< !std::is_const< U >::value, void >::type
 revert a subpart in place
template<typename U = C>
auto reverse_range (size_t ifirst, size_t ilast) -> typename std::enable_if< !std::is_const< U >::value, void >::type
 revert a range in place
template<typename U = C>
auto erase (size_t pos, size_t num) -> typename std::enable_if< !std::is_const< U >::value, basic_substring >::type
 erase part of the string.
template<typename U = C>
auto erase_range (size_t first, size_t last) -> typename std::enable_if< !std::is_const< U >::value, basic_substring >::type
template<typename U = C>
auto erase (ro_substr sub) -> typename std::enable_if< !std::is_const< U >::value, basic_substring >::type
 erase a part of the string.
template<typename U = C>
auto replace (C value, C repl, size_t pos=0) -> typename std::enable_if< ! std::is_const< U >::value, size_t >::type
 replace every occurrence of character value with the character repl
template<typename U = C>
auto replace (ro_substr chars, C repl, size_t pos=0) -> typename std::enable_if< ! std::is_const< U >::value, size_t >::type
 replace every occurrence of each character in value with the character repl.
size_t replace_all (rw_substr dst, ro_substr pattern, ro_substr repl, size_t pos=0) const
 replace pattern with repl, and write the result into dst.

Public Attributes

C * str
 a restricted pointer to the first character of the substring
size_t len
 the length of the substring

Types

enum  : size_t { npos = (size_t)-1 , NONE = (size_t)-1 }
using CC = typename std::add_const<C>::type
 CC=const char.
using NCC_ = typename std::remove_const<C>::type
 NCC_=non const char.
using ro_substr = basic_substring<CC>
using rw_substr = basic_substring<NCC_>
using value_type = C
using char_type = C
using size_type = size_t
using iterator = C*
using const_iterator = CC*
template<class U = C>
 operator typename std::enable_if<!std::is_const< U >::value, ro_substr const & >::type () const noexcept
 convert automatically from substr (of C) to csubstr (of const C)

Splitting methods

using split_proxy = split_proxy_impl
bool next_split (C sep, size_t *start_pos, basic_substring *out) const
 returns true if the string has not been exhausted yet, meaning it's ok to call next_split() again.
split_proxy split (C sep, size_t start_pos=0) const
 a view into the splits
basic_substring pop_right (C sep=C('/'), bool skip_empty=false) const
 pop right: return the first split from the right.
basic_substring pop_left (C sep=C('/'), bool skip_empty=false) const
 return the first split from the left.
basic_substring gpop_left (C sep=C('/'), bool skip_empty=false) const
 greedy pop left.
basic_substring gpop_right (C sep=C('/'), bool skip_empty=false) const
 greedy pop right.

Number-matching query methods

bool is_number () const
bool is_real () const
bool is_integer () const
bool is_unsigned_integer () const
basic_substring first_non_empty_span () const
 get the first span consisting exclusively of non-empty characters
basic_substring first_uint_span () const
 get the first span which can be interpreted as an unsigned integer
basic_substring first_int_span () const
 get the first span which can be interpreted as a signed integer
basic_substring _first_integral_span (size_t skip_start) const
basic_substring first_real_span () const
 get the first span which can be interpreted as a real (floating-point) number
basic_substring _word_follows (size_t pos, csubstr word) const noexcept
basic_substring _first_real_span_dec (size_t pos) const noexcept
basic_substring _first_real_span_hex (size_t pos) const noexcept
basic_substring _first_real_span_bin (size_t pos) const noexcept
basic_substring _first_real_span_oct (size_t pos) const noexcept
static constexpr C4_CONST bool _is_delim_char (char c) noexcept
 true if the character is a delimiter character at the end
static constexpr C4_CONST bool _is_hex_char (char c) noexcept
 true if the character is in [0-9a-fA-F]

Detailed Description

template<class C>
struct c4::basic_substring< C >

a non-owning string-view, consisting of a character pointer and a length.

Note
The pointer is explicitly restricted.
See also
a quickstart sample in rapidyaml's documentation.

Definition at line 211 of file substr.hpp.

Member Typedef Documentation

◆ CC

template<class C>
using c4::basic_substring< C >::CC = typename std::add_const<C>::type

CC=const char.

Definition at line 225 of file substr.hpp.

◆ NCC_

template<class C>
using c4::basic_substring< C >::NCC_ = typename std::remove_const<C>::type

NCC_=non const char.

Definition at line 226 of file substr.hpp.

◆ ro_substr

template<class C>
using c4::basic_substring< C >::ro_substr = basic_substring<CC>

Definition at line 228 of file substr.hpp.

◆ rw_substr

template<class C>
using c4::basic_substring< C >::rw_substr = basic_substring<NCC_>

Definition at line 229 of file substr.hpp.

◆ value_type

template<class C>
using c4::basic_substring< C >::value_type = C

Definition at line 231 of file substr.hpp.

◆ char_type

template<class C>
using c4::basic_substring< C >::char_type = C

Definition at line 232 of file substr.hpp.

◆ size_type

template<class C>
using c4::basic_substring< C >::size_type = size_t

Definition at line 233 of file substr.hpp.

◆ iterator

template<class C>
using c4::basic_substring< C >::iterator = C*

Definition at line 235 of file substr.hpp.

◆ const_iterator

template<class C>
using c4::basic_substring< C >::const_iterator = CC*

Definition at line 236 of file substr.hpp.

◆ split_proxy

template<class C>
using c4::basic_substring< C >::split_proxy = split_proxy_impl

Definition at line 1909 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

template<class C>
anonymous enum : size_t
Enumerator
npos 
NONE 

Definition at line 238 of file substr.hpp.

238: size_t { npos = (size_t)-1, NONE = (size_t)-1 };
a non-owning string-view, consisting of a character pointer and a length.
Definition substr.hpp:212

Constructor & Destructor Documentation

◆ basic_substring() [1/8]

template<class C>
c4::basic_substring< C >::basic_substring ( )
inlineconstexprnoexcept

Definition at line 255 of file substr.hpp.

255: str(), len() {}
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

Referenced by c4::basic_substring< C >::split_proxy_impl::split_iterator_impl::operator*(), and c4::basic_substring< C >::split_proxy_impl::split_iterator_impl::operator->().

◆ basic_substring() [2/8]

template<class C>
c4::basic_substring< C >::basic_substring ( basic_substring< C > const & )
inlinedefaultnoexcept

◆ basic_substring() [3/8]

template<class C>
c4::basic_substring< C >::basic_substring ( basic_substring< C > && )
inlinedefaultnoexcept

◆ basic_substring() [4/8]

template<class C>
c4::basic_substring< C >::basic_substring ( std::nullptr_t )
inlinenoexcept

Definition at line 259 of file substr.hpp.

259: str(nullptr), len(0) {}

◆ basic_substring() [5/8]

template<class C>
template<size_t N>
c4::basic_substring< C >::basic_substring ( C(&) s_[N])
inlineconstexprnoexcept

Construct from an array.

Warning
the input string need not be zero terminated, but the length is taken as if the string was zero terminated

Definition at line 278 of file substr.hpp.

278: str(s_), len(N-1) {}

◆ basic_substring() [6/8]

template<class C>
c4::basic_substring< C >::basic_substring ( C * s_,
size_t len_ )
inlinenoexcept

Construct from a pointer and length.

Warning
the input string need not be zero terminated.

Definition at line 281 of file substr.hpp.

281: str(s_), len(len_) { C4_ASSERT(str || !len_); }

◆ basic_substring() [7/8]

template<class C>
c4::basic_substring< C >::basic_substring ( C * beg_,
C * end_ )
inlinenoexcept

Construct from two pointers.

Warning
the end pointer MUST BE larger than or equal to the begin pointer
the input string need not be zero terminated

Definition at line 285 of file substr.hpp.

285: str(beg_), len(static_cast<size_t>(end_ - beg_)) { C4_ASSERT(end_ >= beg_); }

◆ basic_substring() [8/8]

template<class C>
template<class CharPtr, typename std::enable_if< can_borrow_char_ptr< CharPtr, C >::value, int >::type = 0>
c4::basic_substring< C >::basic_substring ( CharPtr s_)
inlinenoexcept

Construct from a C-string (zero-terminated string).

Warning
the input string MUST BE zero terminated.
will call strlen()
Note
this overload uses SFINAE to prevent it from overriding the array ctor
See also
For a more detailed explanation on why the plain overloads cannot coexist, see http://cplusplus.bordoon.com/specializeForCharacterArrays.html

Definition at line 293 of file substr.hpp.

293: str(s_), len(s_ ? strlen(s_) : 0) {}

Member Function Documentation

◆ operator typename std::enable_if<!std::is_const< U >::value, ro_substr const & >::type()

template<class C>
template<class U = C>
c4::basic_substring< C >::operator typename std::enable_if<!std::is_const< U >::value, ro_substr const & >::type ( ) const
inlinenoexcept

convert automatically from substr (of C) to csubstr (of const C)

Definition at line 242 of file substr.hpp.

244 {
245 return *(ro_substr const*)this; // don't call the str+len ctor because it does a check
246 }
basic_substring< CC > ro_substr
Definition substr.hpp:228

◆ operator=() [1/5]

template<class C>
basic_substring & c4::basic_substring< C >::operator= ( basic_substring< C > const & )
inlinedefaultnoexcept

◆ operator=() [2/5]

template<class C>
basic_substring & c4::basic_substring< C >::operator= ( basic_substring< C > && )
inlinedefaultnoexcept

◆ operator=() [3/5]

template<class C>
basic_substring & c4::basic_substring< C >::operator= ( std::nullptr_t )
inlinenoexcept

Definition at line 263 of file substr.hpp.

263{ str = nullptr; len = 0; return *this; }

◆ clear()

template<class C>
void c4::basic_substring< C >::clear ( )
inlinenoexcept

Definition at line 265 of file substr.hpp.

265{ str = nullptr; len = 0; }

◆ assign() [1/4]

template<class C>
template<size_t N>
void c4::basic_substring< C >::assign ( C(&) s_[N])
inlinenoexcept

Assign from an array.

Warning
the input string need not be zero terminated, but the length is taken as if the string was zero terminated

Definition at line 300 of file substr.hpp.

300{ str = s_; len = (N-1); }

Referenced by c4::yml::NodeRef::operator=().

◆ assign() [2/4]

template<class C>
void c4::basic_substring< C >::assign ( C * s_,
size_t len_ )
inlinenoexcept

Assign from a pointer and length.

Warning
the input string need not be zero terminated.

Definition at line 303 of file substr.hpp.

303{ str = s_; len = len_; C4_ASSERT(str || !len_); }

◆ assign() [3/4]

template<class C>
void c4::basic_substring< C >::assign ( C * beg_,
C * end_ )
inlinenoexcept

Assign from two pointers.

Warning
the end pointer MUST BE larger than or equal to the begin pointer
the input string need not be zero terminated.

Definition at line 307 of file substr.hpp.

307{ C4_ASSERT(end_ >= beg_); str = beg_; len = static_cast<size_t>(end_ - beg_); }

◆ assign() [4/4]

template<class C>
template<class CharPtr, typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type = 0>
void c4::basic_substring< C >::assign ( CharPtr s_)
inlinenoexcept

Assign from a C-string (zero-terminated string of type const C* or C*).

Warning
the input string must be zero terminated.
will call strlen()
Note
this overload uses SFINAE to prevent it from overriding the array assignment
See also
For a more detailed explanation on why the plain pointer overloads cannot coexist with the array overloads, see http://cplusplus.bordoon.com/specializeForCharacterArrays.html

Definition at line 315 of file substr.hpp.

316 {
317 // the SFINAE is catching const types, so that on calls like
318 // s.assign(const char*) we can do a static_assert, and so
319 // the user will see an informative error message
320 static_assert(can_borrow_char_ptr<CharPtr, C>::value, "string pointer is not mutable");
321 str = s_;
322 len = (s_ ? strlen(s_) : 0);
323 }

◆ operator=() [4/5]

template<class C>
template<size_t N>
basic_substring & c4::basic_substring< C >::operator= ( C(&) s_[N])
inlinenoexcept

Assign from an array.

Warning
the input string need not be zero terminated.

Definition at line 329 of file substr.hpp.

329{ str = s_; len = (N-1); return *this; }

◆ operator=() [5/5]

template<class C>
template<class CharPtr, typename std::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type = 0>
basic_substring & c4::basic_substring< C >::operator= ( CharPtr s_)
inlinenoexcept

Assign from a C-string (zero-terminated string of type const C* or C*).

Warning
the input string MUST BE zero terminated.
will call strlen()
Note
this overload uses SFINAE to prevent it from overriding the array assignment
See also
For a more detailed explanation on why the plain pointer overloads cannot coexist with the array overloads, see http://cplusplus.bordoon.com/specializeForCharacterArrays.html

Definition at line 337 of file substr.hpp.

338 {
339 // the SFINAE is catching const types, so that on calls like
340 // substr(const char*) we can do a static_assert, and so
341 // the user will see an informative error message
342 static_assert(can_borrow_char_ptr<CharPtr, C>::value, "string pointer is not mutable");
343 str = s_;
344 len = s_ ? strlen(s_) : 0;
345 return *this;
346 }

◆ has_str()

template<class C>
bool c4::basic_substring< C >::has_str ( ) const
inlinenoexcept

Definition at line 355 of file substr.hpp.

355{ return ! empty() && str[0] != C(0); }
bool empty() const noexcept
Definition substr.hpp:356

◆ empty()

◆ not_empty()

template<class C>
bool c4::basic_substring< C >::not_empty ( ) const
inlinenoexcept

Definition at line 357 of file substr.hpp.

357{ return (len != 0 && str != nullptr); }

◆ size()

◆ begin() [1/2]

template<class C>
iterator c4::basic_substring< C >::begin ( )
inlinenoexcept

◆ end() [1/2]

◆ begin() [2/2]

template<class C>
const_iterator c4::basic_substring< C >::begin ( ) const
inlinenoexcept

Definition at line 363 of file substr.hpp.

363{ return str; }

◆ end() [2/2]

template<class C>
const_iterator c4::basic_substring< C >::end ( ) const
inlinenoexcept

Definition at line 364 of file substr.hpp.

364{ return str + len; }

◆ data() [1/2]

template<class C>
C * c4::basic_substring< C >::data ( )
inlinenoexcept

◆ data() [2/2]

template<class C>
C const * c4::basic_substring< C >::data ( ) const
inlinenoexcept

Definition at line 367 of file substr.hpp.

367{ return str; }

◆ operator[]() [1/2]

template<class C>
C & c4::basic_substring< C >::operator[] ( size_t i)
inlinenoexcept

Definition at line 369 of file substr.hpp.

369{ C4_ASSERT(i >= 0 && i < len); return str[i]; }

◆ operator[]() [2/2]

template<class C>
C const & c4::basic_substring< C >::operator[] ( size_t i) const
inlinenoexcept

Definition at line 370 of file substr.hpp.

370{ C4_ASSERT(i >= 0 && i < len); return str[i]; }

◆ front() [1/2]

template<class C>
C & c4::basic_substring< C >::front ( )
inlinenoexcept

Definition at line 372 of file substr.hpp.

372{ C4_ASSERT(len > 0 && str != nullptr); return *str; }

◆ front() [2/2]

template<class C>
C const & c4::basic_substring< C >::front ( ) const
inlinenoexcept

Definition at line 373 of file substr.hpp.

373{ C4_ASSERT(len > 0 && str != nullptr); return *str; }

◆ back() [1/2]

template<class C>
C & c4::basic_substring< C >::back ( )
inlinenoexcept

Definition at line 375 of file substr.hpp.

375{ C4_ASSERT(len > 0 && str != nullptr); return *(str + len - 1); }

Referenced by sample_substr().

◆ back() [2/2]

template<class C>
C const & c4::basic_substring< C >::back ( ) const
inlinenoexcept

Definition at line 376 of file substr.hpp.

376{ C4_ASSERT(len > 0 && str != nullptr); return *(str + len - 1); }

◆ compare() [1/4]

◆ compare() [2/4]

template<class C>
int c4::basic_substring< C >::compare ( C const * that,
size_t sz ) const
inlinenoexcept

Definition at line 394 of file substr.hpp.

395 {
397 #if defined(__GNUC__) && (__GNUC__ >= 6)
398 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
399 #endif
400 C4_XASSERT(that || sz == 0);
401 C4_XASSERT(str || len == 0);
402 if C4_LIKELY(str && that)
403 {
404 {
405 const size_t min = len < sz ? len : sz;
406 for(size_t i = 0; i < min; ++i)
407 if(str[i] != that[i])
408 return str[i] < that[i] ? -1 : 1;
409 }
410 if(len < sz)
411 return -1;
412 else if(len == sz)
413 return 0;
414 else
415 return 1;
416 }
417 else if(len == sz)
418 {
419 C4_XASSERT(len == 0 && sz == 0);
420 return 0;
421 }
422 return len < sz ? -1 : 1;
424 }

◆ compare() [3/4]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::compare ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 427 of file substr.hpp.

429 {
430 return compare(c_str, strlen(c_str));
431 }
int compare(C const c) const noexcept
Definition substr.hpp:385

◆ compare() [4/4]

template<class C>
template<class U>
int c4::basic_substring< C >::compare ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 434 of file substr.hpp.

435 {
436 return this->compare(that.str, that.len);
437 }

◆ operator==() [1/5]

template<class C>
bool c4::basic_substring< C >::operator== ( std::nullptr_t ) const
inlinenoexcept

Definition at line 439 of file substr.hpp.

439{ return str == nullptr; }

◆ operator!=() [1/5]

template<class C>
bool c4::basic_substring< C >::operator!= ( std::nullptr_t ) const
inlinenoexcept

Definition at line 440 of file substr.hpp.

440{ return str != nullptr; }

◆ operator==() [2/5]

template<class C>
bool c4::basic_substring< C >::operator== ( C const c) const
inlinenoexcept

Definition at line 442 of file substr.hpp.

442{ return this->compare(c) == 0; }

◆ operator!=() [2/5]

template<class C>
bool c4::basic_substring< C >::operator!= ( C const c) const
inlinenoexcept

Definition at line 443 of file substr.hpp.

443{ return this->compare(c) != 0; }

◆ operator<() [1/4]

template<class C>
bool c4::basic_substring< C >::operator< ( C const c) const
inlinenoexcept

Definition at line 444 of file substr.hpp.

444{ return this->compare(c) < 0; }

◆ operator>() [1/4]

template<class C>
bool c4::basic_substring< C >::operator> ( C const c) const
inlinenoexcept

Definition at line 445 of file substr.hpp.

445{ return this->compare(c) > 0; }

◆ operator<=() [1/4]

template<class C>
bool c4::basic_substring< C >::operator<= ( C const c) const
inlinenoexcept

Definition at line 446 of file substr.hpp.

446{ return this->compare(c) <= 0; }

◆ operator>=() [1/4]

template<class C>
bool c4::basic_substring< C >::operator>= ( C const c) const
inlinenoexcept

Definition at line 447 of file substr.hpp.

447{ return this->compare(c) >= 0; }

◆ operator==() [3/5]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator== ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 449 of file substr.hpp.

449{ return this->compare(that) == 0; }

◆ operator!=() [3/5]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator!= ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 450 of file substr.hpp.

450{ return this->compare(that) != 0; }

◆ operator<() [2/4]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator< ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 451 of file substr.hpp.

451{ return this->compare(that) < 0; }

◆ operator>() [2/4]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator> ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 452 of file substr.hpp.

452{ return this->compare(that) > 0; }

◆ operator<=() [2/4]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator<= ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 453 of file substr.hpp.

453{ return this->compare(that) <= 0; }

◆ operator>=() [2/4]

template<class C>
template<class U>
bool c4::basic_substring< C >::operator>= ( basic_substring< U > const that) const
inlinenoexcept

Definition at line 454 of file substr.hpp.

454{ return this->compare(that) >= 0; }

◆ operator==() [4/5]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator== ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 456 of file substr.hpp.

456{ return this->compare(arr, N-1) == 0; }

◆ operator!=() [4/5]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator!= ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 457 of file substr.hpp.

457{ return this->compare(arr, N-1) != 0; }

◆ operator<() [3/4]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator< ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 458 of file substr.hpp.

458{ return this->compare(arr, N-1) < 0; }

◆ operator>() [3/4]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator> ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 459 of file substr.hpp.

459{ return this->compare(arr, N-1) > 0; }

◆ operator<=() [3/4]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator<= ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 460 of file substr.hpp.

460{ return this->compare(arr, N-1) <= 0; }

◆ operator>=() [3/4]

template<class C>
template<size_t N>
bool c4::basic_substring< C >::operator>= ( const char(&) arr[N]) const
inlinenoexcept

Definition at line 461 of file substr.hpp.

461{ return this->compare(arr, N-1) >= 0; }

◆ operator==() [5/5]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator== ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 463 of file substr.hpp.

463{ return this->compare(c_str, strlen(c_str)) == 0; }

◆ operator!=() [5/5]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator!= ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 464 of file substr.hpp.

464{ return this->compare(c_str, strlen(c_str)) != 0; }

◆ operator<() [4/4]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator< ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 465 of file substr.hpp.

465{ return this->compare(c_str, strlen(c_str)) < 0; }

◆ operator>() [4/4]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator> ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 466 of file substr.hpp.

466{ return this->compare(c_str, strlen(c_str)) > 0; }

◆ operator<=() [4/4]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator<= ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 467 of file substr.hpp.

467{ return this->compare(c_str, strlen(c_str)) <= 0; }

◆ operator>=() [4/4]

template<class C>
template<class CharPtr>
auto c4::basic_substring< C >::operator>= ( CharPtr c_str) const->typenamestd::enable_if< is_compatible_char_ptr< CharPtr, C >::value, int >::type
inlinenoexcept

Definition at line 468 of file substr.hpp.

468{ return this->compare(c_str, strlen(c_str)) >= 0; }

◆ is_sub()

template<class C>
bool c4::basic_substring< C >::is_sub ( ro_substr const that) const
inlinenoexcept

true if *this is a substring of that (ie, from the same buffer)

Definition at line 478 of file substr.hpp.

479 {
480 return that.is_super(*this);
481 }
bool is_super(ro_substr const that) const noexcept
true if that is a substring of *this (ie, from the same buffer)
Definition substr.hpp:484

Referenced by sample_formatting(), sample_substr(), and sample_tree_arena().

◆ is_super()

template<class C>
bool c4::basic_substring< C >::is_super ( ro_substr const that) const
inlinenoexcept

true if that is a substring of *this (ie, from the same buffer)

Definition at line 484 of file substr.hpp.

485 {
486 if C4_LIKELY(len > 0)
487 return that.str >= str && that.str+that.len <= str+len;
488 else
489 return that.len == 0 && that.str == str && str != nullptr;
490 }

Referenced by sample_substr(), and sample_tree_arena().

◆ overlaps()

template<class C>
bool c4::basic_substring< C >::overlaps ( ro_substr const that) const
inlinenoexcept

true if there is overlap of at least one element between that and *this

Definition at line 493 of file substr.hpp.

494 {
495 // thanks @timwynants
496 return that.str+that.len > str && that.str < str+len;
497 }

Referenced by c4::yml::Tree::copy_to_arena(), c4::yml::dump(), c4::yml::escape_scalar(), c4::from_chars_first(), c4::yml::normalize_tag_long(), c4::basic_substring< CC >::replace_all(), c4::yml::TagDirectives::resolve(), sample_formatting(), sample_substr(), and sample_tree_arena().

◆ sub() [1/2]

◆ sub() [2/2]

template<class C>
basic_substring c4::basic_substring< C >::sub ( size_t first,
size_t num ) const
inlinenoexcept

return [first,first+num[.

If num==npos, return [first,len[

Definition at line 509 of file substr.hpp.

510 {
511 C4_ASSERT(first >= 0 && first <= len);
512 C4_ASSERT((num >= 0 && num <= len) || (num == npos));
513 size_t rnum = num != npos ? num : len - first;
514 C4_ASSERT((first >= 0 && first + rnum <= len) || (num == 0));
515 return basic_substring(str + first, rnum);
516 }

◆ range()

template<class C>
basic_substring c4::basic_substring< C >::range ( size_t first,
size_t last = npos ) const
inlinenoexcept

return [first,last[.

If last==npos, return [first,len[

Definition at line 519 of file substr.hpp.

520 {
521 C4_ASSERT(first >= 0 && first <= len);
522 last = last != npos ? last : len;
523 C4_ASSERT(first <= last);
524 C4_ASSERT(last >= 0 && last <= len);
525 return basic_substring(str + first, last - first);
526 }
basic_substring last(size_t num) const noexcept
return the last num elements: [len-num,len[
Definition substr.hpp:536

Referenced by c4::yml::detail::_get_text_region(), c4::catrs_append(), c4::catseprs_append(), c4::yml::escape_scalar_fn(), c4::formatrs_append(), sample_substr(), and c4::yml::transform_tag().

◆ first()

◆ last()

template<class C>
basic_substring c4::basic_substring< C >::last ( size_t num) const
inlinenoexcept

return the last num elements: [len-num,len[

Definition at line 536 of file substr.hpp.

537 {
538 C4_ASSERT(num <= len || num == npos);
539 return num != npos ?
541 *this;
542 }

Referenced by c4::yml::detail::_get_text_region(), c4::yml::extra::EventHandlerInts::arena_rem(), c4::yml::extra::events_ints_to_testsuite(), and sample_substr().

◆ offs()

template<class C>
basic_substring c4::basic_substring< C >::offs ( size_t left,
size_t right ) const
inlinenoexcept

offset from the ends: return [left,len-right[ ; ie, trim a number of characters from the left and right.

This is equivalent to python's negative list indices.

Definition at line 547 of file substr.hpp.

548 {
549 C4_ASSERT(left >= 0 && left <= len);
550 C4_ASSERT(right >= 0 && right <= len);
551 C4_ASSERT(left <= len - right + 1);
552 return basic_substring(str + left, len - right - left);
553 }

Referenced by c4::yml::is_valid_tag_handle(), c4::yml::TagDirectives::resolve(), sample_substr(), and c4::yml::to_tag().

◆ left_of() [1/3]

template<class C>
basic_substring c4::basic_substring< C >::left_of ( size_t pos) const
inlinenoexcept

return [0, pos[ .

Same as .first(pos), but provided for compatibility with .right_of()

Definition at line 556 of file substr.hpp.

557 {
558 C4_ASSERT(pos <= len || pos == npos);
559 return (pos != npos) ?
561 *this;
562 }

Referenced by sample_substr().

◆ left_of() [2/3]

template<class C>
basic_substring c4::basic_substring< C >::left_of ( size_t pos,
bool include_pos ) const
inlinenoexcept

return [0, pos+include_pos[ .

Same as .first(pos+1), but provided for compatibility with .right_of()

Definition at line 565 of file substr.hpp.

566 {
567 C4_ASSERT(pos <= len || pos == npos);
568 return (pos != npos) ?
570 *this;
571 }

◆ right_of() [1/3]

template<class C>
basic_substring c4::basic_substring< C >::right_of ( size_t pos) const
inlinenoexcept

return [pos+1, len[

Definition at line 574 of file substr.hpp.

575 {
576 C4_ASSERT(pos <= len || pos == npos);
577 return (pos != npos) ?
578 basic_substring(str + (pos + 1), len - (pos + 1)) :
580 }

Referenced by sample_substr().

◆ right_of() [2/3]

template<class C>
basic_substring c4::basic_substring< C >::right_of ( size_t pos,
bool include_pos ) const
inlinenoexcept

return [pos+!include_pos, len[

Definition at line 583 of file substr.hpp.

584 {
585 C4_ASSERT(pos <= len || pos == npos);
586 return (pos != npos) ?
589 }

◆ left_of() [3/3]

template<class C>
basic_substring c4::basic_substring< C >::left_of ( ro_substr const subs) const
inlinenoexcept

given subs a substring of the current string, get the portion of the current string to the left of it

Definition at line 595 of file substr.hpp.

596 {
598 auto ssb = subs.begin();
599 auto b = begin();
600 auto e = end();
601 if(ssb >= b && ssb <= e)
602 return sub(0, static_cast<size_t>(ssb - b));
603 else
604 return sub(0, 0);
605 }
iterator begin() noexcept
Definition substr.hpp:360
iterator end() noexcept
Definition substr.hpp:361
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:502

◆ right_of() [3/3]

template<class C>
basic_substring c4::basic_substring< C >::right_of ( ro_substr const subs) const
inlinenoexcept

given subs a substring of the current string, get the portion of the current string to the right of it

Definition at line 609 of file substr.hpp.

610 {
612 auto sse = subs.end();
613 auto b = begin();
614 auto e = end();
615 if(sse >= b && sse <= e)
616 return sub(static_cast<size_t>(sse - b), static_cast<size_t>(e - sse));
617 else
618 return sub(0, 0);
619 }

◆ triml() [1/2]

template<class C>
basic_substring c4::basic_substring< C >::triml ( const C c) const
inline

trim left

Definition at line 629 of file substr.hpp.

630 {
631 if( ! empty())
632 {
633 size_t pos = first_not_of(c);
634 if(pos != npos)
635 return sub(pos);
636 }
637 return sub(0, 0);
638 }
size_t first_not_of(const C c) const
Definition substr.hpp:993

Referenced by sample_substr(), c4::yml::Tree::set_key_anchor(), and c4::yml::Tree::set_val_anchor().

◆ triml() [2/2]

template<class C>
basic_substring c4::basic_substring< C >::triml ( ro_substr chars) const
inline

trim left ANY of the characters.

See also
stripl() to remove a pattern from the left

Definition at line 641 of file substr.hpp.

642 {
643 if( ! empty())
644 {
645 size_t pos = first_not_of(chars);
646 if(pos != npos)
647 return sub(pos);
648 }
649 return sub(0, 0);
650 }

◆ trimr() [1/2]

template<class C>
basic_substring c4::basic_substring< C >::trimr ( const C c) const
inline

trim the character c from the right

Definition at line 653 of file substr.hpp.

654 {
655 if( ! empty())
656 {
657 size_t pos = last_not_of(c, npos);
658 if(pos != npos)
659 return sub(0, pos+1);
660 }
661 return sub(0, 0);
662 }
size_t last_not_of(const C c) const
Definition substr.hpp:1014

Referenced by sample_substr().

◆ trimr() [2/2]

template<class C>
basic_substring c4::basic_substring< C >::trimr ( ro_substr chars) const
inline

trim right ANY of the characters

See also
stripr() to remove a pattern from the right

Definition at line 665 of file substr.hpp.

666 {
667 if( ! empty())
668 {
669 size_t pos = last_not_of(chars, npos);
670 if(pos != npos)
671 return sub(0, pos+1);
672 }
673 return sub(0, 0);
674 }

◆ trim() [1/2]

template<class C>
basic_substring c4::basic_substring< C >::trim ( const C c) const
inline

trim the character c left and right

Definition at line 677 of file substr.hpp.

678 {
679 return triml(c).trimr(c);
680 }
basic_substring triml(const C c) const
trim left
Definition substr.hpp:629
basic_substring trimr(const C c) const
trim the character c from the right
Definition substr.hpp:653

Referenced by sample_substr().

◆ trim() [2/2]

template<class C>
basic_substring c4::basic_substring< C >::trim ( ro_substr const chars) const
inline

trim left and right ANY of the characters

See also
strip() to remove a pattern from the left and right

Definition at line 683 of file substr.hpp.

684 {
685 return triml(chars).trimr(chars);
686 }

◆ stripl()

template<class C>
basic_substring c4::basic_substring< C >::stripl ( ro_substr pattern) const
inline

remove a pattern from the left

See also
triml() to remove characters

Definition at line 690 of file substr.hpp.

691 {
692 if( ! begins_with(pattern))
693 return *this;
694 return sub(pattern.len < len ? pattern.len : len);
695 }
bool begins_with(const C c) const noexcept
true if the first character of the string is c
Definition substr.hpp:850

Referenced by sample_substr().

◆ stripr()

template<class C>
basic_substring c4::basic_substring< C >::stripr ( ro_substr pattern) const
inline

remove a pattern from the right

See also
trimr() to remove characters

Definition at line 699 of file substr.hpp.

700 {
701 if( ! ends_with(pattern))
702 return *this;
703 return left_of(len - (pattern.len < len ? pattern.len : len));
704 }
bool ends_with(const C c) const noexcept
true if the last character of the string is c
Definition substr.hpp:894
basic_substring left_of(size_t pos) const noexcept
return [0, pos[ .
Definition substr.hpp:556

Referenced by sample_substr().

◆ find() [1/2]

template<class C>
size_t c4::basic_substring< C >::find ( const C c,
size_t start_pos = 0 ) const
inline

Definition at line 713 of file substr.hpp.

714 {
715 return first_of(c, start_pos);
716 }
size_t first_of(const C c, size_t start=0) const
Definition substr.hpp:934

Referenced by c4::yml::is_custom_tag(), c4::basic_substring< CC >::pair_range(), sample_substr(), and c4::uncatsep().

◆ find() [2/2]

template<class C>
size_t c4::basic_substring< C >::find ( ro_substr pattern,
size_t start_pos = 0 ) const
inline

Definition at line 717 of file substr.hpp.

718 {
719 C4_ASSERT(start_pos == npos || (start_pos >= 0 && start_pos <= len));
720 if(len < pattern.len) return npos;
721 for(size_t i = start_pos, e = len - pattern.len + 1; i < e; ++i)
722 {
723 bool gotit = true;
724 for(size_t j = 0; j < pattern.len; ++j)
725 {
726 C4_ASSERT(i + j < len);
727 if(str[i + j] != pattern.str[j])
728 {
729 gotit = false;
730 break;
731 }
732 }
733 if(gotit)
734 {
735 return i;
736 }
737 }
738 return npos;
739 }

◆ count() [1/2]

template<class C>
size_t c4::basic_substring< C >::count ( const C c,
size_t pos = 0 ) const
inline

count the number of occurrences of c

Definition at line 744 of file substr.hpp.

745 {
746 C4_ASSERT(pos >= 0 && pos <= len);
747 size_t num = 0;
748 pos = find(c, pos);
749 while(pos != npos)
750 {
751 ++num;
752 pos = find(c, pos + 1);
753 }
754 return num;
755 }
size_t find(const C c, size_t start_pos=0) const
Definition substr.hpp:713

Referenced by sample_substr().

◆ count() [2/2]

template<class C>
size_t c4::basic_substring< C >::count ( ro_substr c,
size_t pos = 0 ) const
inline

count the number of occurrences of s

Definition at line 758 of file substr.hpp.

759 {
760 C4_ASSERT(pos >= 0 && pos <= len);
761 size_t num = 0;
762 pos = find(c, pos);
763 while(pos != npos)
764 {
765 ++num;
766 pos = find(c, pos + c.len);
767 }
768 return num;
769 }

◆ select() [1/2]

template<class C>
basic_substring c4::basic_substring< C >::select ( const C c,
size_t pos = 0 ) const
inline

get the substr consisting of the first occurrence of c after pos, or an empty substr if none occurs

Definition at line 772 of file substr.hpp.

773 {
774 pos = find(c, pos);
775 return pos != npos ? sub(pos, 1) : basic_substring();
776 }

Referenced by sample_substr().

◆ select() [2/2]

template<class C>
basic_substring c4::basic_substring< C >::select ( ro_substr pattern,
size_t pos = 0 ) const
inline

get the substr consisting of the first occurrence of pattern after pos, or an empty substr if none occurs

Definition at line 779 of file substr.hpp.

780 {
781 pos = find(pattern, pos);
782 return pos != npos ? sub(pos, pattern.len) : basic_substring();
783 }

◆ first_of_any() [1/4]

template<class C>
first_of_any_result c4::basic_substring< C >::first_of_any ( ro_substr s0,
ro_substr s1 ) const
inline

Definition at line 794 of file substr.hpp.

795 {
796 ro_substr s[2] = {s0, s1};
797 return first_of_any_iter(&s[0], &s[0] + 2);
798 }
first_of_any_result first_of_any_iter(It first_span, It last_span) const
Definition substr.hpp:819

◆ first_of_any() [2/4]

template<class C>
first_of_any_result c4::basic_substring< C >::first_of_any ( ro_substr s0,
ro_substr s1,
ro_substr s2 ) const
inline

Definition at line 800 of file substr.hpp.

801 {
802 ro_substr s[3] = {s0, s1, s2};
803 return first_of_any_iter(&s[0], &s[0] + 3);
804 }

◆ first_of_any() [3/4]

template<class C>
first_of_any_result c4::basic_substring< C >::first_of_any ( ro_substr s0,
ro_substr s1,
ro_substr s2,
ro_substr s3 ) const
inline

Definition at line 806 of file substr.hpp.

807 {
808 ro_substr s[4] = {s0, s1, s2, s3};
809 return first_of_any_iter(&s[0], &s[0] + 4);
810 }

◆ first_of_any() [4/4]

template<class C>
first_of_any_result c4::basic_substring< C >::first_of_any ( ro_substr s0,
ro_substr s1,
ro_substr s2,
ro_substr s3,
ro_substr s4 ) const
inline

Definition at line 812 of file substr.hpp.

813 {
814 ro_substr s[5] = {s0, s1, s2, s3, s4};
815 return first_of_any_iter(&s[0], &s[0] + 5);
816 }

◆ first_of_any_iter()

template<class C>
template<class It>
first_of_any_result c4::basic_substring< C >::first_of_any_iter ( It first_span,
It last_span ) const
inline

Definition at line 819 of file substr.hpp.

820 {
821 for(size_t i = 0; i < len; ++i)
822 {
823 size_t curr = 0;
824 for(It it = first_span; it != last_span; ++curr, ++it)
825 {
826 auto const& chars = *it;
827 if((i + chars.len) > len) continue;
828 bool gotit = true;
829 for(size_t j = 0; j < chars.len; ++j)
830 {
831 C4_ASSERT(i + j < len);
832 if(str[i + j] != chars[j])
833 {
834 gotit = false;
835 break;
836 }
837 }
838 if(gotit)
839 {
840 return {curr, i};
841 }
842 }
843 }
844 return {NONE, npos};
845 }

◆ begins_with() [1/3]

◆ begins_with() [2/3]

template<class C>
bool c4::basic_substring< C >::begins_with ( const C c,
size_t num ) const
inlinenoexcept

true if the first num characters of the string are c

Definition at line 861 of file substr.hpp.

862 {
863 if(len < num)
864 return false;
865 for(size_t i = 0; i < num; ++i)
866 if(str[i] != c)
867 return false;
868 return num > 0;
869 }

◆ begins_with() [3/3]

template<class C>
bool c4::basic_substring< C >::begins_with ( ro_substr pattern) const
inlinenoexcept

true if the string begins with the given pattern

Definition at line 872 of file substr.hpp.

873 {
874 if(len < pattern.len)
875 return false;
876 for(size_t i = 0; i < pattern.len; ++i)
877 if(str[i] != pattern.str[i])
878 return false;
879 return pattern.len > 0;
880 }

◆ begins_with_any()

template<class C>
bool c4::basic_substring< C >::begins_with_any ( ro_substr chars) const
inlinenoexcept

true if the first character of the string is any of the given chars

Definition at line 883 of file substr.hpp.

884 {
885 if(len)
886 for(size_t i = 0; i < chars.len; ++i)
887 if(str[0] == chars.str[i])
888 return true;
889 return false;
890 }

Referenced by sample_substr().

◆ ends_with() [1/3]

template<class C>
bool c4::basic_substring< C >::ends_with ( const C c) const
inlinenoexcept

true if the last character of the string is c

Definition at line 894 of file substr.hpp.

895 {
896 return len && str[len-1] == c;
897 }

Referenced by c4::yml::is_valid_tag_handle(), c4::yml::TagDirectives::resolve(), c4::yml::Tree::lookup_result::resolved(), and sample_substr().

◆ ends_with() [2/3]

template<class C>
bool c4::basic_substring< C >::ends_with ( const C c,
const size_t num ) const
inlinenoexcept

true if the last num characters of the string are c

Definition at line 900 of file substr.hpp.

901 {
902 if(len < num)
903 return false;
904 for(size_t i = len - num; i < len; ++i)
905 if(str[i] != c)
906 return false;
907 return num > 0;
908 }

◆ ends_with() [3/3]

template<class C>
bool c4::basic_substring< C >::ends_with ( ro_substr pattern) const
inlinenoexcept

true if the string ends with the given pattern

Definition at line 911 of file substr.hpp.

912 {
913 if(len < pattern.len)
914 return false;
915 for(size_t i = 0, s = len-pattern.len; i < pattern.len; ++i)
916 if(str[s+i] != pattern[i])
917 return false;
918 return pattern.len > 0;
919 }

◆ ends_with_any()

template<class C>
bool c4::basic_substring< C >::ends_with_any ( ro_substr chars) const
inlinenoexcept

true if the last character of the string is any of the given chars

Definition at line 922 of file substr.hpp.

923 {
924 if(len)
925 for(size_t i = 0; i < chars.len; ++i)
926 if(str[len - 1] == chars[i])
927 return true;
928 return false;
929 }

Referenced by sample_substr().

◆ first_of() [1/2]

template<class C>
size_t c4::basic_substring< C >::first_of ( const C c,
size_t start = 0 ) const
inline
Returns
the first position where c is found in the string, or npos if none is found

Definition at line 934 of file substr.hpp.

935 {
936 C4_ASSERT(start == npos || (start >= 0 && start <= len));
937 for(size_t i = start; i < len; ++i)
938 {
939 if(str[i] == c)
940 return i;
941 }
942 return npos;
943 }

Referenced by c4::yml::detail::_get_text_region(), and sample_substr().

◆ last_of() [1/2]

template<class C>
size_t c4::basic_substring< C >::last_of ( const C c,
size_t start = npos ) const
inline
Returns
the last position where c is found in the string, or npos if none is found

Definition at line 946 of file substr.hpp.

947 {
948 C4_ASSERT(start == npos || (start >= 0 && start <= len));
949 if(start == npos)
950 start = len;
951 for(size_t i = start-1; i != size_t(-1); --i)
952 {
953 if(str[i] == c)
954 return i;
955 }
956 return npos;
957 }

Referenced by c4::yml::detail::_get_text_region(), and sample_substr().

◆ first_of() [2/2]

template<class C>
size_t c4::basic_substring< C >::first_of ( ro_substr chars,
size_t start = 0 ) const
inline
Returns
the first position where ANY of the chars is found in the string, or npos if none is found

Definition at line 960 of file substr.hpp.

961 {
962 C4_ASSERT(start == npos || (start >= 0 && start <= len));
963 for(size_t i = start; i < len; ++i)
964 {
965 for(size_t j = 0; j < chars.len; ++j)
966 {
967 if(str[i] == chars.str[j])
968 return i;
969 }
970 }
971 return npos;
972 }

◆ last_of() [2/2]

template<class C>
size_t c4::basic_substring< C >::last_of ( ro_substr chars,
size_t start = npos ) const
inline
Returns
the last position where ANY of the chars is found in the string, or npos if none is found

Definition at line 975 of file substr.hpp.

976 {
977 C4_ASSERT(start == npos || (start >= 0 && start <= len));
978 if(start == npos)
979 start = len;
980 for(size_t i = start-1; i != size_t(-1); --i)
981 {
982 for(size_t j = 0; j < chars.len; ++j)
983 {
984 if(str[i] == chars[j])
985 return i;
986 }
987 }
988 return npos;
989 }

◆ first_not_of() [1/4]

template<class C>
size_t c4::basic_substring< C >::first_not_of ( const C c) const
inline

Definition at line 993 of file substr.hpp.

994 {
995 for(size_t i = 0; i < len; ++i)
996 {
997 if(str[i] != c)
998 return i;
999 }
1000 return npos;
1001 }

Referenced by sample_substr().

◆ first_not_of() [2/4]

template<class C>
size_t c4::basic_substring< C >::first_not_of ( const C c,
size_t start ) const
inline

Definition at line 1003 of file substr.hpp.

1004 {
1005 C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
1006 for(size_t i = start; i < len; ++i)
1007 {
1008 if(str[i] != c)
1009 return i;
1010 }
1011 return npos;
1012 }

◆ last_not_of() [1/4]

template<class C>
size_t c4::basic_substring< C >::last_not_of ( const C c) const
inline

Definition at line 1014 of file substr.hpp.

1015 {
1016 for(size_t i = len-1; i != size_t(-1); --i)
1017 {
1018 if(str[i] != c)
1019 return i;
1020 }
1021 return npos;
1022 }

Referenced by sample_substr().

◆ last_not_of() [2/4]

template<class C>
size_t c4::basic_substring< C >::last_not_of ( const C c,
size_t start ) const
inline

Definition at line 1024 of file substr.hpp.

1025 {
1026 C4_ASSERT(start == npos || (start >= 0 && start <= len));
1027 if(start == npos)
1028 start = len;
1029 for(size_t i = start-1; i != size_t(-1); --i)
1030 {
1031 if(str[i] != c)
1032 return i;
1033 }
1034 return npos;
1035 }

◆ first_not_of() [3/4]

template<class C>
size_t c4::basic_substring< C >::first_not_of ( ro_substr chars) const
inline

Definition at line 1037 of file substr.hpp.

1038 {
1039 for(size_t i = 0; i < len; ++i)
1040 {
1041 bool gotit = true;
1042 for(size_t j = 0; j < chars.len; ++j)
1043 {
1044 if(str[i] == chars.str[j])
1045 {
1046 gotit = false;
1047 break;
1048 }
1049 }
1050 if(gotit)
1051 {
1052 return i;
1053 }
1054 }
1055 return npos;
1056 }

◆ first_not_of() [4/4]

template<class C>
size_t c4::basic_substring< C >::first_not_of ( ro_substr chars,
size_t start ) const
inline

Definition at line 1058 of file substr.hpp.

1059 {
1060 C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
1061 for(size_t i = start; i < len; ++i)
1062 {
1063 bool gotit = true;
1064 for(size_t j = 0; j < chars.len; ++j)
1065 {
1066 if(str[i] == chars.str[j])
1067 {
1068 gotit = false;
1069 break;
1070 }
1071 }
1072 if(gotit)
1073 {
1074 return i;
1075 }
1076 }
1077 return npos;
1078 }

◆ last_not_of() [3/4]

template<class C>
size_t c4::basic_substring< C >::last_not_of ( ro_substr chars) const
inline

Definition at line 1080 of file substr.hpp.

1081 {
1082 for(size_t i = len-1; i != size_t(-1); --i)
1083 {
1084 bool gotit = true;
1085 for(size_t j = 0; j < chars.len; ++j)
1086 {
1087 if(str[i] == chars.str[j])
1088 {
1089 gotit = false;
1090 break;
1091 }
1092 }
1093 if(gotit)
1094 {
1095 return i;
1096 }
1097 }
1098 return npos;
1099 }

◆ last_not_of() [4/4]

template<class C>
size_t c4::basic_substring< C >::last_not_of ( ro_substr chars,
size_t start ) const
inline

Definition at line 1101 of file substr.hpp.

1102 {
1103 C4_ASSERT(start == npos || (start >= 0 && start <= len));
1104 if(start == npos)
1105 start = len;
1106 for(size_t i = start-1; i != size_t(-1); --i)
1107 {
1108 bool gotit = true;
1109 for(size_t j = 0; j < chars.len; ++j)
1110 {
1111 if(str[i] == chars.str[j])
1112 {
1113 gotit = false;
1114 break;
1115 }
1116 }
1117 if(gotit)
1118 {
1119 return i;
1120 }
1121 }
1122 return npos;
1123 }

◆ pair_range()

template<class C>
basic_substring c4::basic_substring< C >::pair_range ( CC open,
CC close ) const
inline

get the range delimited by an open-close pair of characters.

Note
There must be no nested pairs.
No checks for escapes are performed.

Definition at line 1135 of file substr.hpp.

1136 {
1137 size_t b = find(open);
1138 if(b == npos)
1139 return basic_substring();
1140 size_t e = find(close, b+1);
1141 if(e == npos)
1142 return basic_substring();
1143 basic_substring ret = range(b, e+1);
1144 C4_ASSERT(ret.sub(1).find(open) == npos);
1145 return ret;
1146 }
basic_substring range(size_t first, size_t last=npos) const noexcept
return [first,last[.
Definition substr.hpp:519

◆ pair_range_esc()

template<class C>
basic_substring c4::basic_substring< C >::pair_range_esc ( CC open_close,
CC escape = CC('\\') )
inline

get the range delimited by a single open-close character (eg, quotes).

Note
The open-close character can be escaped.

Definition at line 1150 of file substr.hpp.

1151 {
1152 size_t b = find(open_close);
1153 if(b == npos) return basic_substring();
1154 for(size_t i = b+1; i < len; ++i)
1155 {
1156 CC c = str[i];
1157 if(c == open_close)
1158 {
1159 if(str[i-1] != escape)
1160 {
1161 return range(b, i+1);
1162 }
1163 }
1164 }
1165 return basic_substring();
1166 }
typename std::add_const< C >::type CC
CC=const char.
Definition substr.hpp:225

◆ pair_range_nested()

template<class C>
basic_substring c4::basic_substring< C >::pair_range_nested ( CC open,
CC close ) const
inline

get the range delimited by an open-close pair of characters, with possibly nested occurrences.

No checks for escapes are performed.

Definition at line 1171 of file substr.hpp.

1172 {
1173 size_t b = find(open);
1174 if(b == npos) return basic_substring();
1175 size_t e, curr = b+1, count = 0;
1176 const char both[] = {open, close, '\0'};
1177 while((e = first_of(both, curr)) != npos)
1178 {
1179 if(str[e] == open)
1180 {
1181 ++count;
1182 curr = e+1;
1183 }
1184 else if(str[e] == close)
1185 {
1186 if(count == 0) return range(b, e+1);
1187 --count;
1188 curr = e+1;
1189 }
1190 }
1191 return basic_substring();
1192 }
size_t count(const C c, size_t pos=0) const
count the number of occurrences of c
Definition substr.hpp:744

◆ unquoted()

template<class C>
basic_substring c4::basic_substring< C >::unquoted ( ) const
inline

Definition at line 1194 of file substr.hpp.

1195 {
1196 constexpr const C dq('"'), sq('\'');
1197 if(len >= 2 && (str[len - 2] != C('\\')) &&
1198 ((begins_with(sq) && ends_with(sq))
1199 ||
1200 (begins_with(dq) && ends_with(dq))))
1201 {
1202 return range(1, len -1);
1203 }
1204 return *this;
1205 }

◆ is_number()

template<class C>
bool c4::basic_substring< C >::is_number ( ) const
inline
Returns
true if the substring contents are a floating-point or integer number.
Note
any leading or trailing whitespace will return false.

Definition at line 1216 of file substr.hpp.

1217 {
1218 if(empty() || (first_non_empty_span().empty()))
1219 return false;
1220 if(first_uint_span() == *this)
1221 return true;
1222 if(first_int_span() == *this)
1223 return true;
1224 if(first_real_span() == *this)
1225 return true;
1226 return false;
1227 }
basic_substring first_uint_span() const
get the first span which can be interpreted as an unsigned integer
Definition substr.hpp:1277
basic_substring first_real_span() const
get the first span which can be interpreted as a real (floating-point) number
Definition substr.hpp:1364
basic_substring first_int_span() const
get the first span which can be interpreted as a signed integer
Definition substr.hpp:1289
basic_substring first_non_empty_span() const
get the first span consisting exclusively of non-empty characters
Definition substr.hpp:1265

◆ is_real()

template<class C>
bool c4::basic_substring< C >::is_real ( ) const
inline
Returns
true if the substring contents are a real number.
Note
any leading or trailing whitespace will return false.

Definition at line 1231 of file substr.hpp.

1232 {
1233 if(empty() || (first_non_empty_span().empty()))
1234 return false;
1235 if(first_real_span() == *this)
1236 return true;
1237 return false;
1238 }

◆ is_integer()

template<class C>
bool c4::basic_substring< C >::is_integer ( ) const
inline
Returns
true if the substring contents are an integer number.
Note
any leading or trailing whitespace will return false.

Definition at line 1242 of file substr.hpp.

1243 {
1244 if(empty() || (first_non_empty_span().empty()))
1245 return false;
1246 if(first_uint_span() == *this)
1247 return true;
1248 if(first_int_span() == *this)
1249 return true;
1250 return false;
1251 }

◆ is_unsigned_integer()

template<class C>
bool c4::basic_substring< C >::is_unsigned_integer ( ) const
inline
Returns
true if the substring contents are an unsigned integer number.
Note
any leading or trailing whitespace will return false.

Definition at line 1255 of file substr.hpp.

1256 {
1257 if(empty() || (first_non_empty_span().empty()))
1258 return false;
1259 if(first_uint_span() == *this)
1260 return true;
1261 return false;
1262 }

◆ first_non_empty_span()

template<class C>
basic_substring c4::basic_substring< C >::first_non_empty_span ( ) const
inline

get the first span consisting exclusively of non-empty characters

Definition at line 1265 of file substr.hpp.

1266 {
1267 constexpr const ro_substr empty_chars(" \n\r\t");
1268 size_t pos = first_not_of(empty_chars);
1269 if(pos == npos)
1270 return first(0);
1271 auto ret = sub(pos);
1273 return ret.first(pos);
1274 }

◆ first_uint_span()

template<class C>
basic_substring c4::basic_substring< C >::first_uint_span ( ) const
inline

get the first span which can be interpreted as an unsigned integer

Definition at line 1277 of file substr.hpp.

1278 {
1280 if(ne.empty())
1281 return ne;
1282 if(ne.str[0] == '-')
1283 return first(0);
1284 size_t skip_start = size_t(ne.str[0] == '+');
1286 }
basic_substring _first_integral_span(size_t skip_start) const
Definition substr.hpp:1298

Referenced by c4::atou_first().

◆ first_int_span()

template<class C>
basic_substring c4::basic_substring< C >::first_int_span ( ) const
inline

get the first span which can be interpreted as a signed integer

Definition at line 1289 of file substr.hpp.

1290 {
1292 if(ne.empty())
1293 return ne;
1294 size_t skip_start = size_t(ne.str[0] == '+' || ne.str[0] == '-');
1296 }

Referenced by c4::atoi_first().

◆ _first_integral_span()

template<class C>
basic_substring c4::basic_substring< C >::_first_integral_span ( size_t skip_start) const
inline

Definition at line 1298 of file substr.hpp.

1299 {
1300 C4_ASSERT(!empty());
1301 if(skip_start == len)
1302 return first(0);
1304 if(len >= skip_start + 3)
1305 {
1306 if(str[skip_start] != '0')
1307 {
1308 for(size_t i = skip_start; i < len; ++i)
1309 {
1310 char c = str[i];
1311 if(c < '0' || c > '9')
1312 return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1313 }
1314 }
1315 else
1316 {
1317 char next = str[skip_start + 1];
1318 if(next == 'x' || next == 'X')
1319 {
1320 skip_start += 2;
1321 for(size_t i = skip_start; i < len; ++i)
1322 {
1323 const char c = str[i];
1324 if( ! _is_hex_char(c))
1325 return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1326 }
1327 return *this;
1328 }
1329 else if(next == 'b' || next == 'B')
1330 {
1331 skip_start += 2;
1332 for(size_t i = skip_start; i < len; ++i)
1333 {
1334 const char c = str[i];
1335 if(c != '0' && c != '1')
1336 return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1337 }
1338 return *this;
1339 }
1340 else if(next == 'o' || next == 'O')
1341 {
1342 skip_start += 2;
1343 for(size_t i = skip_start; i < len; ++i)
1344 {
1345 const char c = str[i];
1346 if(c < '0' || c > '7')
1347 return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1348 }
1349 return *this;
1350 }
1351 }
1352 }
1353 // must be a decimal, or it is not a an number
1354 for(size_t i = skip_start; i < len; ++i)
1355 {
1356 const char c = str[i];
1357 if(c < '0' || c > '9')
1358 return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1359 }
1360 return *this;
1361 }
static constexpr C4_CONST bool _is_hex_char(char c) noexcept
true if the character is in [0-9a-fA-F]
Definition substr.hpp:1427
static constexpr C4_CONST bool _is_delim_char(char c) noexcept
true if the character is a delimiter character at the end
Definition substr.hpp:1419

Referenced by c4::basic_substring< CC >::first_int_span(), and c4::basic_substring< CC >::first_uint_span().

◆ first_real_span()

template<class C>
basic_substring c4::basic_substring< C >::first_real_span ( ) const
inline

get the first span which can be interpreted as a real (floating-point) number

Definition at line 1364 of file substr.hpp.

1365 {
1367 if(ne.empty())
1368 return ne;
1369 const size_t skip_start = (ne.str[0] == '+' || ne.str[0] == '-');
1370 C4_ASSERT(skip_start == 0 || skip_start == 1);
1371 // if we have at least three digits after the leading sign, it
1372 // can be decimal, or hex, or bin or oct. Ex:
1373 // non-decimal: 0x0, 0b0, 0o0
1374 // decimal: 1.0, 10., 1e1, 100, inf, nan, infinity
1375 if(ne.len >= skip_start+3)
1376 {
1377 // if it does not have leading 0, it must be decimal, or it is not a real
1378 if(ne.str[skip_start] != '0')
1379 {
1380 if(ne.str[skip_start] == 'i') // is it infinity or inf?
1381 {
1383 if(word.len)
1384 return word;
1385 return ne._word_follows(skip_start + 1, "nf");
1386 }
1387 else if(ne.str[skip_start] == 'n') // is it nan?
1388 {
1389 return ne._word_follows(skip_start + 1, "an");
1390 }
1391 else // must be a decimal, or it is not a real
1392 {
1394 }
1395 }
1396 else // starts with 0. is it 0x, 0b or 0o?
1397 {
1398 const char next = ne.str[skip_start + 1];
1399 // hexadecimal
1400 if(next == 'x' || next == 'X')
1402 // binary
1403 else if(next == 'b' || next == 'B')
1405 // octal
1406 else if(next == 'o' || next == 'O')
1408 // none of the above. may still be a decimal.
1409 else
1410 return ne._first_real_span_dec(skip_start); // do not skip the 0.
1411 }
1412 }
1413 // less than 3 chars after the leading sign. It is either a
1414 // decimal or it is not a real. (cannot be any of 0x0, etc).
1416 }
basic_substring _first_real_span_hex(size_t pos) const noexcept
Definition substr.hpp:1529
basic_substring _first_real_span_oct(size_t pos) const noexcept
Definition substr.hpp:1709
basic_substring _first_real_span_bin(size_t pos) const noexcept
Definition substr.hpp:1619
basic_substring _first_real_span_dec(size_t pos) const noexcept
Definition substr.hpp:1442
basic_substring _word_follows(size_t pos, csubstr word) const noexcept
Definition substr.hpp:1432

◆ _is_delim_char()

template<class C>
constexpr C4_CONST bool c4::basic_substring< C >::_is_delim_char ( char c)
inlinestaticconstexprnoexcept

true if the character is a delimiter character at the end

Definition at line 1419 of file substr.hpp.

1420 {
1421 return c == ' ' || c == '\n'
1422 || c == ']' || c == ')' || c == '}'
1423 || c == ',' || c == ';' || c == '\r' || c == '\t' || c == '\0';
1424 }

◆ _is_hex_char()

template<class C>
constexpr C4_CONST bool c4::basic_substring< C >::_is_hex_char ( char c)
inlinestaticconstexprnoexcept

true if the character is in [0-9a-fA-F]

Definition at line 1427 of file substr.hpp.

1428 {
1429 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
1430 }

◆ _word_follows()

template<class C>
basic_substring c4::basic_substring< C >::_word_follows ( size_t pos,
csubstr word ) const
inlinenoexcept

Definition at line 1432 of file substr.hpp.

1433 {
1434 size_t posend = pos + word.len;
1435 if(len >= posend && sub(pos, word.len) == word)
1436 if(len == posend || _is_delim_char(str[posend]))
1437 return first(posend);
1438 return first(0);
1439 }

Referenced by c4::basic_substring< CC >::first_real_span().

◆ _first_real_span_dec()

template<class C>
basic_substring c4::basic_substring< C >::_first_real_span_dec ( size_t pos) const
inlinenoexcept

Definition at line 1442 of file substr.hpp.

1443 {
1444 bool intchars = false;
1445 bool fracchars = false;
1446 bool powchars;
1447 // integral part
1448 for( ; pos < len; ++pos)
1449 {
1450 const char c = str[pos];
1451 if(c >= '0' && c <= '9')
1452 {
1453 intchars = true;
1454 }
1455 else if(c == '.')
1456 {
1457 ++pos;
1458 goto fractional_part_dec; // NOLINT
1459 }
1460 else if(c == 'e' || c == 'E')
1461 {
1462 ++pos;
1463 goto power_part_dec; // NOLINT
1464 }
1465 else if(_is_delim_char(c))
1466 {
1467 return intchars ? first(pos) : first(0);
1468 }
1469 else
1470 {
1471 return first(0);
1472 }
1473 }
1474 // no . or p were found; this is either an integral number
1475 // or not a number at all
1476 return intchars ?
1477 *this :
1478 first(0);
1480 C4_ASSERT(pos > 0);
1481 C4_ASSERT(str[pos - 1] == '.');
1482 for( ; pos < len; ++pos)
1483 {
1484 const char c = str[pos];
1485 if(c >= '0' && c <= '9')
1486 {
1487 fracchars = true;
1488 }
1489 else if(c == 'e' || c == 'E')
1490 {
1491 ++pos;
1492 goto power_part_dec; // NOLINT
1493 }
1494 else if(_is_delim_char(c))
1495 {
1496 return intchars || fracchars ? first(pos) : first(0);
1497 }
1498 else
1499 {
1500 return first(0);
1501 }
1502 }
1503 return intchars || fracchars ?
1504 *this :
1505 first(0);
1507 C4_ASSERT(pos > 0);
1508 C4_ASSERT(str[pos - 1] == 'e' || str[pos - 1] == 'E');
1509 // either digits, or +, or - are expected here, followed by more digits.
1510 if((len == pos) || ((!intchars) && (!fracchars)))
1511 return first(0);
1512 if(str[pos] == '-' || str[pos] == '+')
1513 ++pos; // skip the sign
1514 powchars = false;
1515 for( ; pos < len; ++pos)
1516 {
1517 const char c = str[pos];
1518 if(c >= '0' && c <= '9')
1519 powchars = true;
1520 else if(powchars && _is_delim_char(c))
1521 return first(pos);
1522 else
1523 return first(0);
1524 }
1525 return powchars ? *this : first(0);
1526 }

Referenced by c4::basic_substring< CC >::first_real_span().

◆ _first_real_span_hex()

template<class C>
basic_substring c4::basic_substring< C >::_first_real_span_hex ( size_t pos) const
inlinenoexcept

Definition at line 1529 of file substr.hpp.

1530 {
1531 bool intchars = false;
1532 bool fracchars = false;
1533 bool powchars;
1534 // integral part
1535 for( ; pos < len; ++pos)
1536 {
1537 const char c = str[pos];
1538 if(_is_hex_char(c))
1539 {
1540 intchars = true;
1541 }
1542 else if(c == '.')
1543 {
1544 ++pos;
1545 goto fractional_part_hex; // NOLINT
1546 }
1547 else if(c == 'p' || c == 'P')
1548 {
1549 ++pos;
1550 goto power_part_hex; // NOLINT
1551 }
1552 else if(_is_delim_char(c))
1553 {
1554 return intchars ? first(pos) : first(0);
1555 }
1556 else
1557 {
1558 return first(0);
1559 }
1560 }
1561 // no . or p were found; this is either an integral number
1562 // or not a number at all
1563 return intchars ?
1564 *this :
1565 first(0);
1567 C4_ASSERT(pos > 0);
1568 C4_ASSERT(str[pos - 1] == '.');
1569 for( ; pos < len; ++pos)
1570 {
1571 const char c = str[pos];
1572 if(_is_hex_char(c))
1573 {
1574 fracchars = true;
1575 }
1576 else if(c == 'p' || c == 'P')
1577 {
1578 ++pos;
1579 goto power_part_hex; // NOLINT
1580 }
1581 else if(_is_delim_char(c))
1582 {
1583 return intchars || fracchars ? first(pos) : first(0);
1584 }
1585 else
1586 {
1587 return first(0);
1588 }
1589 }
1590 return intchars || fracchars ?
1591 *this :
1592 first(0);
1594 C4_ASSERT(pos > 0);
1595 C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1596 // either a + or a - is expected here, followed by more chars.
1597 // also, using (pos+1) in this check will cause an early
1598 // return when no more chars follow the sign.
1599 if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1600 return first(0);
1601 ++pos; // this was the sign.
1602 // ... so the (pos+1) ensures that we enter the loop and
1603 // hence that there exist chars in the power part
1604 powchars = false;
1605 for( ; pos < len; ++pos)
1606 {
1607 const char c = str[pos];
1608 if(c >= '0' && c <= '9')
1609 powchars = true;
1610 else if(powchars && _is_delim_char(c))
1611 return first(pos);
1612 else
1613 return first(0);
1614 }
1615 return *this;
1616 }

Referenced by c4::basic_substring< CC >::first_real_span().

◆ _first_real_span_bin()

template<class C>
basic_substring c4::basic_substring< C >::_first_real_span_bin ( size_t pos) const
inlinenoexcept

Definition at line 1619 of file substr.hpp.

1620 {
1621 bool intchars = false;
1622 bool fracchars = false;
1623 bool powchars;
1624 // integral part
1625 for( ; pos < len; ++pos)
1626 {
1627 const char c = str[pos];
1628 if(c == '0' || c == '1')
1629 {
1630 intchars = true;
1631 }
1632 else if(c == '.')
1633 {
1634 ++pos;
1635 goto fractional_part_bin; // NOLINT
1636 }
1637 else if(c == 'p' || c == 'P')
1638 {
1639 ++pos;
1640 goto power_part_bin; // NOLINT
1641 }
1642 else if(_is_delim_char(c))
1643 {
1644 return intchars ? first(pos) : first(0);
1645 }
1646 else
1647 {
1648 return first(0);
1649 }
1650 }
1651 // no . or p were found; this is either an integral number
1652 // or not a number at all
1653 return intchars ?
1654 *this :
1655 first(0);
1657 C4_ASSERT(pos > 0);
1658 C4_ASSERT(str[pos - 1] == '.');
1659 for( ; pos < len; ++pos)
1660 {
1661 const char c = str[pos];
1662 if(c == '0' || c == '1')
1663 {
1664 fracchars = true;
1665 }
1666 else if(c == 'p' || c == 'P')
1667 {
1668 ++pos;
1669 goto power_part_bin; // NOLINT
1670 }
1671 else if(_is_delim_char(c))
1672 {
1673 return intchars || fracchars ? first(pos) : first(0);
1674 }
1675 else
1676 {
1677 return first(0);
1678 }
1679 }
1680 return intchars || fracchars ?
1681 *this :
1682 first(0);
1684 C4_ASSERT(pos > 0);
1685 C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1686 // either a + or a - is expected here, followed by more chars.
1687 // also, using (pos+1) in this check will cause an early
1688 // return when no more chars follow the sign.
1689 if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1690 return first(0);
1691 ++pos; // this was the sign.
1692 // ... so the (pos+1) ensures that we enter the loop and
1693 // hence that there exist chars in the power part
1694 powchars = false;
1695 for( ; pos < len; ++pos)
1696 {
1697 const char c = str[pos];
1698 if(c >= '0' && c <= '9')
1699 powchars = true;
1700 else if(powchars && _is_delim_char(c))
1701 return first(pos);
1702 else
1703 return first(0);
1704 }
1705 return *this;
1706 }

Referenced by c4::basic_substring< CC >::first_real_span().

◆ _first_real_span_oct()

template<class C>
basic_substring c4::basic_substring< C >::_first_real_span_oct ( size_t pos) const
inlinenoexcept

Definition at line 1709 of file substr.hpp.

1710 {
1711 bool intchars = false;
1712 bool fracchars = false;
1713 bool powchars;
1714 // integral part
1715 for( ; pos < len; ++pos)
1716 {
1717 const char c = str[pos];
1718 if(c >= '0' && c <= '7')
1719 {
1720 intchars = true;
1721 }
1722 else if(c == '.')
1723 {
1724 ++pos;
1725 goto fractional_part_oct; // NOLINT
1726 }
1727 else if(c == 'p' || c == 'P')
1728 {
1729 ++pos;
1730 goto power_part_oct; // NOLINT
1731 }
1732 else if(_is_delim_char(c))
1733 {
1734 return intchars ? first(pos) : first(0);
1735 }
1736 else
1737 {
1738 return first(0);
1739 }
1740 }
1741 // no . or p were found; this is either an integral number
1742 // or not a number at all
1743 return intchars ?
1744 *this :
1745 first(0);
1747 C4_ASSERT(pos > 0);
1748 C4_ASSERT(str[pos - 1] == '.');
1749 for( ; pos < len; ++pos)
1750 {
1751 const char c = str[pos];
1752 if(c >= '0' && c <= '7')
1753 {
1754 fracchars = true;
1755 }
1756 else if(c == 'p' || c == 'P')
1757 {
1758 ++pos;
1759 goto power_part_oct; // NOLINT
1760 }
1761 else if(_is_delim_char(c))
1762 {
1763 return intchars || fracchars ? first(pos) : first(0);
1764 }
1765 else
1766 {
1767 return first(0);
1768 }
1769 }
1770 return intchars || fracchars ?
1771 *this :
1772 first(0);
1774 C4_ASSERT(pos > 0);
1775 C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1776 // either a + or a - is expected here, followed by more chars.
1777 // also, using (pos+1) in this check will cause an early
1778 // return when no more chars follow the sign.
1779 if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1780 return first(0);
1781 ++pos; // this was the sign.
1782 // ... so the (pos+1) ensures that we enter the loop and
1783 // hence that there exist chars in the power part
1784 powchars = false;
1785 for( ; pos < len; ++pos)
1786 {
1787 const char c = str[pos];
1788 if(c >= '0' && c <= '9')
1789 powchars = true;
1790 else if(powchars && _is_delim_char(c))
1791 return first(pos);
1792 else
1793 return first(0);
1794 }
1795 return *this;
1796 }

Referenced by c4::basic_substring< CC >::first_real_span().

◆ next_split()

template<class C>
bool c4::basic_substring< C >::next_split ( C sep,
size_t * start_pos,
basic_substring< C > * out ) const
inline

returns true if the string has not been exhausted yet, meaning it's ok to call next_split() again.

When no instance of sep exists in the string, returns the full string. When the input is an empty string, the output string is the empty string.

Definition at line 1809 of file substr.hpp.

1810 {
1811 if C4_LIKELY(*start_pos < len)
1812 {
1813 for(size_t i = *start_pos; i < len; i++)
1814 {
1815 if(str[i] == sep)
1816 {
1817 out->assign(str + *start_pos, i - *start_pos);
1818 *start_pos = i+1;
1819 return true;
1820 }
1821 }
1823 *start_pos = len + 1;
1824 return true;
1825 }
1826 else
1827 {
1828 bool valid = len > 0 && (*start_pos == len);
1829 if(valid && str && str[len-1] == sep)
1830 {
1831 out->assign(str + len, size_t(0)); // the cast is needed to prevent overload ambiguity
1832 }
1833 else
1834 {
1835 out->assign(str + len + 1, size_t(0)); // the cast is needed to prevent overload ambiguity
1836 }
1837 *start_pos = len + 1;
1838 return valid;
1839 }
1840 }
void assign(C(&s_)[N]) noexcept
Assign from an array.
Definition substr.hpp:300

◆ split()

template<class C>
split_proxy c4::basic_substring< C >::split ( C sep,
size_t start_pos = 0 ) const
inline

a view into the splits

Definition at line 1912 of file substr.hpp.

1913 {
1914 C4_XASSERT((start_pos >= 0 && start_pos < len) || empty());
1915 auto ss = sub(0, len);
1916 auto it = split_proxy(ss, start_pos, sep);
1917 return it;
1918 }
split_proxy_impl split_proxy
Definition substr.hpp:1909

Referenced by c4::yml::location_format_with_context().

◆ pop_right()

template<class C>
basic_substring c4::basic_substring< C >::pop_right ( C sep = C('/'),
bool skip_empty = false ) const
inline

pop right: return the first split from the right.

Use gpop_left() to get the reciprocal part.

Definition at line 1925 of file substr.hpp.

1926 {
1927 if C4_LIKELY(len > 1)
1928 {
1929 auto pos = last_of(sep);
1930 if(pos != npos)
1931 {
1932 if(pos + 1 < len) // does not end with sep
1933 {
1934 return sub(pos + 1); // return from sep to end
1935 }
1936 else // the string ends with sep
1937 {
1938 if( ! skip_empty)
1939 {
1940 return sub(pos + 1, 0);
1941 }
1942 auto ppos = last_not_of(sep); // skip repeated seps
1943 if(ppos == npos) // the string is all made of seps
1944 {
1945 return sub(0, 0);
1946 }
1947 // find the previous sep
1948 auto pos0 = last_of(sep, ppos);
1949 if(pos0 == npos) // only the last sep exists
1950 {
1951 return sub(0); // return the full string (because skip_empty is true)
1952 }
1953 ++pos0;
1954 return sub(pos0);
1955 }
1956 }
1957 else // no sep was found, return the full string
1958 {
1959 return *this;
1960 }
1961 }
1962 else if(len == 1)
1963 {
1964 if(begins_with(sep))
1965 {
1966 return sub(0, 0);
1967 }
1968 return *this;
1969 }
1970 else // an empty string
1971 {
1972 return basic_substring();
1973 }
1974 }
size_t last_of(const C c, size_t start=npos) const
Definition substr.hpp:946

◆ pop_left()

template<class C>
basic_substring c4::basic_substring< C >::pop_left ( C sep = C('/'),
bool skip_empty = false ) const
inline

return the first split from the left.

Use gpop_right() to get the reciprocal part.

Definition at line 1978 of file substr.hpp.

1979 {
1980 if C4_LIKELY(len > 1)
1981 {
1982 auto pos = first_of(sep);
1983 if(pos != npos)
1984 {
1985 if(pos > 0) // does not start with sep
1986 {
1987 return sub(0, pos); // return everything up to it
1988 }
1989 else // the string starts with sep
1990 {
1991 if( ! skip_empty)
1992 {
1993 return sub(0, 0);
1994 }
1995 auto ppos = first_not_of(sep); // skip repeated seps
1996 if(ppos == npos) // the string is all made of seps
1997 {
1998 return sub(0, 0);
1999 }
2000 // find the next sep
2001 auto pos0 = first_of(sep, ppos);
2002 if(pos0 == npos) // only the first sep exists
2003 {
2004 return sub(0); // return the full string (because skip_empty is true)
2005 }
2006 C4_XASSERT(pos0 > 0);
2007 // return everything up to the second sep
2008 return sub(0, pos0);
2009 }
2010 }
2011 else // no sep was found, return the full string
2012 {
2013 return sub(0);
2014 }
2015 }
2016 else if(len == 1)
2017 {
2018 if(begins_with(sep))
2019 {
2020 return sub(0, 0);
2021 }
2022 return sub(0);
2023 }
2024 else // an empty string
2025 {
2026 return basic_substring();
2027 }
2028 }

◆ gpop_left()

template<class C>
basic_substring c4::basic_substring< C >::gpop_left ( C sep = C('/'),
bool skip_empty = false ) const
inline

greedy pop left.

eg, csubstr("a/b/c").gpop_left('/')="c"

Definition at line 2033 of file substr.hpp.

2034 {
2035 auto ss = pop_right(sep, skip_empty);
2036 ss = left_of(ss);
2037 if(ss.find(sep) != npos)
2038 {
2039 if(ss.ends_with(sep))
2040 {
2041 if(skip_empty)
2042 {
2043 ss = ss.trimr(sep);
2044 }
2045 else
2046 {
2047 ss = ss.sub(0, ss.len-1); // safe to subtract because ends_with(sep) is true
2048 }
2049 }
2050 }
2051 return ss;
2052 }
basic_substring pop_right(C sep=C('/'), bool skip_empty=false) const
pop right: return the first split from the right.
Definition substr.hpp:1925

◆ gpop_right()

template<class C>
basic_substring c4::basic_substring< C >::gpop_right ( C sep = C('/'),
bool skip_empty = false ) const
inline

greedy pop right.

eg, csubstr("a/b/c").gpop_right('/')="a"

Definition at line 2055 of file substr.hpp.

2056 {
2057 auto ss = pop_left(sep, skip_empty);
2058 ss = right_of(ss);
2059 if(ss.find(sep) != npos)
2060 {
2061 if(ss.begins_with(sep))
2062 {
2063 if(skip_empty)
2064 {
2065 ss = ss.triml(sep);
2066 }
2067 else
2068 {
2069 ss = ss.sub(1);
2070 }
2071 }
2072 }
2073 return ss;
2074 }
basic_substring right_of(size_t pos) const noexcept
return [pos+1, len[
Definition substr.hpp:574
basic_substring pop_left(C sep=C('/'), bool skip_empty=false) const
return the first split from the left.
Definition substr.hpp:1978

◆ basename()

template<class C>
basic_substring c4::basic_substring< C >::basename ( C sep = C('/')) const
inline

Definition at line 2083 of file substr.hpp.

2084 {
2085 auto ss = pop_right(sep, /*skip_empty*/true);
2086 ss = ss.trimr(sep);
2087 return ss;
2088 }

◆ dirname()

template<class C>
basic_substring c4::basic_substring< C >::dirname ( C sep = C('/')) const
inline

Definition at line 2090 of file substr.hpp.

2091 {
2092 auto ss = basename(sep);
2093 ss = ss.empty() ? *this : left_of(ss);
2094 return ss;
2095 }
basic_substring basename(C sep=C('/')) const
Definition substr.hpp:2083

◆ name_wo_extshort()

template<class C>
basic_substring c4::basic_substring< C >::name_wo_extshort ( ) const
inline

Definition at line 2097 of file substr.hpp.

2098 {
2099 return gpop_left('.');
2100 }
basic_substring gpop_left(C sep=C('/'), bool skip_empty=false) const
greedy pop left.
Definition substr.hpp:2033

◆ name_wo_extlong()

template<class C>
basic_substring c4::basic_substring< C >::name_wo_extlong ( ) const
inline

Definition at line 2102 of file substr.hpp.

2103 {
2104 return pop_left('.');
2105 }

◆ extshort()

template<class C>
basic_substring c4::basic_substring< C >::extshort ( ) const
inline

Definition at line 2107 of file substr.hpp.

2108 {
2109 return pop_right('.');
2110 }

◆ extlong()

template<class C>
basic_substring c4::basic_substring< C >::extlong ( ) const
inline

Definition at line 2112 of file substr.hpp.

2113 {
2114 return gpop_right('.');
2115 }
basic_substring gpop_right(C sep=C('/'), bool skip_empty=false) const
greedy pop right.
Definition substr.hpp:2055

◆ toupper()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::toupper ( ) ->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

convert the string to upper-case

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2127 of file substr.hpp.

2129 {
2130 for(size_t i = 0; i < len; ++i)
2131 {
2132 str[i] = static_cast<C>(::toupper(str[i]));
2133 }
2134 }
auto toupper() -> typename std::enable_if< ! std::is_const< U >::value, void >::type
convert the string to upper-case
Definition substr.hpp:2127

Referenced by sample_substr().

◆ tolower()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::tolower ( ) ->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

convert the string to lower-case

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2139 of file substr.hpp.

2141 {
2142 for(size_t i = 0; i < len; ++i)
2143 {
2144 str[i] = static_cast<C>(::tolower(str[i]));
2145 }
2146 }
auto tolower() -> typename std::enable_if< !std::is_const< U >::value, void >::type
convert the string to lower-case
Definition substr.hpp:2139

Referenced by sample_substr().

◆ fill()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::fill ( C val) ->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

fill the entire contents with the given val

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2153 of file substr.hpp.

2155 {
2156 for(size_t i = 0; i < len; ++i)
2157 str[i] = val;
2158 }

Referenced by sample_substr(), c4::to_chars(), c4::to_chars(), and c4::to_chars().

◆ copy_from() [1/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::copy_from ( ro_substr that) ->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

copy a string to this substr, starting at 0

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2165 of file substr.hpp.

2167 {
2169 size_t num = that.len <= len ? that.len : len;
2170 // calling memcpy with zero len is undefined behavior
2171 // and will wreak havoc in calling code's branches.
2172 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2173 if(num)
2174 memcpy(str, that.str, sizeof(C) * num);
2175 }
bool overlaps(ro_substr const that) const noexcept
true if there is overlap of at least one element between that and *this
Definition substr.hpp:493

Referenced by c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), and c4::to_chars().

◆ copy_from() [2/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::copy_from ( ro_substr that,
size_t ifirst,
size_t num = npos )->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

copy a string to this substr, starting at a specified given position

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2180 of file substr.hpp.

2182 {
2183 C4_ASSERT(ifirst >= 0 && ifirst <= len);
2184 num = num != npos ? num : len - ifirst;
2185 num = num < that.len ? num : that.len;
2186 C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2187 // calling memcpy with zero len is undefined behavior
2188 // and will wreak havoc in calling code's branches.
2189 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2190 if(num)
2191 memcpy(str + (sizeof(C) * ifirst), that.str, sizeof(C) * num);
2192 }

◆ reverse()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::reverse ( ) ->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

reverse in place

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2199 of file substr.hpp.

2201 {
2202 if(len == 0) return;
2204 }

Referenced by sample_substr().

◆ reverse_sub()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::reverse_sub ( size_t ifirst,
size_t num )->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

revert a subpart in place

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2209 of file substr.hpp.

2211 {
2212 C4_ASSERT(ifirst >= 0 && ifirst <= len);
2213 C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2214 if(num == 0) return;
2216 }

Referenced by sample_substr().

◆ reverse_range()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::reverse_range ( size_t ifirst,
size_t ilast )->typenamestd::enable_if<!std::is_const< U >::value, void >::type
inline

revert a range in place

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2221 of file substr.hpp.

2223 {
2224 C4_ASSERT(ifirst >= 0 && ifirst <= len);
2225 C4_ASSERT(ilast >= 0 && ilast <= len);
2226 if(ifirst == ilast) return;
2228 }

Referenced by sample_substr().

◆ erase() [1/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::erase ( size_t pos,
size_t num )->typenamestd::enable_if<!std::is_const< U >::value, basic_substring >::type
inline

erase part of the string.

eg, with char s[] = "0123456789", substr(s).erase(3, 2) = "01256789", and s is now "0125678989"

Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2236 of file substr.hpp.

2238 {
2239 C4_ASSERT(pos >= 0 && pos+num <= len);
2240 size_t num_to_move = len - pos - num;
2241 memmove(str + pos, str + pos + num, sizeof(C) * num_to_move);
2242 return basic_substring{str, len - num};
2243 }

◆ erase_range()

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::erase_range ( size_t first,
size_t last )->typenamestd::enable_if<!std::is_const< U >::value, basic_substring >::type
inline
Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2247 of file substr.hpp.

2249 {
2250 C4_ASSERT(first <= last);
2251 return erase(first, static_cast<size_t>(last-first)); // NOLINT
2252 }
auto erase(size_t pos, size_t num) -> typename std::enable_if< !std::is_const< U >::value, basic_substring >::type
erase part of the string.
Definition substr.hpp:2236

◆ erase() [2/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::erase ( ro_substr sub) ->typenamestd::enable_if<!std::is_const< U >::value, basic_substring >::type
inline

erase a part of the string.

Note
sub must be a substring of this string
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2258 of file substr.hpp.

2260 {
2262 C4_ASSERT(sub.str >= str);
2263 return erase(static_cast<size_t>(sub.str - str), sub.len);
2264 }

◆ replace() [1/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::replace ( C value,
C repl,
size_t pos = 0 )->typenamestd::enable_if<!std::is_const< U >::value, size_t >::type
inline

replace every occurrence of character value with the character repl

Returns
the number of characters that were replaced
Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2272 of file substr.hpp.

2274 {
2275 C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2276 size_t did_it = 0;
2277 while((pos = find(value, pos)) != npos)
2278 {
2279 str[pos++] = repl;
2280 ++did_it;
2281 }
2282 return did_it;
2283 }

Referenced by sample_substr().

◆ replace() [2/2]

template<class C>
template<typename U = C>
auto c4::basic_substring< C >::replace ( ro_substr chars,
C repl,
size_t pos = 0 )->typenamestd::enable_if<!std::is_const< U >::value, size_t >::type
inline

replace every occurrence of each character in value with the character repl.

Returns
the number of characters that were replaced
Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2290 of file substr.hpp.

2292 {
2293 C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2294 size_t did_it = 0;
2295 while((pos = first_of(chars, pos)) != npos)
2296 {
2297 str[pos++] = repl;
2298 ++did_it;
2299 }
2300 return did_it;
2301 }

◆ replace_all()

template<class C>
size_t c4::basic_substring< C >::replace_all ( rw_substr dst,
ro_substr pattern,
ro_substr repl,
size_t pos = 0 ) const
inline

replace pattern with repl, and write the result into dst.

pattern and repl don't need equal sizes.

Returns
the required size for dst. No overflow occurs if dst.len is smaller than the required size; this can be used to determine the required size for an existing container.

<

<

Definition at line 2309 of file substr.hpp.

2310 {
2311 C4_ASSERT( ! pattern.empty()); //!< @todo relax this precondition
2312 C4_ASSERT( ! this ->overlaps(dst)); //!< @todo relax this precondition
2314 C4_ASSERT( ! repl .overlaps(dst));
2315 C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2317 C4_SUPPRESS_WARNING_GCC("-Warray-bounds") // gcc11 has a false positive here
2318 #if (!defined(__clang__)) && (defined(__GNUC__) && (__GNUC__ >= 7))
2319 C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow") // gcc11 has a false positive here
2320 #endif
2321 #define _c4append(first, last) \
2322 { \
2323 C4_ASSERT((last) >= (first)); \
2324 size_t num = static_cast<size_t>((last) - (first)); \
2325 if(num > 0 && sz + num <= dst.len) \
2326 { \
2327 memcpy(dst.str + sz, first, num * sizeof(C)); \
2328 } \
2329 sz += num; \
2330 }
2331 size_t sz = 0;
2332 size_t b = pos;
2333 _c4append(str, str + pos)
2334 do {
2335 size_t e = find(pattern, b);
2336 if(e == npos)
2337 {
2338 _c4append(str + b, str + len)
2339 break;
2340 }
2341 _c4append(str + b, str + e)
2343 b = e + pattern.size();
2344 } while(b < len && b != npos);
2345 return sz;
2346 #undef _c4append
2348 }
size_t size() const noexcept
Definition substr.hpp:358
#define _c4append(first, last)

Member Data Documentation

◆ str

template<class C>
C* c4::basic_substring< C >::str

a restricted pointer to the first character of the substring

Definition at line 216 of file substr.hpp.

Referenced by c4::yml::extra::EventHandlerInts::alloc_arena(), c4::atod(), c4::atof(), c4::fmt::base64(), c4::fmt::base64(), c4::cat_sub(), c4::catsep_sub(), c4::fmt::cbase64(), c4::yml::Tree::copy_to_arena(), c4::decode_code_point(), c4::yml::emitrs_json(), c4::yml::emitrs_yaml(), c4::yml::escape_scalar(), c4::yml::escape_scalar_fn(), c4::yml::extra::estimate_events_ints_size(), c4::yml::estimate_tree_capacity(), c4::yml::extra::events_ints_print(), c4::yml::extra::events_ints_to_testsuite(), c4::basic_substring< CC >::find(), c4::basic_substring< CC >::first_int_span(), c4::basic_substring< CC >::first_not_of(), c4::basic_substring< CC >::first_not_of(), c4::basic_substring< CC >::first_of(), c4::basic_substring< CC >::first_real_span(), c4::basic_substring< CC >::first_uint_span(), c4::yml::format_exc(), c4::yml::format_exc(), c4::yml::format_exc(), c4::format_sub(), c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::from_chars_first(), c4::yml::WriterBuf::get_result(), c4::yml::is_custom_tag(), c4::basic_substring< CC >::last_not_of(), c4::basic_substring< CC >::last_not_of(), c4::yml::Tree::location(), c4::yml::normalize_tag_long(), ErrorHandlerExample::on_error_basic(), ErrorHandlerExample::on_error_parse(), ErrorHandlerExample::on_error_visit(), c4::operator<<(), c4::yml::NodeRef::operator==(), c4::yml::Tree::reserve_arena(), c4::yml::TagDirectives::resolve(), c4::yml::FilterProcessorInplaceEndExtending::result(), c4::yml::FilterProcessorInplaceMidExtending::result(), c4::yml::FilterProcessorSrcDst::result(), sample_create_tree(), sample_deserialize_error(), sample_emit_to_container(), sample_empty_null_values(), sample_error_parse(), sample_error_visit_location(), sample_formatting(), sample_substr(), sample_tree_arena(), c4::yml::serialize_to_arena_str(), c4::yml::extra::EventHandlerInts::set_key_scalar_dquoted(), c4::yml::extra::EventHandlerInts::set_key_scalar_folded(), c4::yml::extra::EventHandlerInts::set_key_scalar_literal(), c4::yml::extra::EventHandlerInts::set_key_scalar_plain(), c4::yml::extra::EventHandlerInts::set_key_scalar_squoted(), c4::yml::extra::EventHandlerInts::set_key_tag(), c4::yml::extra::EventHandlerInts::set_val_scalar_dquoted(), c4::yml::extra::EventHandlerInts::set_val_scalar_folded(), c4::yml::extra::EventHandlerInts::set_val_scalar_literal(), c4::yml::extra::EventHandlerInts::set_val_scalar_plain(), c4::yml::extra::EventHandlerInts::set_val_scalar_squoted(), c4::yml::extra::EventHandlerInts::set_val_tag(), c4::yml::extra::EventHandlerInts::start_parse(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::yml::transform_tag(), and c4::yml::NodeType::type_str_sub().

◆ len

template<class C>
size_t c4::basic_substring< C >::len

the length of the substring

Definition at line 218 of file substr.hpp.

Referenced by c4::yml::detail::_get_text_region(), c4::yml::extra::EventHandlerInts::alloc_arena(), c4::yml::extra::EventHandlerInts::arena(), c4::yml::extra::EventHandlerInts::arena_rem(), c4::atod(), c4::atod_first(), c4::atof(), c4::atof_first(), c4::atoi_first(), c4::atou_first(), c4::fmt::base64(), c4::fmt::base64(), c4::cat(), c4::cat_sub(), c4::catrs(), c4::catrs_append(), c4::catsep(), c4::catsep_sub(), c4::catseprs(), c4::catseprs_append(), c4::fmt::cbase64(), c4::yml::Tree::copy_to_arena(), c4::basic_substring< CC >::count(), c4::decode_code_point(), c4::yml::emitrs_json(), c4::yml::emitrs_yaml(), c4::yml::escape_scalar(), c4::yml::escape_scalar_fn(), c4::yml::extra::estimate_events_ints_size(), c4::yml::estimate_tree_capacity(), c4::yml::extra::events_ints_print(), c4::yml::extra::events_ints_to_testsuite(), c4::basic_substring< CC >::find(), c4::first_non_bom(), c4::basic_substring< CC >::first_not_of(), c4::basic_substring< CC >::first_not_of(), c4::basic_substring< CC >::first_of(), c4::basic_substring< CC >::first_real_span(), c4::yml::extra::EventHandlerInts::fits_buffers(), c4::format(), c4::yml::format_exc(), c4::yml::format_exc(), c4::yml::format_exc(), c4::format_sub(), c4::formatrs(), c4::formatrs_append(), c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::from_chars(), c4::from_chars_first(), c4::from_chars_first(), c4::from_chars_first(), c4::yml::WriterBuf::get_result(), c4::yml::is_custom_tag(), c4::basic_substring< CC >::last_not_of(), c4::basic_substring< CC >::last_not_of(), c4::basic_substring< CC >::last_of(), c4::yml::location_format(), c4::yml::location_format_with_context(), c4::yml::normalize_tag_long(), ErrorHandlerExample::on_error_basic(), ErrorHandlerExample::on_error_parse(), ErrorHandlerExample::on_error_visit(), c4::operator<<(), c4::yml::NodeRef::operator==(), c4::yml::Tree::reserve_arena(), c4::yml::TagDirectives::resolve(), c4::yml::Tree::resolve_tag_sub(), c4::yml::Tree::lookup_result::resolved(), c4::yml::FilterProcessorInplaceEndExtending::result(), c4::yml::FilterProcessorInplaceMidExtending::result(), c4::yml::FilterProcessorSrcDst::result(), sample_base64(), sample_emit_to_container(), sample_empty_null_values(), sample_error_parse(), sample_error_visit_location(), sample_formatting(), sample_substr(), sample_tree_arena(), c4::basic_substring< CC >::select(), c4::yml::serialize_to_arena_scalar(), c4::yml::serialize_to_arena_str(), c4::yml::EventHandlerTree::set_key_anchor(), c4::yml::EventHandlerTree::set_key_ref(), c4::yml::extra::EventHandlerInts::set_key_scalar_dquoted(), c4::yml::extra::EventHandlerInts::set_key_scalar_folded(), c4::yml::extra::EventHandlerInts::set_key_scalar_literal(), c4::yml::extra::EventHandlerInts::set_key_scalar_plain(), c4::yml::extra::EventHandlerInts::set_key_scalar_squoted(), c4::yml::EventHandlerTree::set_key_tag(), c4::yml::extra::EventHandlerInts::set_key_tag(), c4::yml::EventHandlerTree::set_val_anchor(), c4::yml::EventHandlerTree::set_val_ref(), c4::yml::extra::EventHandlerInts::set_val_scalar_dquoted(), c4::yml::extra::EventHandlerInts::set_val_scalar_folded(), c4::yml::extra::EventHandlerInts::set_val_scalar_literal(), c4::yml::extra::EventHandlerInts::set_val_scalar_plain(), c4::yml::extra::EventHandlerInts::set_val_scalar_squoted(), c4::yml::EventHandlerTree::set_val_tag(), c4::yml::extra::EventHandlerInts::set_val_tag(), c4::yml::extra::EventHandlerInts::start_parse(), c4::basic_substring< CC >::stripl(), c4::basic_substring< CC >::stripr(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::to_chars(), c4::yml::extra::ievt::to_str_sub(), c4::yml::to_tag(), c4::yml::transform_tag(), c4::yml::NodeType::type_str_sub(), c4::uncat(), c4::uncatsep(), and c4::unformat().


The documentation for this struct was generated from the following file:
  • /home/docs/checkouts/readthedocs.org/user_builds/rapidyaml/checkouts/latest/ext/c4core.src/c4/substr.hpp