rapidyaml  0.7.0
parse and emit YAML, and do it fast
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. More...
 
 basic_substring (C *s_, size_t len_) noexcept
 Construct from a pointer and length. More...
 
 basic_substring (C *beg_, C *end_) noexcept
 Construct from two pointers. More...
 
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
 basic_substring (U s_) noexcept
 Construct from a C-string (zero-terminated string) More...
 
template<size_t N>
void assign (C(&s_)[N]) noexcept
 Assign from an array. More...
 
void assign (C *s_, size_t len_) noexcept
 Assign from a pointer and length. More...
 
void assign (C *beg_, C *end_) noexcept
 Assign from two pointers. More...
 
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
void assign (U s_) noexcept
 Assign from a C-string (zero-terminated string) More...
 
template<size_t N>
basic_substringoperator= (C(&s_)[N]) noexcept
 Assign from an array. More...
 
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
basic_substringoperator= (U s_) noexcept
 Assign from a C-string (zero-terminated string) More...
 
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 (const char *that, size_t sz) const noexcept
 
int compare (ro_substr 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(&that)[N]) const noexcept
 
template<size_t N>
bool operator!= (const char(&that)[N]) const noexcept
 
template<size_t N>
bool operator< (const char(&that)[N]) const noexcept
 
template<size_t N>
bool operator> (const char(&that)[N]) const noexcept
 
template<size_t N>
bool operator<= (const char(&that)[N]) const noexcept
 
template<size_t N>
bool operator>= (const char(&that)[N]) const noexcept
 
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) More...
 
bool is_super (ro_substr const that) const noexcept
 true if that is a substring of *this (ie, from the same buffer) More...
 
bool overlaps (ro_substr const that) const noexcept
 true if there is overlap of at least one element between that and *this More...
 
