rapidyaml  0.12.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 (C const *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)
 copy a string to this substr, starting at 0 More...
 
void copy_from (ro_substr that, size_t ifirst, size_t num=npos)
 copy a string to this substr, starting at a specified given position 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.

Definition at line 73 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 87 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 88 of file substr.hpp.

◆ ro_substr

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

Definition at line 90 of file substr.hpp.

◆ rw_substr

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

Definition at line 91 of file substr.hpp.

◆ char_type

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

Definition at line 93 of file substr.hpp.

◆ size_type

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

Definition at line 94 of file substr.hpp.

◆ iterator

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

Definition at line 96 of file substr.hpp.

◆ const_iterator

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

Definition at line 97 of file substr.hpp.

◆ split_proxy

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

Definition at line 1771 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

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

Definition at line 99 of file substr.hpp.

99 : 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 115 of file substr.hpp.

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

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

119 : 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 138 of file substr.hpp.

138 : 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 141 of file substr.hpp.

141 : 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 145 of file substr.hpp.

145 : 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 153 of file substr.hpp.

153 : 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 103 of file substr.hpp.

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

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

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

◆ clear()

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

Definition at line 125 of file substr.hpp.

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

159 { 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 162 of file substr.hpp.

162 { 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 166 of file substr.hpp.

166 { 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 174 of file substr.hpp.

174 { 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 179 of file substr.hpp.

179 { 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 187 of file substr.hpp.

187 { 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 196 of file substr.hpp.

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

◆ empty()

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

Definition at line 197 of file substr.hpp.

197 { return (len == 0 || str == nullptr); }

◆ not_empty()

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

Definition at line 198 of file substr.hpp.

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

◆ size()

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

Definition at line 199 of file substr.hpp.

199 { return len; }

◆ begin() [1/2]

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

Definition at line 201 of file substr.hpp.

201 { return str; }

◆ end() [1/2]

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

Definition at line 202 of file substr.hpp.

202 { return str + len; }

◆ begin() [2/2]

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

Definition at line 204 of file substr.hpp.

204 { return str; }

◆ end() [2/2]

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

Definition at line 205 of file substr.hpp.

205 { return str + len; }

◆ data() [1/2]

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

Definition at line 207 of file substr.hpp.

207 { return str; }

◆ data() [2/2]

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

Definition at line 208 of file substr.hpp.

208 { return str; }

◆ operator[]() [1/2]

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

Definition at line 210 of file substr.hpp.

210 { 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 211 of file substr.hpp.

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

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

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

◆ back() [1/2]

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

Definition at line 216 of file substr.hpp.

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

217 { 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 226 of file substr.hpp.

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

◆ compare() [2/3]

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

Definition at line 235 of file substr.hpp.

236  {
237  #if defined(__GNUC__) && (__GNUC__ >= 6)
238  C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wnull-dereference")
239  #endif
240  C4_XASSERT(that || sz == 0);
241  C4_XASSERT(str || len == 0);
242  if(C4_LIKELY(str && that))
243  {
244  {
245  const size_t min = len < sz ? len : sz;
246  for(size_t i = 0; i < min; ++i)
247  if(str[i] != that[i])
248  return str[i] < that[i] ? -1 : 1;
249  }
250  if(len < sz)
251  return -1;
252  else if(len == sz)
253  return 0;
254  else
255  return 1;
256  }
257  else if(len == sz)
258  {
259  C4_XASSERT(len == 0 && sz == 0);
260  return 0;
261  }
262  return len < sz ? -1 : 1;
263  #if defined(__GNUC__) && (__GNUC__ >= 6)
264  C4_SUPPRESS_WARNING_GCC_POP
265  #endif
266  }

◆ compare() [3/3]

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

Definition at line 268 of file substr.hpp.

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

References 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 270 of file substr.hpp.

270 { return str == nullptr; }

◆ operator!=() [1/4]

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

Definition at line 271 of file substr.hpp.

271 { return str != nullptr; }

◆ operator==() [2/4]

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!=() [2/4]

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<() [1/3]

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

Definition at line 275 of file substr.hpp.

275 { 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 276 of file substr.hpp.

276 { 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 277 of file substr.hpp.

277 { 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 278 of file substr.hpp.

278 { 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 280 of file substr.hpp.

280 { 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 281 of file substr.hpp.

281 { 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 282 of file substr.hpp.

282 { 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 283 of file substr.hpp.

283 { 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 284 of file substr.hpp.

284 { 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 285 of file substr.hpp.

285 { 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 287 of file substr.hpp.

287 { 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 288 of file substr.hpp.

288 { 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 289 of file substr.hpp.

289 { 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 290 of file substr.hpp.

290 { 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 291 of file substr.hpp.

291 { 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 292 of file substr.hpp.

292 { 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 302 of file substr.hpp.

303  {
304  return that.is_super(*this);
305  }

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

309  {
310  if(C4_LIKELY(len > 0))
311  return that.str >= str && that.str+that.len <= str+len;
312  else
313  return that.len == 0 && that.str == str && str != nullptr;
314  }

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

318  {
319  // thanks @timwynants
320  return that.str+that.len > str && that.str < str+len;
321  }

◆ sub() [1/2]

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

return [first,len[

Definition at line 326 of file substr.hpp.

327  {
328  C4_ASSERT(first >= 0 && first <= len);
329  return basic_substring(str + first, len - first);
330  }
constexpr basic_substring() noexcept
Definition: substr.hpp:115
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
Definition: substr.hpp:353

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

334  {
335  C4_ASSERT(first >= 0 && first <= len);
336  C4_ASSERT((num >= 0 && num <= len) || (num == npos));
337  size_t rnum = num != npos ? num : len - first;
338  C4_ASSERT((first >= 0 && first + rnum <= len) || (num == 0));
339  return basic_substring(str + first, rnum);
340  }

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

344  {
345  C4_ASSERT(first >= 0 && first <= len);
346  last = last != npos ? last : len;
347  C4_ASSERT(first <= last);
348  C4_ASSERT(last >= 0 && last <= len);
349  return basic_substring(str + first, last - first);
350  }
basic_substring last(size_t num) const noexcept
return the last num elements: [len-num,len[
Definition: substr.hpp:360

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

354  {
355  C4_ASSERT(num <= len || num == npos);
356  return basic_substring(str, num != npos ? num : len);
357  }

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

361  {
362  C4_ASSERT(num <= len || num == npos);
363  return num != npos ?
364  basic_substring(str + len - num, num) :
365  *this;
366  }

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

372  {
373  C4_ASSERT(left >= 0 && left <= len);
374  C4_ASSERT(right >= 0 && right <= len);
375  C4_ASSERT(left <= len - right + 1);
376  return basic_substring(str + left, len - right - left);
377  }
left_< T > left(T val, size_t width, char padchar=' ')
mark an argument to be aligned left
Definition: format.hpp:525
right_< T > right(T val, size_t width, char padchar=' ')
mark an argument to be aligned right
Definition: format.hpp:532

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

381  {
382  C4_ASSERT(pos <= len || pos == npos);
383  return (pos != npos) ?
384  basic_substring(str, pos) :
385  *this;
386  }

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

390  {
391  C4_ASSERT(pos <= len || pos == npos);
392  return (pos != npos) ?
393  basic_substring(str, pos+include_pos) :
394  *this;
395  }

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

399  {
400  C4_ASSERT(pos <= len || pos == npos);
401  return (pos != npos) ?
402  basic_substring(str + (pos + 1), len - (pos + 1)) :
403  basic_substring(str + len, size_t(0));
404  }

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

408  {
409  C4_ASSERT(pos <= len || pos == npos);
410  return (pos != npos) ?
411  basic_substring(str + (pos + !include_pos), len - (pos + !include_pos)) :
412  basic_substring(str + len, size_t(0));
413  }

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

420  {
421  C4_ASSERT(is_super(subs) || subs.empty());
422  auto ssb = subs.begin();
423  auto b = begin();
424  auto e = end();
425  if(ssb >= b && ssb <= e)
426  return sub(0, static_cast<size_t>(ssb - b));
427  else
428  return sub(0, 0);
429  }
iterator begin() noexcept
Definition: substr.hpp:201
iterator end() noexcept
Definition: substr.hpp:202
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition: substr.hpp:326
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:308

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

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

◆ triml() [1/2]

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

trim left

Definition at line 453 of file substr.hpp.

454  {
455  if( ! empty())
456  {
457  size_t pos = first_not_of(c);
458  if(pos != npos)
459  return sub(pos);
460  }
461  return sub(0, 0);
462  }
size_t first_not_of(const C c) const
Definition: substr.hpp:855

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

466  {
467  if( ! empty())
468  {
469  size_t pos = first_not_of(chars);
470  if(pos != npos)
471  return sub(pos);
472  }
473  return sub(0, 0);
474  }

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

478  {
479  if( ! empty())
480  {
481  size_t pos = last_not_of(c, npos);
482  if(pos != npos)
483  return sub(0, pos+1);
484  }
485  return sub(0, 0);
486  }
size_t last_not_of(const C c) const
Definition: substr.hpp:876

References c4::yml::npos.

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

490  {
491  if( ! empty())
492  {
493  size_t pos = last_not_of(chars, npos);
494  if(pos != npos)
495  return sub(0, pos+1);
496  }
497  return sub(0, 0);
498  }

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

502  {
503  return triml(c).trimr(c);
504  }
basic_substring triml(const C c) const
trim left
Definition: substr.hpp:453
basic_substring trimr(const C c) const
trim the character c from the right
Definition: substr.hpp:477

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

508  {
509  return triml(chars).trimr(chars);
510  }

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

515  {
516  if( ! begins_with(pattern))
517  return *this;
518  return sub(pattern.len < len ? pattern.len : len);
519  }
bool begins_with(const C c) const
true if the first character of the string is c
Definition: substr.hpp:674

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

524  {
525  if( ! ends_with(pattern))
526  return *this;
527  return left_of(len - (pattern.len < len ? pattern.len : len));
528  }
bool ends_with(const C c) const
true if the last character of the string is c
Definition: substr.hpp:737
basic_substring left_of(size_t pos) const noexcept
return [0, pos[ .
Definition: substr.hpp:380

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

538  {
539  return first_of(c, start_pos);
540  }
size_t first_of(const C c, size_t start=0) const
Definition: substr.hpp:796

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

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

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

569  {
570  C4_ASSERT(pos >= 0 && pos <= len);
571  size_t num = 0;
572  pos = find(c, pos);
573  while(pos != npos)
574  {
575  ++num;
576  pos = find(c, pos + 1);
577  }
578  return num;
579  }
size_t find(const C c, size_t start_pos=0) const
Definition: substr.hpp:537

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

583  {
584  C4_ASSERT(pos >= 0 && pos <= len);
585  size_t num = 0;
586  pos = find(c, pos);
587  while(pos != npos)
588  {
589  ++num;
590  pos = find(c, pos + c.len);
591  }
592  return num;
593  }

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

597  {
598  pos = find(c, pos);
599  return pos != npos ? sub(pos, 1) : basic_substring();
600  }

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

604  {
605  pos = find(pattern, pos);
606  return pos != npos ? sub(pos, pattern.len) : basic_substring();
607  }

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

619  {
620  ro_substr s[2] = {s0, s1};
621  return first_of_any_iter(&s[0], &s[0] + 2);
622  }
first_of_any_result first_of_any_iter(It first_span, It last_span) const
Definition: substr.hpp:643

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

625  {
626  ro_substr s[3] = {s0, s1, s2};
627  return first_of_any_iter(&s[0], &s[0] + 3);
628  }

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

631  {
632  ro_substr s[4] = {s0, s1, s2, s3};
633  return first_of_any_iter(&s[0], &s[0] + 4);
634  }

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

637  {
638  ro_substr s[5] = {s0, s1, s2, s3, s4};
639  return first_of_any_iter(&s[0], &s[0] + 5);
640  }

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

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

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

675  {
676  #if defined(__GNUC__) && (__GNUC__ >= 6)
677  C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wnull-dereference")
678  #endif
679  return len > 0 ? str[0] == c : false;
680  #if defined(__GNUC__) && (__GNUC__ >= 6)
681  C4_SUPPRESS_WARNING_GCC_POP
682  #endif
683  }

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

687  {
688  if(len < num)
689  {
690  return false;
691  }
692  for(size_t i = 0; i < num; ++i)
693  {
694  if(str[i] != c)
695  {
696  return false;
697  }
698  }
699  return true;
700  }

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

704  {
705  if(len < pattern.len)
706  {
707  return false;
708  }
709  for(size_t i = 0; i < pattern.len; ++i)
710  {
711  if(str[i] != pattern[i])
712  {
713  return false;
714  }
715  }
716  return true;
717  }

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

721  {
722  if(len == 0)
723  {
724  return false;
725  }
726  for(size_t i = 0; i < chars.len; ++i)
727  {
728  if(str[0] == chars.str[i])
729  {
730  return true;
731  }
732  }
733  return false;
734  }

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

738  {
739  return len > 0 ? str[len-1] == c : false;
740  }

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

744  {
745  if(len < num)
746  {
747  return false;
748  }
749  for(size_t i = len - num; i < len; ++i)
750  {
751  if(str[i] != c)
752  {
753  return false;
754  }
755  }
756  return true;
757  }

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

761  {
762  if(len < pattern.len)
763  {
764  return false;
765  }
766  for(size_t i = 0, s = len-pattern.len; i < pattern.len; ++i)
767  {
768  if(str[s+i] != pattern[i])
769  {
770  return false;
771  }
772  }
773  return true;
774  }

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

778  {
779  if(len == 0)
780  {
781  return false;
782  }
783  for(size_t i = 0; i < chars.len; ++i)
784  {
785  if(str[len - 1] == chars[i])
786  {
787  return true;
788  }
789  }
790  return false;
791  }

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

797  {
798  C4_ASSERT(start == npos || (start >= 0 && start <= len));
799  for(size_t i = start; i < len; ++i)
800  {
801  if(str[i] == c)
802  return i;
803  }
804  return npos;
805  }

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

809  {
810  C4_ASSERT(start == npos || (start >= 0 && start <= len));
811  if(start == npos)
812  start = len;
813  for(size_t i = start-1; i != size_t(-1); --i)
814  {
815  if(str[i] == c)
816  return i;
817  }
818  return npos;
819  }

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

823  {
824  C4_ASSERT(start == npos || (start >= 0 && start <= len));
825  for(size_t i = start; i < len; ++i)
826  {
827  for(size_t j = 0; j < chars.len; ++j)
828  {
829  if(str[i] == chars[j])
830  return i;
831  }
832  }
833  return npos;
834  }

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

838  {
839  C4_ASSERT(start == npos || (start >= 0 && start <= len));
840  if(start == npos)
841  start = len;
842  for(size_t i = start-1; i != size_t(-1); --i)
843  {
844  for(size_t j = 0; j < chars.len; ++j)
845  {
846  if(str[i] == chars[j])
847  return i;
848  }
849  }
850  return npos;
851  }

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

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

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

866  {
867  C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
868  for(size_t i = start; i < len; ++i)
869  {
870  if(str[i] != c)
871  return i;
872  }
873  return npos;
874  }

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

877  {
878  for(size_t i = len-1; i != size_t(-1); --i)
879  {
880  if(str[i] != c)
881  return i;
882  }
883  return npos;
884  }

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

887  {
888  C4_ASSERT(start == npos || (start >= 0 && start <= len));
889  if(start == npos)
890  start = len;
891  for(size_t i = start-1; i != size_t(-1); --i)
892  {
893  if(str[i] != c)
894  return i;
895  }
896  return npos;
897  }

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

900  {
901  for(size_t i = 0; i < len; ++i)
902  {
903  bool gotit = true;
904  for(size_t j = 0; j < chars.len; ++j)
905  {
906  if(str[i] == chars.str[j])
907  {
908  gotit = false;
909  break;
910  }
911  }
912  if(gotit)
913  {
914  return i;
915  }
916  }
917  return npos;
918  }

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

921  {
922  C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
923  for(size_t i = start; i < len; ++i)
924  {
925  bool gotit = true;
926  for(size_t j = 0; j < chars.len; ++j)
927  {
928  if(str[i] == chars.str[j])
929  {
930  gotit = false;
931  break;
932  }
933  }
934  if(gotit)
935  {
936  return i;
937  }
938  }
939  return npos;
940  }

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

943  {
944  for(size_t i = len-1; i != size_t(-1); --i)
945  {
946  bool gotit = true;
947  for(size_t j = 0; j < chars.len; ++j)
948  {
949  if(str[i] == chars.str[j])
950  {
951  gotit = false;
952  break;
953  }
954  }
955  if(gotit)
956  {
957  return i;
958  }
959  }
960  return npos;
961  }

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

964  {
965  C4_ASSERT(start == npos || (start >= 0 && start <= len));
966  if(start == npos)
967  start = len;
968  for(size_t i = start-1; i != size_t(-1); --i)
969  {
970  bool gotit = true;
971  for(size_t j = 0; j < chars.len; ++j)
972  {
973  if(str[i] == chars.str[j])
974  {
975  gotit = false;
976  break;
977  }
978  }
979  if(gotit)
980  {
981  return i;
982  }
983  }
984  return npos;
985  }

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

998  {
999  size_t b = find(open);
1000  if(b == npos)
1001  return basic_substring();
1002  size_t e = find(close, b+1);
1003  if(e == npos)
1004  return basic_substring();
1005  basic_substring ret = range(b, e+1);
1006  C4_ASSERT(ret.sub(1).find(open) == npos);
1007  return ret;
1008  }
basic_substring range(size_t first, size_t last=npos) const noexcept
return [first,last[.
Definition: substr.hpp:343

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

1013  {
1014  size_t b = find(open_close);
1015  if(b == npos) return basic_substring();
1016  for(size_t i = b+1; i < len; ++i)
1017  {
1018  CC c = str[i];
1019  if(c == open_close)
1020  {
1021  if(str[i-1] != escape)
1022  {
1023  return range(b, i+1);
1024  }
1025  }
1026  }
1027  return basic_substring();
1028  }
typename std::add_const< C >::type CC
CC=const char.
Definition: substr.hpp:87

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

1034  {
1035  size_t b = find(open);
1036  if(b == npos) return basic_substring();
1037  size_t e, curr = b+1, count = 0;
1038  const char both[] = {open, close, '\0'};
1039  while((e = first_of(both, curr)) != npos)
1040  {
1041  if(str[e] == open)
1042  {
1043  ++count;
1044  curr = e+1;
1045  }
1046  else if(str[e] == close)
1047  {
1048  if(count == 0) return range(b, e+1);
1049  --count;
1050  curr = e+1;
1051  }
1052  }
1053  return basic_substring();
1054  }
size_t count(const C c, size_t pos=0) const
count the number of occurrences of c
Definition: substr.hpp:568

References c4::yml::npos.

◆ unquoted()

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

Definition at line 1056 of file substr.hpp.

1057  {
1058  constexpr const C dq('"'), sq('\'');
1059  if(len >= 2 && (str[len - 2] != C('\\')) &&
1060  ((begins_with(sq) && ends_with(sq))
1061  ||
1062  (begins_with(dq) && ends_with(dq))))
1063  {
1064  return range(1, len -1);
1065  }
1066  return *this;
1067  }

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

1079  {
1080  if(empty() || (first_non_empty_span().empty()))
1081  return false;
1082  if(first_uint_span() == *this)
1083  return true;
1084  if(first_int_span() == *this)
1085  return true;
1086  if(first_real_span() == *this)
1087  return true;
1088  return false;
1089  }
basic_substring first_uint_span() const
get the first span which can be interpreted as an unsigned integer
Definition: substr.hpp:1139
basic_substring first_real_span() const
get the first span which can be interpreted as a real (floating-point) number
Definition: substr.hpp:1226
basic_substring first_int_span() const
get the first span which can be interpreted as a signed integer
Definition: substr.hpp:1151
basic_substring first_non_empty_span() const
get the first span consisting exclusively of non-empty characters
Definition: substr.hpp:1127

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

1094  {
1095  if(empty() || (first_non_empty_span().empty()))
1096  return false;
1097  if(first_real_span() == *this)
1098  return true;
1099  return false;
1100  }

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

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

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

1118  {
1119  if(empty() || (first_non_empty_span().empty()))
1120  return false;
1121  if(first_uint_span() == *this)
1122  return true;
1123  return false;
1124  }

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

1128  {
1129  constexpr const ro_substr empty_chars(" \n\r\t");
1130  size_t pos = first_not_of(empty_chars);
1131  if(pos == npos)
1132  return first(0);
1133  auto ret = sub(pos);
1134  pos = ret.first_of(empty_chars);
1135  return ret.first(pos);
1136  }

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

1140  {
1142  if(ne.empty())
1143  return ne;
1144  if(ne.str[0] == '-')
1145  return first(0);
1146  size_t skip_start = size_t(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_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 1151 of file substr.hpp.

1152  {
1154  if(ne.empty())
1155  return ne;
1156  size_t skip_start = size_t(ne.str[0] == '+' || ne.str[0] == '-');
1157  return ne._first_integral_span(skip_start);
1158  }

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

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

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

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

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

1282  {
1283  return c == ' ' || c == '\n'
1284  || c == ']' || c == ')' || c == '}'
1285  || c == ',' || c == ';' || c == '\r' || c == '\t' || c == '\0';
1286  }

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

1290  {
1291  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
1292  }

◆ _word_follows()

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

Definition at line 1294 of file substr.hpp.

1295  {
1296  size_t posend = pos + word.len;
1297  if(len >= posend && sub(pos, word.len) == word)
1298  if(len == posend || _is_delim_char(str[posend]))
1299  return first(posend);
1300  return first(0);
1301  }

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

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

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

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

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

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

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

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

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

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

1672  {
1673  if(C4_LIKELY(*start_pos < len))
1674  {
1675  for(size_t i = *start_pos; i < len; i++)
1676  {
1677  if(str[i] == sep)
1678  {
1679  out->assign(str + *start_pos, i - *start_pos);
1680  *start_pos = i+1;
1681  return true;
1682  }
1683  }
1684  out->assign(str + *start_pos, len - *start_pos);
1685  *start_pos = len + 1;
1686  return true;
1687  }
1688  else
1689  {
1690  bool valid = len > 0 && (*start_pos == len);
1691  if(valid && str && str[len-1] == sep)
1692  {
1693  out->assign(str + len, size_t(0)); // the cast is needed to prevent overload ambiguity
1694  }
1695  else
1696  {
1697  out->assign(str + len + 1, size_t(0)); // the cast is needed to prevent overload ambiguity
1698  }
1699  *start_pos = len + 1;
1700  return valid;
1701  }
1702  }

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

1775  {
1776  C4_XASSERT((start_pos >= 0 && start_pos < len) || empty());
1777  auto ss = sub(0, len);
1778  auto it = split_proxy(ss, start_pos, sep);
1779  return it;
1780  }
split_proxy_impl split_proxy
Definition: substr.hpp:1771

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

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

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

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

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

1896  {
1897  auto ss = pop_right(sep, skip_empty);
1898  ss = left_of(ss);
1899  if(ss.find(sep) != npos)
1900  {
1901  if(ss.ends_with(sep))
1902  {
1903  if(skip_empty)
1904  {
1905  ss = ss.trimr(sep);
1906  }
1907  else
1908  {
1909  ss = ss.sub(0, ss.len-1); // safe to subtract because ends_with(sep) is true
1910  }
1911  }
1912  }
1913  return ss;
1914  }
basic_substring pop_right(C sep=C('/'), bool skip_empty=false) const
pop right: return the first split from the right.
Definition: substr.hpp:1787

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

1918  {
1919  auto ss = pop_left(sep, skip_empty);
1920  ss = right_of(ss);
1921  if(ss.find(sep) != npos)
1922  {
1923  if(ss.begins_with(sep))
1924  {
1925  if(skip_empty)
1926  {
1927  ss = ss.triml(sep);
1928  }
1929  else
1930  {
1931  ss = ss.sub(1);
1932  }
1933  }
1934  }
1935  return ss;
1936  }
basic_substring right_of(size_t pos) const noexcept
return [pos+1, len[
Definition: substr.hpp:398
basic_substring pop_left(C sep=C('/'), bool skip_empty=false) const
return the first split from the left.
Definition: substr.hpp:1840

References c4::yml::npos.

◆ basename()

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

Definition at line 1945 of file substr.hpp.

1946  {
1947  auto ss = pop_right(sep, /*skip_empty*/true);
1948  ss = ss.trimr(sep);
1949  return ss;
1950  }

◆ dirname()

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

Definition at line 1952 of file substr.hpp.

1953  {
1954  auto ss = basename(sep);
1955  ss = ss.empty() ? *this : left_of(ss);
1956  return ss;
1957  }
basic_substring basename(C sep=C('/')) const
Definition: substr.hpp:1945

◆ name_wo_extshort()

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

Definition at line 1959 of file substr.hpp.

1960  {
1961  return gpop_left('.');
1962  }
basic_substring gpop_left(C sep=C('/'), bool skip_empty=false) const
greedy pop left.
Definition: substr.hpp:1895

◆ name_wo_extlong()

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

Definition at line 1964 of file substr.hpp.

1965  {
1966  return pop_left('.');
1967  }

◆ extshort()

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

Definition at line 1969 of file substr.hpp.

1970  {
1971  return pop_right('.');
1972  }

◆ extlong()

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

Definition at line 1974 of file substr.hpp.

1975  {
1976  return gpop_right('.');
1977  }
basic_substring gpop_right(C sep=C('/'), bool skip_empty=false) const
greedy pop right.
Definition: substr.hpp:1917

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

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

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

1999  {
2000  for(size_t i = 0; i < len; ++i)
2001  {
2002  str[i] = static_cast<C>(::tolower(str[i]));
2003  }
2004  }
void tolower()
convert the string to lower-case
Definition: substr.hpp:1998

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

2011  {
2012  for(size_t i = 0; i < len; ++i)
2013  str[i] = val;
2014  }

◆ copy_from() [1/2]

template<class C >
void c4::basic_substring< C >::copy_from ( ro_substr  that)
inline

copy a string to this substr, starting at 0

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

Definition at line 2020 of file substr.hpp.

2021  {
2022  C4_ASSERT(!overlaps(that));
2023  size_t num = that.len <= len ? that.len : len;
2024  // calling memcpy with zero len is undefined behavior
2025  // and will wreak havoc in calling code's branches.
2026  // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2027  if(num)
2028  memcpy(str, that.str, sizeof(C) * num);
2029  }
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:317

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

◆ copy_from() [2/2]

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

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

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

Definition at line 2033 of file substr.hpp.

2034  {
2035  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2036  num = num != npos ? num : len - ifirst;
2037  num = num < that.len ? num : that.len;
2038  C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2039  // calling memcpy with zero len is undefined behavior
2040  // and will wreak havoc in calling code's branches.
2041  // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2042  if(num)
2043  memcpy(str + (sizeof(C) * ifirst), that.str, sizeof(C) * num);
2044  }

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

2051  {
2052  if(len == 0) return;
2053  detail::_do_reverse(str, str + len - 1);
2054  }

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

2059  {
2060  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2061  C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2062  if(num == 0) return;
2063  detail::_do_reverse(str + ifirst, str + ifirst + num - 1);
2064  }

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

2069  {
2070  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2071  C4_ASSERT(ilast >= 0 && ilast <= len);
2072  if(ifirst == ilast) return;
2073  detail::_do_reverse(str + ifirst, str + ilast - 1);
2074  }

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

2082  {
2083  C4_ASSERT(pos >= 0 && pos+num <= len);
2084  size_t num_to_move = len - pos - num;
2085  memmove(str + pos, str + pos + num, sizeof(C) * num_to_move);
2086  return basic_substring{str, len - num};
2087  }

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

2091  {
2092  C4_ASSERT(first <= last);
2093  return erase(first, static_cast<size_t>(last-first)); // NOLINT
2094  }
basic_substring erase(size_t pos, size_t num)
erase part of the string.
Definition: substr.hpp:2081

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

2100  {
2101  C4_ASSERT(is_super(sub));
2102  C4_ASSERT(sub.str >= str);
2103  return erase(static_cast<size_t>(sub.str - str), sub.len);
2104  }

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

2112  {
2113  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2114  size_t did_it = 0;
2115  while((pos = find(value, pos)) != npos)
2116  {
2117  str[pos++] = repl;
2118  ++did_it;
2119  }
2120  return did_it;
2121  }

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

2128  {
2129  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2130  size_t did_it = 0;
2131  while((pos = first_of(chars, pos)) != npos)
2132  {
2133  str[pos++] = repl;
2134  ++did_it;
2135  }
2136  return did_it;
2137  }

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

2146  {
2147  C4_ASSERT( ! pattern.empty()); //!< @todo relax this precondition
2148  C4_ASSERT( ! this ->overlaps(dst)); //!< @todo relax this precondition
2149  C4_ASSERT( ! pattern.overlaps(dst));
2150  C4_ASSERT( ! repl .overlaps(dst));
2151  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2152  C4_SUPPRESS_WARNING_GCC_PUSH
2153  C4_SUPPRESS_WARNING_GCC("-Warray-bounds") // gcc11 has a false positive here
2154  #if (!defined(__clang__)) && (defined(__GNUC__) && (__GNUC__ >= 7))
2155  C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow") // gcc11 has a false positive here
2156  #endif
2157  #define _c4append(first, last) \
2158  { \
2159  C4_ASSERT((last) >= (first)); \
2160  size_t num = static_cast<size_t>((last) - (first)); \
2161  if(num > 0 && sz + num <= dst.len) \
2162  { \
2163  memcpy(dst.str + sz, first, num * sizeof(C)); \
2164  } \
2165  sz += num; \
2166  }
2167  size_t sz = 0;
2168  size_t b = pos;
2169  _c4append(str, str + pos);
2170  do {
2171  size_t e = find(pattern, b);
2172  if(e == npos)
2173  {
2174  _c4append(str + b, str + len);
2175  break;
2176  }
2177  _c4append(str + b, str + e);
2178  _c4append(repl.begin(), repl.end());
2179  b = e + pattern.size();
2180  } while(b < len && b != npos);
2181  return sz;
2182  #undef _c4append
2183  C4_SUPPRESS_WARNING_GCC_POP
2184  }
#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

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

a restricted pointer to the first character of the substring

Definition at line 78 of file substr.hpp.

◆ len

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

the length of the substring

Definition at line 80 of file substr.hpp.


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