basic_substring sub (size_t first) const noexcept
 return [first,len[ More...
 
basic_substring sub (size_t first, size_t num) const noexcept
 return [first,first+num[. More...
 
basic_substring range (size_t first, size_t last=npos) const noexcept
 return [first,last[. More...
 
basic_substring first (size_t num) const noexcept
 return the first num elements: [0,num[ More...
 
basic_substring last (size_t num) const noexcept
 return the last num elements: [len-num,len[ More...
 
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. More...
 
basic_substring left_of (size_t pos) const noexcept
 return [0, pos[ . More...
 
basic_substring left_of (size_t pos, bool include_pos) const noexcept
 return [0, pos+include_pos[ . More...
 
basic_substring right_of (size_t pos) const noexcept
 return [pos+1, len[ More...
 
basic_substring right_of (size_t pos, bool include_pos) const noexcept
 return [pos+!include_pos, len[ More...
 
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 More...
 
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 More...
 
Removing characters (trim()) / patterns (strip()) from the tips of the string
basic_substring triml (const C c) const
 trim left More...
 
basic_substring triml (ro_substr chars) const
 trim left ANY of the characters. More...
 
basic_substring trimr (const C c) const
 trim the character c from the right More...
 
basic_substring trimr (ro_substr chars) const
 trim right ANY of the characters More...
 
basic_substring trim (const C c) const
 trim the character c left and right More...
 
basic_substring trim (ro_substr const chars) const
 trim left and right ANY of the characters More...
 
basic_substring stripl (ro_substr pattern) const
 remove a pattern from the left More...
 
basic_substring stripr (ro_substr pattern) const
 remove a pattern from the right More...
 
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 More...
 
size_t count (ro_substr c, size_t pos=0) const
 count the number of occurrences of s More...
 
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 More...
 
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 More...
 
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
 true if the first character of the string is c More...
 
bool begins_with (const C c, size_t num) const
 true if the first num characters of the string are c More...
 
bool begins_with (ro_substr pattern) const
 true if the string begins with the given pattern More...
 
bool begins_with_any (ro_substr chars) const
 true if the first character of the string is any of the given chars More...
 
bool ends_with (const C c) const
 true if the last character of the string is c More...
 
bool ends_with (const C c, size_t num) const
 true if the last num characters of the string are c More...
 
bool ends_with (ro_substr pattern) const
 true if the string ends with the given pattern More...
 
bool ends_with_any (ro_substr chars) const
 true if the last character of the string is any of the given chars More...
 
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. More...
 
basic_substring pair_range_esc (CC open_close, CC escape=CC('\\'))
 get the range delimited by a single open-close character (eg, quotes). More...
 
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. More...
 
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)
void toupper ()
 convert the string to upper-case More...
 
void tolower ()
 convert the string to lower-case More...
 
void fill (C val)
 fill the entire contents with the given val More...
 
void copy_from (ro_substr that, size_t ifirst=0, size_t num=npos)
 set the current substring to a copy of the given csubstr More...
 
void reverse ()
 reverse in place More...
 
void reverse_sub (size_t ifirst, size_t num)
 revert a subpart in place More...
 
void reverse_range (size_t ifirst, size_t ilast)
 revert a range in place More...
 
basic_substring erase (size_t pos, size_t num)
 erase part of the string. More...
 
basic_substring erase_range (size_t first, size_t last)
 
basic_substring erase (ro_substr sub)
 erase a part of the string. More...
 
size_t replace (C value, C repl, size_t pos=0)
 replace every occurrence of character value with the character repl More...
 
size_t replace (ro_substr chars, C repl, size_t pos=0)
 replace every occurrence of each character in value with the character repl. More...
 
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. More...
 

Public Attributes

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

Types

enum  : size_t { npos = (size_t)-1 , NONE = (size_t)-1 }
 
using CC = typename std::add_const< C >::type
 CC=const char. More...
 
using NCC_ = typename std::remove_const< C >::type
 NCC_=non const char. More...
 
using ro_substr = basic_substring< CC >
 
using rw_substr = basic_substring< NCC_ >
 
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 to substring of const C More...
 

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. More...
 
split_proxy split (C sep, size_t start_pos=0) const
 a view into the splits More...
 
basic_substring pop_right (C sep=C('/'), bool skip_empty=false) const
 pop right: return the first split from the right. More...
 
basic_substring pop_left (C sep=C('/'), bool skip_empty=false) const
 return the first split from the left. More...
 
basic_substring gpop_left (C sep=C('/'), bool skip_empty=false) const
 greedy pop left. More...
 
basic_substring gpop_right (C sep=C('/'), bool skip_empty=false) const
 greedy pop right. More...
 

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 More...
 
basic_substring first_uint_span () const
 get the first span which can be interpreted as an unsigned integer More...
 
basic_substring first_int_span () const
 get the first span which can be interpreted as a signed integer More...
 
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 More...
 
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 More...
 
static constexpr C4_CONST bool _is_hex_char (char c) noexcept
 true if the character is in [0-9a-fA-F] More...
 

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.
substr and to_substr()
csubstr and to_csubstr()

Definition at line 75 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 89 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 90 of file substr.hpp.

◆ ro_substr

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

Definition at line 92 of file substr.hpp.

◆ rw_substr

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

Definition at line 93 of file substr.hpp.

◆ char_type

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

Definition at line 95 of file substr.hpp.

◆ size_type

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

Definition at line 96 of file substr.hpp.

◆ iterator

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

Definition at line 98 of file substr.hpp.

◆ const_iterator

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

Definition at line 99 of file substr.hpp.

◆ split_proxy

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

Definition at line 1761 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

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

Definition at line 101 of file substr.hpp.

101 : size_t { npos = (size_t)-1, NONE = (size_t)-1 };

Constructor & Destructor Documentation

◆ basic_substring() [1/8]

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

Definition at line 117 of file substr.hpp.

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

◆ 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 121 of file substr.hpp.

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

◆ basic_substring() [5/8]

template<class C >
template<size_t N>
constexpr 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 140 of file substr.hpp.

140 : 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 143 of file substr.hpp.

143 : 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 147 of file substr.hpp.

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

◆ basic_substring() [8/8]

template<class C >
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
c4::basic_substring< C >::basic_substring ( 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 155 of file substr.hpp.

155 : 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 to substring of const C

Definition at line 105 of file substr.hpp.

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

◆ 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 125 of file substr.hpp.

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

◆ clear()

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

Definition at line 127 of file substr.hpp.

127 { 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 161 of file substr.hpp.

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

◆ 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 164 of file substr.hpp.

164 { 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 168 of file substr.hpp.

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

◆ assign() [4/4]

template<class C >
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
void c4::basic_substring< C >::assign ( s_)
inlinenoexcept

Assign 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 176 of file substr.hpp.

176 { str = (s_); len = (s_ ? strlen(s_) : 0); }

◆ 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 181 of file substr.hpp.

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

◆ operator=() [5/5]

template<class C >
template<class U , typename std::enable_if< std::is_same< U, C * >::value||std::is_same< U, NCC_ * >::value, int >::type = 0>
basic_substring& c4::basic_substring< C >::operator= ( s_)
inlinenoexcept

Assign 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 189 of file substr.hpp.

189 { str = s_; len = s_ ? strlen(s_) : 0; return *this; }

◆ has_str()

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

Definition at line 198 of file substr.hpp.

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

◆ empty()

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

◆ not_empty()

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

Definition at line 200 of file substr.hpp.

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

◆ size()

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

◆ begin() [1/2]

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

Definition at line 203 of file substr.hpp.

203 { return str; }

Referenced by c4::basic_substring< C >::replace_all().

◆ end() [1/2]

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

Definition at line 204 of file substr.hpp.

204 { return str + len; }

Referenced by c4::basic_substring< C >::replace_all().

◆ begin() [2/2]

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

Definition at line 206 of file substr.hpp.

206 { return str; }

◆ end() [2/2]

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

Definition at line 207 of file substr.hpp.

207 { return str + len; }

◆ data() [1/2]

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

Definition at line 209 of file substr.hpp.

209 { return str; }

Referenced by c4::basic_substring< C >::split_proxy_impl::split_iterator_impl::operator==().

◆ data() [2/2]

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

Definition at line 210 of file substr.hpp.

210 { return str; }

◆ operator[]() [1/2]

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

Definition at line 212 of file substr.hpp.

212 { 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 213 of file substr.hpp.

213 { 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 215 of file substr.hpp.

215 { 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 216 of file substr.hpp.

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

◆ back() [1/2]

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

Definition at line 218 of file substr.hpp.

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

◆ back() [2/2]

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

Definition at line 219 of file substr.hpp.

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

◆ compare() [1/3]

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

Definition at line 228 of file substr.hpp.

229  {
230  C4_XASSERT((str != nullptr) || len == 0);
231  if(C4_LIKELY(str != nullptr && len > 0))
232  return (*str != c) ? *str - c : (static_cast<int>(len) - 1);
233  else
234  return -1;
235  }

◆ compare() [2/3]

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

Definition at line 237 of file substr.hpp.

238  {
239  C4_XASSERT(that || sz == 0);
240  C4_XASSERT(str || len == 0);
241  if(C4_LIKELY(str && that))
242  {
243  {
244  const size_t min = len < sz ? len : sz;
245  for(size_t i = 0; i < min; ++i)
246  if(str[i] != that[i])
247  return str[i] < that[i] ? -1 : 1;
248  }
249  if(len < sz)
250  return -1;
251  else if(len == sz)
252  return 0;
253  else
254  return 1;
255  }
256  else if(len == sz)
257  {
258  C4_XASSERT(len == 0 && sz == 0);
259  return 0;
260  }
261  return len < sz ? -1 : 1;
262  }

◆ compare() [3/3]

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

Definition at line 264 of file substr.hpp.

264 { return this->compare(that.str, that.len); }
int compare(C const c) const noexcept
Definition: substr.hpp:228

References c4::basic_substring< C >::compare().

Referenced by c4::basic_substring< C >::compare().

◆ operator==() [1/4]

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

Definition at line 266 of file substr.hpp.

266 { return str == nullptr; }

◆ operator!=() [1/4]

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

Definition at line 267 of file substr.hpp.

267 { return str != nullptr; }

◆ operator==() [2/4]

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

Definition at line 269 of file substr.hpp.

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

◆ operator!=() [2/4]

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

Definition at line 270 of file substr.hpp.

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

◆ operator<() [1/3]

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

Definition at line 271 of file substr.hpp.

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

◆ operator>() [1/3]

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

Definition at line 272 of file substr.hpp.

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

◆ operator<=() [1/3]

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

Definition at line 273 of file substr.hpp.

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

◆ operator>=() [1/3]

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

Definition at line 274 of file substr.hpp.

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

◆ operator==() [3/4]

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

Definition at line 276 of file substr.hpp.

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

◆ operator!=() [3/4]

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

Definition at line 277 of file substr.hpp.

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

◆ operator<() [2/3]

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

Definition at line 278 of file substr.hpp.

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

◆ operator>() [2/3]

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

Definition at line 279 of file substr.hpp.

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

◆ operator<=() [2/3]

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

Definition at line 280 of file substr.hpp.

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

◆ operator>=() [2/3]

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

Definition at line 281 of file substr.hpp.

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

◆ operator==() [4/4]

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

Definition at line 283 of file substr.hpp.

283 { return this->compare(that, N-1) == 0; }

◆ operator!=() [4/4]

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

Definition at line 284 of file substr.hpp.

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

◆ operator<() [3/3]

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

Definition at line 285 of file substr.hpp.

285 { return this->compare(that, N-1) < 0; }

◆ operator>() [3/3]

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

Definition at line 286 of file substr.hpp.

286 { return this->compare(that, N-1) > 0; }

◆ operator<=() [3/3]

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

Definition at line 287 of file substr.hpp.

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

◆ operator>=() [3/3]

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

Definition at line 288 of file substr.hpp.

288 { return this->compare(that, N-1) >= 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 298 of file substr.hpp.

299  {
300  return that.is_super(*this);
301  }

◆ 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 304 of file substr.hpp.

305  {
306  if(C4_LIKELY(len > 0))
307  return that.str >= str && that.str+that.len <= str+len;
308  else
309  return that.len == 0 && that.str == str && str != nullptr;
310  }

◆ 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 313 of file substr.hpp.

314  {
315  // thanks @timwynants
316  return that.str+that.len > str && that.str < str+len;
317  }

Referenced by c4::basic_substring< C >::replace_all().

◆ sub() [1/2]

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

return [first,len[

Definition at line 322 of file substr.hpp.

323  {
324  C4_ASSERT(first >= 0 && first <= len);
325  return basic_substring(str + first, len - first);
326  }
constexpr basic_substring() noexcept
Definition: substr.hpp:117
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
Definition: substr.hpp:349

Referenced by c4::basic_substring< C >::pair_range().

◆ 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 329 of file substr.hpp.

330  {
331  C4_ASSERT(first >= 0 && first <= len);
332  C4_ASSERT((num >= 0 && num <= len) || (num == npos));
333  size_t rnum = num != npos ? num : len - first;
334  C4_ASSERT((first >= 0 && first + rnum <= len) || (num == 0));
335  return basic_substring(str + first, rnum);
336  }

References c4::yml::npos.

◆ 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 339 of file substr.hpp.

340  {
341  C4_ASSERT(first >= 0 && first <= len);
342  last = last != npos ? last : len;
343  C4_ASSERT(first <= last);
344  C4_ASSERT(last >= 0 && last <= len);
345  return basic_substring(str + first, last - first);
346  }
basic_substring last(size_t num) const noexcept
return the last num elements: [len-num,len[
Definition: substr.hpp:356

References c4::yml::npos.

◆ first()

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

return the first num elements: [0,num[

Definition at line 349 of file substr.hpp.

350  {
351  C4_ASSERT(num <= len || num == npos);
352  return basic_substring(str, num != npos ? num : len);
353  }

References c4::yml::npos.

◆ 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 356 of file substr.hpp.

357  {
358  C4_ASSERT(num <= len || num == npos);
359  return num != npos ?
360  basic_substring(str + len - num, num) :
361  *this;
362  }

References c4::yml::npos.

◆ 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 367 of file substr.hpp.

368  {
369  C4_ASSERT(left >= 0 && left <= len);
370  C4_ASSERT(right >= 0 && right <= len);
371  C4_ASSERT(left <= len - right + 1);
372  return basic_substring(str + left, len - right - left);
373  }
left_< T > left(T val, size_t width, char padchar=' ')
mark an argument to be aligned left
Definition: format.hpp:515
right_< T > right(T val, size_t width, char padchar=' ')
mark an argument to be aligned right
Definition: format.hpp:522

References c4::fmt::left(), and c4::fmt::right().

◆ 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 376 of file substr.hpp.

377  {
378  C4_ASSERT(pos <= len || pos == npos);
379  return (pos != npos) ?
380  basic_substring(str, pos) :
381  *this;
382  }

References c4::yml::npos.

◆ 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 385 of file substr.hpp.

386  {
387  C4_ASSERT(pos <= len || pos == npos);
388  return (pos != npos) ?
389  basic_substring(str, pos+include_pos) :
390  *this;
391  }

References c4::yml::npos.

◆ 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 394 of file substr.hpp.

395  {
396  C4_ASSERT(pos <= len || pos == npos);
397  return (pos != npos) ?
398  basic_substring(str + (pos + 1), len - (pos + 1)) :
399  basic_substring(str + len, size_t(0));
400  }

References c4::yml::npos.

◆ 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 403 of file substr.hpp.

404  {
405  C4_ASSERT(pos <= len || pos == npos);
406  return (pos != npos) ?
407  basic_substring(str + (pos + !include_pos), len - (pos + !include_pos)) :
408  basic_substring(str + len, size_t(0));
409  }

References c4::yml::npos.

◆ 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 415 of file substr.hpp.

416  {
417  C4_ASSERT(is_super(subs) || subs.empty());
418  auto ssb = subs.begin();
419  auto b = begin();
420  auto e = end();
421  if(ssb >= b && ssb <= e)
422  return sub(0, static_cast<size_t>(ssb - b));
423  else
424  return sub(0, 0);
425  }
iterator begin() noexcept
Definition: substr.hpp:203
iterator end() noexcept
Definition: substr.hpp:204
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition: substr.hpp:322
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:304

◆ 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 429 of file substr.hpp.

430  {
431  C4_ASSERT(is_super(subs) || subs.empty());
432  auto sse = subs.end();
433  auto b = begin();
434  auto e = end();
435  if(sse >= b && sse <= e)
436  return sub(static_cast<size_t>(sse - b), static_cast<size_t>(e - sse));
437  else
438  return sub(0, 0);
439  }

◆ triml() [1/2]

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

trim left

Definition at line 449 of file substr.hpp.

450  {
451  if( ! empty())
452  {
453  size_t pos = first_not_of(c);
454  if(pos != npos)
455  return sub(pos);
456  }
457  return sub(0, 0);
458  }
size_t first_not_of(const C c) const
Definition: substr.hpp:845

References c4::yml::npos.

◆ 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 461 of file substr.hpp.

462  {
463  if( ! empty())
464  {
465  size_t pos = first_not_of(chars);
466  if(pos != npos)
467  return sub(pos);
468  }
469  return sub(0, 0);
470  }

References c4::yml::npos.

◆ 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 473 of file substr.hpp.

474  {
475  if( ! empty())
476  {
477  size_t pos = last_not_of(c, npos);
478  if(pos != npos)
479  return sub(0, pos+1);
480  }
481  return sub(0, 0);
482  }
size_t last_not_of(const C c) const
Definition: substr.hpp:866

References c4::yml::npos.

Referenced by c4::basic_substring< C >::trim().

◆ 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 485 of file substr.hpp.

486  {
487  if( ! empty())
488  {
489  size_t pos = last_not_of(chars, npos);
490  if(pos != npos)
491  return sub(0, pos+1);
492  }
493  return sub(0, 0);
494  }

References c4::yml::npos.

◆ 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 497 of file substr.hpp.

498  {
499  return triml(c).trimr(c);
500  }
basic_substring triml(const C c) const
trim left
Definition: substr.hpp:449
basic_substring trimr(const C c) const
trim the character c from the right
Definition: substr.hpp:473

References c4::basic_substring< C >::trimr().

◆ 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 503 of file substr.hpp.

504  {
505  return triml(chars).trimr(chars);
506  }

References c4::basic_substring< C >::trimr().

◆ 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 510 of file substr.hpp.

511  {
512  if( ! begins_with(pattern))
513  return *this;
514  return sub(pattern.len < len ? pattern.len : len);
515  }
bool begins_with(const C c) const
true if the first character of the string is c
Definition: substr.hpp:670

References c4::basic_substring< C >::len.

◆ 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 519 of file substr.hpp.

520  {
521  if( ! ends_with(pattern))
522  return *this;
523  return left_of(len - (pattern.len < len ? pattern.len : len));
524  }
bool ends_with(const C c) const
true if the last character of the string is c
Definition: substr.hpp:727
basic_substring left_of(size_t pos) const noexcept
return [0, pos[ .
Definition: substr.hpp:376

References c4::basic_substring< C >::len.

◆ 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 533 of file substr.hpp.

534  {
535  return first_of(c, start_pos);
536  }
size_t first_of(const C c, size_t start=0) const
Definition: substr.hpp:786

Referenced by c4::basic_substring< C >::pair_range().

◆ 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 537 of file substr.hpp.

538  {
539  C4_ASSERT(start_pos == npos || (start_pos >= 0 && start_pos <= len));
540  if(len < pattern.len) return npos;
541  for(size_t i = start_pos, e = len - pattern.len + 1; i < e; ++i)
542  {
543  bool gotit = true;
544  for(size_t j = 0; j < pattern.len; ++j)
545  {
546  C4_ASSERT(i + j < len);
547  if(str[i + j] != pattern.str[j])
548  {
549  gotit = false;
550  break;
551  }
552  }
553  if(gotit)
554  {
555  return i;
556  }
557  }
558  return npos;
559  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ 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 564 of file substr.hpp.

565  {
566  C4_ASSERT(pos >= 0 && pos <= len);
567  size_t num = 0;
568  pos = find(c, pos);
569  while(pos != npos)
570  {
571  ++num;
572  pos = find(c, pos + 1);
573  }
574  return num;
575  }
size_t find(const C c, size_t start_pos=0) const
Definition: substr.hpp:533

References c4::yml::npos.

◆ 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 578 of file substr.hpp.

579  {
580  C4_ASSERT(pos >= 0 && pos <= len);
581  size_t num = 0;
582  pos = find(c, pos);
583  while(pos != npos)
584  {
585  ++num;
586  pos = find(c, pos + c.len);
587  }
588  return num;
589  }

References c4::basic_substring< C >::len, and c4::yml::npos.

◆ 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 592 of file substr.hpp.

593  {
594  pos = find(c, pos);
595  return pos != npos ? sub(pos, 1) : basic_substring();
596  }

References c4::yml::npos.

◆ 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 599 of file substr.hpp.

600  {
601  pos = find(pattern, pos);
602  return pos != npos ? sub(pos, pattern.len) : basic_substring();
603  }

References c4::basic_substring< C >::len, and c4::yml::npos.

◆ 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 614 of file substr.hpp.

615  {
616  ro_substr s[2] = {s0, s1};
617  return first_of_any_iter(&s[0], &s[0] + 2);
618  }
first_of_any_result first_of_any_iter(It first_span, It last_span) const
Definition: substr.hpp:639

◆ 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 620 of file substr.hpp.

621  {
622  ro_substr s[3] = {s0, s1, s2};
623  return first_of_any_iter(&s[0], &s[0] + 3);
624  }

◆ 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 626 of file substr.hpp.

627  {
628  ro_substr s[4] = {s0, s1, s2, s3};
629  return first_of_any_iter(&s[0], &s[0] + 4);
630  }

◆ 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 632 of file substr.hpp.

633  {
634  ro_substr s[5] = {s0, s1, s2, s3, s4};
635  return first_of_any_iter(&s[0], &s[0] + 5);
636  }

◆ 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 639 of file substr.hpp.

640  {
641  for(size_t i = 0; i < len; ++i)
642  {
643  size_t curr = 0;
644  for(It it = first_span; it != last_span; ++curr, ++it)
645  {
646  auto const& chars = *it;
647  if((i + chars.len) > len) continue;
648  bool gotit = true;
649  for(size_t j = 0; j < chars.len; ++j)
650  {
651  C4_ASSERT(i + j < len);
652  if(str[i + j] != chars[j])
653  {
654  gotit = false;
655  break;
656  }
657  }
658  if(gotit)
659  {
660  return {curr, i};
661  }
662  }
663  }
664  return {NONE, npos};
665  }

References c4::yml::NONE, and c4::yml::npos.

◆ begins_with() [1/3]

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

true if the first character of the string is c

Definition at line 670 of file substr.hpp.

671  {
672  return len > 0 ? str[0] == c : false;
673  }

◆ begins_with() [2/3]

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

true if the first num characters of the string are c

Definition at line 676 of file substr.hpp.

677  {
678  if(len < num)
679  {
680  return false;
681  }
682  for(size_t i = 0; i < num; ++i)
683  {
684  if(str[i] != c)
685  {
686  return false;
687  }
688  }
689  return true;
690  }

◆ begins_with() [3/3]

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

true if the string begins with the given pattern

Definition at line 693 of file substr.hpp.

694  {
695  if(len < pattern.len)
696  {
697  return false;
698  }
699  for(size_t i = 0; i < pattern.len; ++i)
700  {
701  if(str[i] != pattern[i])
702  {
703  return false;
704  }
705  }
706  return true;
707  }

References c4::basic_substring< C >::len.

◆ begins_with_any()

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

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

Definition at line 710 of file substr.hpp.

711  {
712  if(len == 0)
713  {
714  return false;
715  }
716  for(size_t i = 0; i < chars.len; ++i)
717  {
718  if(str[0] == chars.str[i])
719  {
720  return true;
721  }
722  }
723  return false;
724  }

References c4::basic_substring< C >::len, and c4::basic_substring< C >::str.

◆ ends_with() [1/3]

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

true if the last character of the string is c

Definition at line 727 of file substr.hpp.

728  {
729  return len > 0 ? str[len-1] == c : false;
730  }

◆ ends_with() [2/3]

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

true if the last num characters of the string are c

Definition at line 733 of file substr.hpp.

734  {
735  if(len < num)
736  {
737  return false;
738  }
739  for(size_t i = len - num; i < len; ++i)
740  {
741  if(str[i] != c)
742  {
743  return false;
744  }
745  }
746  return true;
747  }

◆ ends_with() [3/3]

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

true if the string ends with the given pattern

Definition at line 750 of file substr.hpp.

751  {
752  if(len < pattern.len)
753  {
754  return false;
755  }
756  for(size_t i = 0, s = len-pattern.len; i < pattern.len; ++i)
757  {
758  if(str[s+i] != pattern[i])
759  {
760  return false;
761  }
762  }
763  return true;
764  }

References c4::basic_substring< C >::len.

◆ ends_with_any()

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

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

Definition at line 767 of file substr.hpp.

768  {
769  if(len == 0)
770  {
771  return false;
772  }
773  for(size_t i = 0; i < chars.len; ++i)
774  {
775  if(str[len - 1] == chars[i])
776  {
777  return true;
778  }
779  }
780  return false;
781  }

References c4::basic_substring< C >::len.

◆ 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 786 of file substr.hpp.

787  {
788  C4_ASSERT(start == npos || (start >= 0 && start <= len));
789  for(size_t i = start; i < len; ++i)
790  {
791  if(str[i] == c)
792  return i;
793  }
794  return npos;
795  }

References c4::yml::npos.

◆ 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 798 of file substr.hpp.

799  {
800  C4_ASSERT(start == npos || (start >= 0 && start <= len));
801  if(start == npos)
802  start = len;
803  for(size_t i = start-1; i != size_t(-1); --i)
804  {
805  if(str[i] == c)
806  return i;
807  }
808  return npos;
809  }

References c4::yml::npos.

◆ 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 812 of file substr.hpp.

813  {
814  C4_ASSERT(start == npos || (start >= 0 && start <= len));
815  for(size_t i = start; i < len; ++i)
816  {
817  for(size_t j = 0; j < chars.len; ++j)
818  {
819  if(str[i] == chars[j])
820  return i;
821  }
822  }
823  return npos;
824  }

References c4::basic_substring< C >::len, and c4::yml::npos.

◆ 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 827 of file substr.hpp.

828  {
829  C4_ASSERT(start == npos || (start >= 0 && start <= len));
830  if(start == npos)
831  start = len;
832  for(size_t i = start-1; i != size_t(-1); --i)
833  {
834  for(size_t j = 0; j < chars.len; ++j)
835  {
836  if(str[i] == chars[j])
837  return i;
838  }
839  }
840  return npos;
841  }

References c4::basic_substring< C >::len, and c4::yml::npos.

◆ 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 845 of file substr.hpp.

846  {
847  for(size_t i = 0; i < len; ++i)
848  {
849  if(str[i] != c)
850  return i;
851  }
852  return npos;
853  }

References c4::yml::npos.

◆ 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 855 of file substr.hpp.

856  {
857  C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
858  for(size_t i = start; i < len; ++i)
859  {
860  if(str[i] != c)
861  return i;
862  }
863  return npos;
864  }

References c4::yml::npos.

◆ 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 866 of file substr.hpp.

867  {
868  for(size_t i = len-1; i != size_t(-1); --i)
869  {
870  if(str[i] != c)
871  return i;
872  }
873  return npos;
874  }

References c4::yml::npos.

◆ 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 876 of file substr.hpp.

877  {
878  C4_ASSERT(start == npos || (start >= 0 && start <= len));
879  if(start == npos)
880  start = len;
881  for(size_t i = start-1; i != size_t(-1); --i)
882  {
883  if(str[i] != c)
884  return i;
885  }
886  return npos;
887  }

References c4::yml::npos.

◆ 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 889 of file substr.hpp.

890  {
891  for(size_t i = 0; i < len; ++i)
892  {
893  bool gotit = true;
894  for(size_t j = 0; j < chars.len; ++j)
895  {
896  if(str[i] == chars.str[j])
897  {
898  gotit = false;
899  break;
900  }
901  }
902  if(gotit)
903  {
904  return i;
905  }
906  }
907  return npos;
908  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ 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 910 of file substr.hpp.

911  {
912  C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
913  for(size_t i = start; i < len; ++i)
914  {
915  bool gotit = true;
916  for(size_t j = 0; j < chars.len; ++j)
917  {
918  if(str[i] == chars.str[j])
919  {
920  gotit = false;
921  break;
922  }
923  }
924  if(gotit)
925  {
926  return i;
927  }
928  }
929  return npos;
930  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ 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 932 of file substr.hpp.

933  {
934  for(size_t i = len-1; i != size_t(-1); --i)
935  {
936  bool gotit = true;
937  for(size_t j = 0; j < chars.len; ++j)
938  {
939  if(str[i] == chars.str[j])
940  {
941  gotit = false;
942  break;
943  }
944  }
945  if(gotit)
946  {
947  return i;
948  }
949  }
950  return npos;
951  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ 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 953 of file substr.hpp.

954  {
955  C4_ASSERT(start == npos || (start >= 0 && start <= len));
956  if(start == npos)
957  start = len;
958  for(size_t i = start-1; i != size_t(-1); --i)
959  {
960  bool gotit = true;
961  for(size_t j = 0; j < chars.len; ++j)
962  {
963  if(str[i] == chars.str[j])
964  {
965  gotit = false;
966  break;
967  }
968  }
969  if(gotit)
970  {
971  return i;
972  }
973  }
974  return npos;
975  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ 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 987 of file substr.hpp.

988  {
989  size_t b = find(open);
990  if(b == npos)
991  return basic_substring();
992  size_t e = find(close, b+1);
993  if(e == npos)
994  return basic_substring();
995  basic_substring ret = range(b, e+1);
996  C4_ASSERT(ret.sub(1).find(open) == npos);
997  return ret;
998  }
basic_substring range(size_t first, size_t last=npos) const noexcept
return [first,last[.
Definition: substr.hpp:339

References c4::basic_substring< C >::find(), c4::yml::npos, and c4::basic_substring< C >::sub().

◆ 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 1002 of file substr.hpp.

1003  {
1004  size_t b = find(open_close);
1005  if(b == npos) return basic_substring();
1006  for(size_t i = b+1; i < len; ++i)
1007  {
1008  CC c = str[i];
1009  if(c == open_close)
1010  {
1011  if(str[i-1] != escape)
1012  {
1013  return range(b, i+1);
1014  }
1015  }
1016  }
1017  return basic_substring();
1018  }
typename std::add_const< C >::type CC
CC=const char.
Definition: substr.hpp:89

References c4::yml::npos.

◆ 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 1023 of file substr.hpp.

1024  {
1025  size_t b = find(open);
1026  if(b == npos) return basic_substring();
1027  size_t e, curr = b+1, count = 0;
1028  const char both[] = {open, close, '\0'};
1029  while((e = first_of(both, curr)) != npos)
1030  {
1031  if(str[e] == open)
1032  {
1033  ++count;
1034  curr = e+1;
1035  }
1036  else if(str[e] == close)
1037  {
1038  if(count == 0) return range(b, e+1);
1039  --count;
1040  curr = e+1;
1041  }
1042  }
1043  return basic_substring();
1044  }
size_t count(const C c, size_t pos=0) const
count the number of occurrences of c
Definition: substr.hpp:564

References c4::yml::npos.

◆ unquoted()

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

Definition at line 1046 of file substr.hpp.

1047  {
1048  constexpr const C dq('"'), sq('\'');
1049  if(len >= 2 && (str[len - 2] != C('\\')) &&
1050  ((begins_with(sq) && ends_with(sq))
1051  ||
1052  (begins_with(dq) && ends_with(dq))))
1053  {
1054  return range(1, len -1);
1055  }
1056  return *this;
1057  }

◆ 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 1068 of file substr.hpp.

1069  {
1070  if(empty() || (first_non_empty_span().empty()))
1071  return false;
1072  if(first_uint_span() == *this)
1073  return true;
1074  if(first_int_span() == *this)
1075  return true;
1076  if(first_real_span() == *this)
1077  return true;
1078  return false;
1079  }
basic_substring first_uint_span() const
get the first span which can be interpreted as an unsigned integer
Definition: substr.hpp:1129
basic_substring first_real_span() const
get the first span which can be interpreted as a real (floating-point) number
Definition: substr.hpp:1216
basic_substring first_int_span() const
get the first span which can be interpreted as a signed integer
Definition: substr.hpp:1141
basic_substring first_non_empty_span() const
get the first span consisting exclusively of non-empty characters
Definition: substr.hpp:1117

◆ 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 1083 of file substr.hpp.

1084  {
1085  if(empty() || (first_non_empty_span().empty()))
1086  return false;
1087  if(first_real_span() == *this)
1088  return true;
1089  return false;
1090  }

◆ 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 1094 of file substr.hpp.

1095  {
1096  if(empty() || (first_non_empty_span().empty()))
1097  return false;
1098  if(first_uint_span() == *this)
1099  return true;
1100  if(first_int_span() == *this)
1101  return true;
1102  return false;
1103  }

◆ 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 1107 of file substr.hpp.

1108  {
1109  if(empty() || (first_non_empty_span().empty()))
1110  return false;
1111  if(first_uint_span() == *this)
1112  return true;
1113  return false;
1114  }

◆ 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 1117 of file substr.hpp.

1118  {
1119  constexpr const ro_substr empty_chars(" \n\r\t");
1120  size_t pos = first_not_of(empty_chars);
1121  if(pos == npos)
1122  return first(0);
1123  auto ret = sub(pos);
1124  pos = ret.first_of(empty_chars);
1125  return ret.first(pos);
1126  }

References c4::yml::npos.

◆ 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 1129 of file substr.hpp.

1130  {
1132  if(ne.empty())
1133  return ne;
1134  if(ne.str[0] == '-')
1135  return first(0);
1136  size_t skip_start = size_t(ne.str[0] == '+');
1137  return ne._first_integral_span(skip_start);
1138  }

References c4::basic_substring< C >::_first_integral_span(), c4::basic_substring< C >::empty(), and c4::basic_substring< C >::str.

◆ 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 1141 of file substr.hpp.

1142  {
1144  if(ne.empty())
1145  return ne;
1146  size_t skip_start = size_t(ne.str[0] == '+' || ne.str[0] == '-');
1147  return ne._first_integral_span(skip_start);
1148  }

References c4::basic_substring< C >::_first_integral_span(), c4::basic_substring< C >::empty(), and c4::basic_substring< C >::str.

◆ _first_integral_span()

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

Definition at line 1150 of file substr.hpp.

1151  {
1152  C4_ASSERT(!empty());
1153  if(skip_start == len)
1154  return first(0);
1155  C4_ASSERT(skip_start < len);
1156  if(len >= skip_start + 3)
1157  {
1158  if(str[skip_start] != '0')
1159  {
1160  for(size_t i = skip_start; i < len; ++i)
1161  {
1162  char c = str[i];
1163  if(c < '0' || c > '9')
1164  return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1165  }
1166  }
1167  else
1168  {
1169  char next = str[skip_start + 1];
1170  if(next == 'x' || next == 'X')
1171  {
1172  skip_start += 2;
1173  for(size_t i = skip_start; i < len; ++i)
1174  {
1175  const char c = str[i];
1176  if( ! _is_hex_char(c))
1177  return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1178  }
1179  return *this;
1180  }
1181  else if(next == 'b' || next == 'B')
1182  {
1183  skip_start += 2;
1184  for(size_t i = skip_start; i < len; ++i)
1185  {
1186  const char c = str[i];
1187  if(c != '0' && c != '1')
1188  return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1189  }
1190  return *this;
1191  }
1192  else if(next == 'o' || next == 'O')
1193  {
1194  skip_start += 2;
1195  for(size_t i = skip_start; i < len; ++i)
1196  {
1197  const char c = str[i];
1198  if(c < '0' || c > '7')
1199  return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1200  }
1201  return *this;
1202  }
1203  }
1204  }
1205  // must be a decimal, or it is not a an number
1206  for(size_t i = skip_start; i < len; ++i)
1207  {
1208  const char c = str[i];
1209  if(c < '0' || c > '9')
1210  return i > skip_start && _is_delim_char(c) ? first(i) : first(0);
1211  }
1212  return *this;
1213  }
static constexpr C4_CONST bool _is_hex_char(char c) noexcept
true if the character is in [0-9a-fA-F]
Definition: substr.hpp:1279
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:1271

Referenced by c4::basic_substring< C >::first_int_span(), and c4::basic_substring< C >::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 1216 of file substr.hpp.

1217  {
1219  if(ne.empty())
1220  return ne;
1221  const size_t skip_start = (ne.str[0] == '+' || ne.str[0] == '-');
1222  C4_ASSERT(skip_start == 0 || skip_start == 1);
1223  // if we have at least three digits after the leading sign, it
1224  // can be decimal, or hex, or bin or oct. Ex:
1225  // non-decimal: 0x0, 0b0, 0o0
1226  // decimal: 1.0, 10., 1e1, 100, inf, nan, infinity
1227  if(ne.len >= skip_start+3)
1228  {
1229  // if it does not have leading 0, it must be decimal, or it is not a real
1230  if(ne.str[skip_start] != '0')
1231  {
1232  if(ne.str[skip_start] == 'i') // is it infinity or inf?
1233  {
1234  basic_substring word = ne._word_follows(skip_start + 1, "nfinity");
1235  if(word.len)
1236  return word;
1237  return ne._word_follows(skip_start + 1, "nf");
1238  }
1239  else if(ne.str[skip_start] == 'n') // is it nan?
1240  {
1241  return ne._word_follows(skip_start + 1, "an");
1242  }
1243  else // must be a decimal, or it is not a real
1244  {
1245  return ne._first_real_span_dec(skip_start);
1246  }
1247  }
1248  else // starts with 0. is it 0x, 0b or 0o?
1249  {
1250  const char next = ne.str[skip_start + 1];
1251  // hexadecimal
1252  if(next == 'x' || next == 'X')
1253  return ne._first_real_span_hex(skip_start + 2);
1254  // binary
1255  else if(next == 'b' || next == 'B')
1256  return ne._first_real_span_bin(skip_start + 2);
1257  // octal
1258  else if(next == 'o' || next == 'O')
1259  return ne._first_real_span_oct(skip_start + 2);
1260  // none of the above. may still be a decimal.
1261  else
1262  return ne._first_real_span_dec(skip_start); // do not skip the 0.
1263  }
1264  }
1265  // less than 3 chars after the leading sign. It is either a
1266  // decimal or it is not a real. (cannot be any of 0x0, etc).
1267  return ne._first_real_span_dec(skip_start);
1268  }

References c4::basic_substring< C >::_first_real_span_bin(), c4::basic_substring< C >::_first_real_span_dec(), c4::basic_substring< C >::_first_real_span_hex(), c4::basic_substring< C >::_first_real_span_oct(), c4::basic_substring< C >::_word_follows(), c4::basic_substring< C >::empty(), c4::basic_substring< C >::len, and c4::basic_substring< C >::str.

◆ _is_delim_char()

template<class C >
static 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 1271 of file substr.hpp.

1272  {
1273  return c == ' ' || c == '\n'
1274  || c == ']' || c == ')' || c == '}'
1275  || c == ',' || c == ';' || c == '\r' || c == '\t' || c == '\0';
1276  }

◆ _is_hex_char()

template<class C >
static 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 1279 of file substr.hpp.

1280  {
1281  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
1282  }

◆ _word_follows()

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

Definition at line 1284 of file substr.hpp.

1285  {
1286  size_t posend = pos + word.len;
1287  if(len >= posend && sub(pos, word.len) == word)
1288  if(len == posend || _is_delim_char(str[posend]))
1289  return first(posend);
1290  return first(0);
1291  }

References c4::basic_substring< C >::len.

Referenced by c4::basic_substring< C >::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 1294 of file substr.hpp.

1295  {
1296  bool intchars = false;
1297  bool fracchars = false;
1298  bool powchars;
1299  // integral part
1300  for( ; pos < len; ++pos)
1301  {
1302  const char c = str[pos];
1303  if(c >= '0' && c <= '9')
1304  {
1305  intchars = true;
1306  }
1307  else if(c == '.')
1308  {
1309  ++pos;
1310  goto fractional_part_dec;
1311  }
1312  else if(c == 'e' || c == 'E')
1313  {
1314  ++pos;
1315  goto power_part_dec;
1316  }
1317  else if(_is_delim_char(c))
1318  {
1319  return intchars ? first(pos) : first(0);
1320  }
1321  else
1322  {
1323  return first(0);
1324  }
1325  }
1326  // no . or p were found; this is either an integral number
1327  // or not a number at all
1328  return intchars ?
1329  *this :
1330  first(0);
1331  fractional_part_dec:
1332  C4_ASSERT(pos > 0);
1333  C4_ASSERT(str[pos - 1] == '.');
1334  for( ; pos < len; ++pos)
1335  {
1336  const char c = str[pos];
1337  if(c >= '0' && c <= '9')
1338  {
1339  fracchars = true;
1340  }
1341  else if(c == 'e' || c == 'E')
1342  {
1343  ++pos;
1344  goto power_part_dec;
1345  }
1346  else if(_is_delim_char(c))
1347  {
1348  return intchars || fracchars ? first(pos) : first(0);
1349  }
1350  else
1351  {
1352  return first(0);
1353  }
1354  }
1355  return intchars || fracchars ?
1356  *this :
1357  first(0);
1358  power_part_dec:
1359  C4_ASSERT(pos > 0);
1360  C4_ASSERT(str[pos - 1] == 'e' || str[pos - 1] == 'E');
1361  // either digits, or +, or - are expected here, followed by more digits.
1362  if((len == pos) || ((!intchars) && (!fracchars)))
1363  return first(0);
1364  if(str[pos] == '-' || str[pos] == '+')
1365  ++pos; // skip the sign
1366  powchars = false;
1367  for( ; pos < len; ++pos)
1368  {
1369  const char c = str[pos];
1370  if(c >= '0' && c <= '9')
1371  powchars = true;
1372  else if(powchars && _is_delim_char(c))
1373  return first(pos);
1374  else
1375  return first(0);
1376  }
1377  return powchars ? *this : first(0);
1378  }

Referenced by c4::basic_substring< C >::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 1381 of file substr.hpp.

1382  {
1383  bool intchars = false;
1384  bool fracchars = false;
1385  bool powchars;
1386  // integral part
1387  for( ; pos < len; ++pos)
1388  {
1389  const char c = str[pos];
1390  if(_is_hex_char(c))
1391  {
1392  intchars = true;
1393  }
1394  else if(c == '.')
1395  {
1396  ++pos;
1397  goto fractional_part_hex;
1398  }
1399  else if(c == 'p' || c == 'P')
1400  {
1401  ++pos;
1402  goto power_part_hex;
1403  }
1404  else if(_is_delim_char(c))
1405  {
1406  return intchars ? first(pos) : first(0);
1407  }
1408  else
1409  {
1410  return first(0);
1411  }
1412  }
1413  // no . or p were found; this is either an integral number
1414  // or not a number at all
1415  return intchars ?
1416  *this :
1417  first(0);
1418  fractional_part_hex:
1419  C4_ASSERT(pos > 0);
1420  C4_ASSERT(str[pos - 1] == '.');
1421  for( ; pos < len; ++pos)
1422  {
1423  const char c = str[pos];
1424  if(_is_hex_char(c))
1425  {
1426  fracchars = true;
1427  }
1428  else if(c == 'p' || c == 'P')
1429  {
1430  ++pos;
1431  goto power_part_hex;
1432  }
1433  else if(_is_delim_char(c))
1434  {
1435  return intchars || fracchars ? first(pos) : first(0);
1436  }
1437  else
1438  {
1439  return first(0);
1440  }
1441  }
1442  return intchars || fracchars ?
1443  *this :
1444  first(0);
1445  power_part_hex:
1446  C4_ASSERT(pos > 0);
1447  C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1448  // either a + or a - is expected here, followed by more chars.
1449  // also, using (pos+1) in this check will cause an early
1450  // return when no more chars follow the sign.
1451  if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1452  return first(0);
1453  ++pos; // this was the sign.
1454  // ... so the (pos+1) ensures that we enter the loop and
1455  // hence that there exist chars in the power part
1456  powchars = false;
1457  for( ; pos < len; ++pos)
1458  {
1459  const char c = str[pos];
1460  if(c >= '0' && c <= '9')
1461  powchars = true;
1462  else if(powchars && _is_delim_char(c))
1463  return first(pos);
1464  else
1465  return first(0);
1466  }
1467  return *this;
1468  }

Referenced by c4::basic_substring< C >::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 1471 of file substr.hpp.

1472  {
1473  bool intchars = false;
1474  bool fracchars = false;
1475  bool powchars;
1476  // integral part
1477  for( ; pos < len; ++pos)
1478  {
1479  const char c = str[pos];
1480  if(c == '0' || c == '1')
1481  {
1482  intchars = true;
1483  }
1484  else if(c == '.')
1485  {
1486  ++pos;
1487  goto fractional_part_bin;
1488  }
1489  else if(c == 'p' || c == 'P')
1490  {
1491  ++pos;
1492  goto power_part_bin;
1493  }
1494  else if(_is_delim_char(c))
1495  {
1496  return intchars ? first(pos) : first(0);
1497  }
1498  else
1499  {
1500  return first(0);
1501  }
1502  }
1503  // no . or p were found; this is either an integral number
1504  // or not a number at all
1505  return intchars ?
1506  *this :
1507  first(0);
1508  fractional_part_bin:
1509  C4_ASSERT(pos > 0);
1510  C4_ASSERT(str[pos - 1] == '.');
1511  for( ; pos < len; ++pos)
1512  {
1513  const char c = str[pos];
1514  if(c == '0' || c == '1')
1515  {
1516  fracchars = true;
1517  }
1518  else if(c == 'p' || c == 'P')
1519  {
1520  ++pos;
1521  goto power_part_bin;
1522  }
1523  else if(_is_delim_char(c))
1524  {
1525  return intchars || fracchars ? first(pos) : first(0);
1526  }
1527  else
1528  {
1529  return first(0);
1530  }
1531  }
1532  return intchars || fracchars ?
1533  *this :
1534  first(0);
1535  power_part_bin:
1536  C4_ASSERT(pos > 0);
1537  C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1538  // either a + or a - is expected here, followed by more chars.
1539  // also, using (pos+1) in this check will cause an early
1540  // return when no more chars follow the sign.
1541  if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1542  return first(0);
1543  ++pos; // this was the sign.
1544  // ... so the (pos+1) ensures that we enter the loop and
1545  // hence that there exist chars in the power part
1546  powchars = false;
1547  for( ; pos < len; ++pos)
1548  {
1549  const char c = str[pos];
1550  if(c >= '0' && c <= '9')
1551  powchars = true;
1552  else if(powchars && _is_delim_char(c))
1553  return first(pos);
1554  else
1555  return first(0);
1556  }
1557  return *this;
1558  }

Referenced by c4::basic_substring< C >::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 1561 of file substr.hpp.

1562  {
1563  bool intchars = false;
1564  bool fracchars = false;
1565  bool powchars;
1566  // integral part
1567  for( ; pos < len; ++pos)
1568  {
1569  const char c = str[pos];
1570  if(c >= '0' && c <= '7')
1571  {
1572  intchars = true;
1573  }
1574  else if(c == '.')
1575  {
1576  ++pos;
1577  goto fractional_part_oct;
1578  }
1579  else if(c == 'p' || c == 'P')
1580  {
1581  ++pos;
1582  goto power_part_oct;
1583  }
1584  else if(_is_delim_char(c))
1585  {
1586  return intchars ? first(pos) : first(0);
1587  }
1588  else
1589  {
1590  return first(0);
1591  }
1592  }
1593  // no . or p were found; this is either an integral number
1594  // or not a number at all
1595  return intchars ?
1596  *this :
1597  first(0);
1598  fractional_part_oct:
1599  C4_ASSERT(pos > 0);
1600  C4_ASSERT(str[pos - 1] == '.');
1601  for( ; pos < len; ++pos)
1602  {
1603  const char c = str[pos];
1604  if(c >= '0' && c <= '7')
1605  {
1606  fracchars = true;
1607  }
1608  else if(c == 'p' || c == 'P')
1609  {
1610  ++pos;
1611  goto power_part_oct;
1612  }
1613  else if(_is_delim_char(c))
1614  {
1615  return intchars || fracchars ? first(pos) : first(0);
1616  }
1617  else
1618  {
1619  return first(0);
1620  }
1621  }
1622  return intchars || fracchars ?
1623  *this :
1624  first(0);
1625  power_part_oct:
1626  C4_ASSERT(pos > 0);
1627  C4_ASSERT(str[pos - 1] == 'p' || str[pos - 1] == 'P');
1628  // either a + or a - is expected here, followed by more chars.
1629  // also, using (pos+1) in this check will cause an early
1630  // return when no more chars follow the sign.
1631  if(len <= (pos+1) || (str[pos] != '+' && str[pos] != '-') || ((!intchars) && (!fracchars)))
1632  return first(0);
1633  ++pos; // this was the sign.
1634  // ... so the (pos+1) ensures that we enter the loop and
1635  // hence that there exist chars in the power part
1636  powchars = false;
1637  for( ; pos < len; ++pos)
1638  {
1639  const char c = str[pos];
1640  if(c >= '0' && c <= '9')
1641  powchars = true;
1642  else if(powchars && _is_delim_char(c))
1643  return first(pos);
1644  else
1645  return first(0);
1646  }
1647  return *this;
1648  }

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

◆ next_split()

template<class C >
bool c4::basic_substring< C >::next_split ( 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 1661 of file substr.hpp.

1662  {
1663  if(C4_LIKELY(*start_pos < len))
1664  {
1665  for(size_t i = *start_pos; i < len; i++)
1666  {
1667  if(str[i] == sep)
1668  {
1669  out->assign(str + *start_pos, i - *start_pos);
1670  *start_pos = i+1;
1671  return true;
1672  }
1673  }
1674  out->assign(str + *start_pos, len - *start_pos);
1675  *start_pos = len + 1;
1676  return true;
1677  }
1678  else
1679  {
1680  bool valid = len > 0 && (*start_pos == len);
1681  if(valid && str && str[len-1] == sep)
1682  {
1683  out->assign(str + len, size_t(0)); // the cast is needed to prevent overload ambiguity
1684  }
1685  else
1686  {
1687  out->assign(str + len + 1, size_t(0)); // the cast is needed to prevent overload ambiguity
1688  }
1689  *start_pos = len + 1;
1690  return valid;
1691  }
1692  }

◆ split()

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

a view into the splits

Definition at line 1764 of file substr.hpp.

1765  {
1766  C4_XASSERT((start_pos >= 0 && start_pos < len) || empty());
1767  auto ss = sub(0, len);
1768  auto it = split_proxy(ss, start_pos, sep);
1769  return it;
1770  }
split_proxy_impl split_proxy
Definition: substr.hpp:1761

◆ pop_right()

template<class C >
basic_substring c4::basic_substring< C >::pop_right ( 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 1777 of file substr.hpp.

1778  {
1779  if(C4_LIKELY(len > 1))
1780  {
1781  auto pos = last_of(sep);
1782  if(pos != npos)
1783  {
1784  if(pos + 1 < len) // does not end with sep
1785  {
1786  return sub(pos + 1); // return from sep to end
1787  }
1788  else // the string ends with sep
1789  {
1790  if( ! skip_empty)
1791  {
1792  return sub(pos + 1, 0);
1793  }
1794  auto ppos = last_not_of(sep); // skip repeated seps
1795  if(ppos == npos) // the string is all made of seps
1796  {
1797  return sub(0, 0);
1798  }
1799  // find the previous sep
1800  auto pos0 = last_of(sep, ppos);
1801  if(pos0 == npos) // only the last sep exists
1802  {
1803  return sub(0); // return the full string (because skip_empty is true)
1804  }
1805  ++pos0;
1806  return sub(pos0);
1807  }
1808  }
1809  else // no sep was found, return the full string
1810  {
1811  return *this;
1812  }
1813  }
1814  else if(len == 1)
1815  {
1816  if(begins_with(sep))
1817  {
1818  return sub(0, 0);
1819  }
1820  return *this;
1821  }
1822  else // an empty string
1823  {
1824  return basic_substring();
1825  }
1826  }
size_t last_of(const C c, size_t start=npos) const
Definition: substr.hpp:798

References c4::yml::npos.

◆ pop_left()

template<class C >
basic_substring c4::basic_substring< C >::pop_left ( 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 1830 of file substr.hpp.

1831  {
1832  if(C4_LIKELY(len > 1))
1833  {
1834  auto pos = first_of(sep);
1835  if(pos != npos)
1836  {
1837  if(pos > 0) // does not start with sep
1838  {
1839  return sub(0, pos); // return everything up to it
1840  }
1841  else // the string starts with sep
1842  {
1843  if( ! skip_empty)
1844  {
1845  return sub(0, 0);
1846  }
1847  auto ppos = first_not_of(sep); // skip repeated seps
1848  if(ppos == npos) // the string is all made of seps
1849  {
1850  return sub(0, 0);
1851  }
1852  // find the next sep
1853  auto pos0 = first_of(sep, ppos);
1854  if(pos0 == npos) // only the first sep exists
1855  {
1856  return sub(0); // return the full string (because skip_empty is true)
1857  }
1858  C4_XASSERT(pos0 > 0);
1859  // return everything up to the second sep
1860  return sub(0, pos0);
1861  }
1862  }
1863  else // no sep was found, return the full string
1864  {
1865  return sub(0);
1866  }
1867  }
1868  else if(len == 1)
1869  {
1870  if(begins_with(sep))
1871  {
1872  return sub(0, 0);
1873  }
1874  return sub(0);
1875  }
1876  else // an empty string
1877  {
1878  return basic_substring();
1879  }
1880  }

References c4::yml::npos.

◆ gpop_left()

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

greedy pop left.

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

Definition at line 1885 of file substr.hpp.

1886  {
1887  auto ss = pop_right(sep, skip_empty);
1888  ss = left_of(ss);
1889  if(ss.find(sep) != npos)
1890  {
1891  if(ss.ends_with(sep))
1892  {
1893  if(skip_empty)
1894  {
1895  ss = ss.trimr(sep);
1896  }
1897  else
1898  {
1899  ss = ss.sub(0, ss.len-1); // safe to subtract because ends_with(sep) is true
1900  }
1901  }
1902  }
1903  return ss;
1904  }
basic_substring pop_right(C sep=C('/'), bool skip_empty=false) const
pop right: return the first split from the right.
Definition: substr.hpp:1777

References c4::yml::npos.

◆ gpop_right()

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

greedy pop right.

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

Definition at line 1907 of file substr.hpp.

1908  {
1909  auto ss = pop_left(sep, skip_empty);
1910  ss = right_of(ss);
1911  if(ss.find(sep) != npos)
1912  {
1913  if(ss.begins_with(sep))
1914  {
1915  if(skip_empty)
1916  {
1917  ss = ss.triml(sep);
1918  }
1919  else
1920  {
1921  ss = ss.sub(1);
1922  }
1923  }
1924  }
1925  return ss;
1926  }
basic_substring right_of(size_t pos) const noexcept
return [pos+1, len[
Definition: substr.hpp:394
basic_substring pop_left(C sep=C('/'), bool skip_empty=false) const
return the first split from the left.
Definition: substr.hpp:1830

References c4::yml::npos.

◆ basename()

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

Definition at line 1935 of file substr.hpp.

1936  {
1937  auto ss = pop_right(sep, /*skip_empty*/true);
1938  ss = ss.trimr(sep);
1939  return ss;
1940  }

◆ dirname()

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

Definition at line 1942 of file substr.hpp.

1943  {
1944  auto ss = basename(sep);
1945  ss = ss.empty() ? *this : left_of(ss);
1946  return ss;
1947  }
basic_substring basename(C sep=C('/')) const
Definition: substr.hpp:1935

◆ name_wo_extshort()

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

Definition at line 1949 of file substr.hpp.

1950  {
1951  return gpop_left('.');
1952  }
basic_substring gpop_left(C sep=C('/'), bool skip_empty=false) const
greedy pop left.
Definition: substr.hpp:1885

◆ name_wo_extlong()

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

Definition at line 1954 of file substr.hpp.

1955  {
1956  return pop_left('.');
1957  }

◆ extshort()

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

Definition at line 1959 of file substr.hpp.

1960  {
1961  return pop_right('.');
1962  }

◆ extlong()

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

Definition at line 1964 of file substr.hpp.

1965  {
1966  return gpop_right('.');
1967  }
basic_substring gpop_right(C sep=C('/'), bool skip_empty=false) const
greedy pop right.
Definition: substr.hpp:1907

◆ toupper()

template<class C >
void c4::basic_substring< C >::toupper ( )
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 1978 of file substr.hpp.

1979  {
1980  for(size_t i = 0; i < len; ++i)
1981  {
1982  str[i] = static_cast<C>(::toupper(str[i]));
1983  }
1984  }
void toupper()
convert the string to upper-case
Definition: substr.hpp:1978

◆ tolower()

template<class C >
void c4::basic_substring< C >::tolower ( )
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 1988 of file substr.hpp.

1989  {
1990  for(size_t i = 0; i < len; ++i)
1991  {
1992  str[i] = static_cast<C>(::tolower(str[i]));
1993  }
1994  }
void tolower()
convert the string to lower-case
Definition: substr.hpp:1988

◆ fill()

template<class C >
void c4::basic_substring< C >::fill ( val)
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 2000 of file substr.hpp.

2001  {
2002  for(size_t i = 0; i < len; ++i)
2003  {
2004  str[i] = val;
2005  }
2006  }

◆ copy_from()

template<class C >
void c4::basic_substring< C >::copy_from ( ro_substr  that,
size_t  ifirst = 0,
size_t  num = npos 
)
inline

set the current substring to a copy of the given csubstr

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

Definition at line 2012 of file substr.hpp.

2013  {
2014  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2015  num = num != npos ? num : len - ifirst;
2016  num = num < that.len ? num : that.len;
2017  C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2018  // calling memcpy with null strings is undefined behavior
2019  // and will wreak havoc in calling code's branches.
2020  // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2021  if(num)
2022  memcpy(str + sizeof(C) * ifirst, that.str, sizeof(C) * num);
2023  }

References c4::basic_substring< C >::len, c4::yml::npos, and c4::basic_substring< C >::str.

◆ reverse()

template<class C >
void c4::basic_substring< C >::reverse ( )
inline

reverse in place

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

Definition at line 2029 of file substr.hpp.

2030  {
2031  if(len == 0) return;
2032  detail::_do_reverse(str, str + len - 1);
2033  }

◆ reverse_sub()

template<class C >
void c4::basic_substring< C >::reverse_sub ( size_t  ifirst,
size_t  num 
)
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 2037 of file substr.hpp.

2038  {
2039  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2040  C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2041  if(num == 0) return;
2042  detail::_do_reverse(str + ifirst, str + ifirst + num - 1);
2043  }

◆ reverse_range()

template<class C >
void c4::basic_substring< C >::reverse_range ( size_t  ifirst,
size_t  ilast 
)
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 2047 of file substr.hpp.

2048  {
2049  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2050  C4_ASSERT(ilast >= 0 && ilast <= len);
2051  if(ifirst == ilast) return;
2052  detail::_do_reverse(str + ifirst, str + ilast - 1);
2053  }

◆ erase() [1/2]

template<class C >
basic_substring c4::basic_substring< C >::erase ( size_t  pos,
size_t  num 
)
inline

erase part of the string.

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

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

Definition at line 2060 of file substr.hpp.

2061  {
2062  C4_ASSERT(pos >= 0 && pos+num <= len);
2063  size_t num_to_move = len - pos - num;
2064  memmove(str + pos, str + pos + num, sizeof(C) * num_to_move);
2065  return basic_substring{str, len - num};
2066  }

◆ erase_range()

template<class C >
basic_substring c4::basic_substring< C >::erase_range ( size_t  first,
size_t  last 
)
inline
Note
this method requires that the string memory is writeable and is SFINAEd out for const C

Definition at line 2069 of file substr.hpp.

2070  {
2071  C4_ASSERT(first <= last);
2072  return erase(first, static_cast<size_t>(last-first));
2073  }
basic_substring erase(size_t pos, size_t num)
erase part of the string.
Definition: substr.hpp:2060

◆ erase() [2/2]

template<class C >
basic_substring c4::basic_substring< C >::erase ( ro_substr  sub)
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 2078 of file substr.hpp.

2079  {
2080  C4_ASSERT(is_super(sub));
2081  C4_ASSERT(sub.str >= str);
2082  return erase(static_cast<size_t>(sub.str - str), sub.len);
2083  }

References c4::basic_substring< C >::len, and c4::basic_substring< C >::str.

◆ replace() [1/2]

template<class C >
size_t c4::basic_substring< C >::replace ( value,
repl,
size_t  pos = 0 
)
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 2090 of file substr.hpp.

2091  {
2092  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2093  size_t did_it = 0;
2094  while((pos = find(value, pos)) != npos)
2095  {
2096  str[pos++] = repl;
2097  ++did_it;
2098  }
2099  return did_it;
2100  }

References c4::yml::npos.

◆ replace() [2/2]

template<class C >
size_t c4::basic_substring< C >::replace ( ro_substr  chars,
repl,
size_t  pos = 0 
)
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 2106 of file substr.hpp.

2107  {
2108  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2109  size_t did_it = 0;
2110  while((pos = first_of(chars, pos)) != npos)
2111  {
2112  str[pos++] = repl;
2113  ++did_it;
2114  }
2115  return did_it;
2116  }

References c4::yml::npos.

◆ 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 2124 of file substr.hpp.

2125  {
2126  C4_ASSERT( ! pattern.empty()); //!< @todo relax this precondition
2127  C4_ASSERT( ! this ->overlaps(dst)); //!< @todo relax this precondition
2128  C4_ASSERT( ! pattern.overlaps(dst));
2129  C4_ASSERT( ! repl .overlaps(dst));
2130  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2131  C4_SUPPRESS_WARNING_GCC_PUSH
2132  C4_SUPPRESS_WARNING_GCC("-Warray-bounds") // gcc11 has a false positive here
2133  #if (!defined(__clang__)) && (defined(__GNUC__) && (__GNUC__ >= 7))
2134  C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow") // gcc11 has a false positive here
2135  #endif
2136  #define _c4append(first, last) \
2137  { \
2138  C4_ASSERT((last) >= (first)); \
2139  size_t num = static_cast<size_t>((last) - (first)); \
2140  if(num > 0 && sz + num <= dst.len) \
2141  { \
2142  memcpy(dst.str + sz, first, num * sizeof(C)); \
2143  } \
2144  sz += num; \
2145  }
2146  size_t sz = 0;
2147  size_t b = pos;
2148  _c4append(str, str + pos);
2149  do {
2150  size_t e = find(pattern, b);
2151  if(e == npos)
2152  {
2153  _c4append(str + b, str + len);
2154  break;
2155  }
2156  _c4append(str + b, str + e);
2157  _c4append(repl.begin(), repl.end());
2158  b = e + pattern.size();
2159  } while(b < len && b != npos);
2160  return sz;
2161  #undef _c4append
2162  C4_SUPPRESS_WARNING_GCC_POP
2163  }
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:313
#define _c4append(first, last)

References _c4append, c4::basic_substring< C >::begin(), c4::basic_substring< C >::empty(), c4::basic_substring< C >::end(), c4::yml::npos, c4::basic_substring< C >::overlaps(), and c4::basic_substring< C >::size().

Member Data Documentation

◆ str

◆ len


The documentation for this struct was generated from the following file: