rapidyaml  0.13.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 of type const C* or C*) 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 of type const C* or C*) 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 68 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 82 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 83 of file substr.hpp.

◆ ro_substr

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

Definition at line 85 of file substr.hpp.

◆ rw_substr

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

Definition at line 86 of file substr.hpp.

◆ char_type

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

Definition at line 88 of file substr.hpp.

◆ size_type

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

Definition at line 89 of file substr.hpp.

◆ iterator

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

Definition at line 91 of file substr.hpp.

◆ const_iterator

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

Definition at line 92 of file substr.hpp.

◆ split_proxy

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

Definition at line 1766 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

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

Definition at line 94 of file substr.hpp.

94 : 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 110 of file substr.hpp.

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

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

114 : 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 133 of file substr.hpp.

133 : 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 136 of file substr.hpp.

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

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

148 : 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 98 of file substr.hpp.

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

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

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

◆ clear()

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

Definition at line 120 of file substr.hpp.

120 { 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 154 of file substr.hpp.

154 { 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 157 of file substr.hpp.

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

161 { 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 of type const C* or C*)

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

Definition at line 169 of file substr.hpp.

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

174 { 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 of type const C* or C*)

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

Definition at line 182 of file substr.hpp.

182 { 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 191 of file substr.hpp.

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

◆ empty()

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

Definition at line 192 of file substr.hpp.

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

◆ not_empty()

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

Definition at line 193 of file substr.hpp.

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

◆ size()

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

Definition at line 194 of file substr.hpp.

194 { return len; }

◆ begin() [1/2]

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

Definition at line 196 of file substr.hpp.

196 { return str; }

◆ end() [1/2]

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

Definition at line 197 of file substr.hpp.

197 { return str + len; }

◆ begin() [2/2]

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

Definition at line 199 of file substr.hpp.

199 { return str; }

◆ end() [2/2]

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

Definition at line 200 of file substr.hpp.

200 { return str + len; }

◆ data() [1/2]

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

Definition at line 202 of file substr.hpp.

202 { return str; }

◆ data() [2/2]

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

Definition at line 203 of file substr.hpp.

203 { return str; }

◆ operator[]() [1/2]

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

Definition at line 205 of file substr.hpp.

205 { 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 206 of file substr.hpp.

206 { 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 208 of file substr.hpp.

208 { 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 209 of file substr.hpp.

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

◆ back() [1/2]

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

Definition at line 211 of file substr.hpp.

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

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

222  {
223  C4_XASSERT((str != nullptr) || len == 0);
224  if(C4_LIKELY(str != nullptr && len > 0))
225  return (*str != c) ? *str - c : (static_cast<int>(len) - 1);
226  else
227  return -1;
228  }

◆ compare() [2/3]

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

Definition at line 230 of file substr.hpp.

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

◆ compare() [3/3]

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

Definition at line 263 of file substr.hpp.

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

◆ operator==() [1/4]

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

Definition at line 265 of file substr.hpp.

265 { return str == nullptr; }

◆ operator!=() [1/4]

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

Definition at line 266 of file substr.hpp.

266 { return str != nullptr; }

◆ operator==() [2/4]

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

Definition at line 268 of file substr.hpp.

268 { 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 269 of file substr.hpp.

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

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

◆ operator>() [1/3]

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

Definition at line 271 of file substr.hpp.

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

◆ operator<=() [1/3]

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

Definition at line 272 of file substr.hpp.

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

◆ operator>=() [1/3]

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

Definition at line 273 of file substr.hpp.

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

◆ operator==() [3/4]

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

Definition at line 275 of file substr.hpp.

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

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

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

◆ operator>() [2/3]

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

Definition at line 278 of file substr.hpp.

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

◆ operator<=() [2/3]

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

Definition at line 279 of file substr.hpp.

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

◆ operator>=() [2/3]

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

Definition at line 280 of file substr.hpp.

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

◆ operator==() [4/4]

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

Definition at line 282 of file substr.hpp.

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

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

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

◆ operator>() [3/3]

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

Definition at line 285 of file substr.hpp.

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

◆ operator<=() [3/3]

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

Definition at line 286 of file substr.hpp.

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

◆ operator>=() [3/3]

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

Definition at line 287 of file substr.hpp.

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

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

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

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

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

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

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

◆ sub() [1/2]

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

return [first,len[

Definition at line 321 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ triml() [1/2]

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

trim left

Definition at line 448 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

670  {
671  #if defined(__GNUC__) && (__GNUC__ >= 6)
672  C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wnull-dereference")
673  #endif
674  return len > 0 ? str[0] == c : false;
675  #if defined(__GNUC__) && (__GNUC__ >= 6)
676  C4_SUPPRESS_WARNING_GCC_POP
677  #endif
678  }

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

682  {
683  if(len < num)
684  {
685  return false;
686  }
687  for(size_t i = 0; i < num; ++i)
688  {
689  if(str[i] != c)
690  {
691  return false;
692  }
693  }
694  return true;
695  }

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

699  {
700  if(len < pattern.len)
701  {
702  return false;
703  }
704  for(size_t i = 0; i < pattern.len; ++i)
705  {
706  if(str[i] != pattern[i])
707  {
708  return false;
709  }
710  }
711  return true;
712  }

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

716  {
717  if(len == 0)
718  {
719  return false;
720  }
721  for(size_t i = 0; i < chars.len; ++i)
722  {
723  if(str[0] == chars.str[i])
724  {
725  return true;
726  }
727  }
728  return false;
729  }

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

733  {
734  return len > 0 ? str[len-1] == c : false;
735  }

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

739  {
740  if(len < num)
741  {
742  return false;
743  }
744  for(size_t i = len - num; i < len; ++i)
745  {
746  if(str[i] != c)
747  {
748  return false;
749  }
750  }
751  return true;
752  }

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

756  {
757  if(len < pattern.len)
758  {
759  return false;
760  }
761  for(size_t i = 0, s = len-pattern.len; i < pattern.len; ++i)
762  {
763  if(str[s+i] != pattern[i])
764  {
765  return false;
766  }
767  }
768  return true;
769  }

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

773  {
774  if(len == 0)
775  {
776  return false;
777  }
778  for(size_t i = 0; i < chars.len; ++i)
779  {
780  if(str[len - 1] == chars[i])
781  {
782  return true;
783  }
784  }
785  return false;
786  }

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

792  {
793  C4_ASSERT(start == npos || (start >= 0 && start <= len));
794  for(size_t i = start; i < len; ++i)
795  {
796  if(str[i] == c)
797  return i;
798  }
799  return npos;
800  }

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

804  {
805  C4_ASSERT(start == npos || (start >= 0 && start <= len));
806  if(start == npos)
807  start = len;
808  for(size_t i = start-1; i != size_t(-1); --i)
809  {
810  if(str[i] == c)
811  return i;
812  }
813  return npos;
814  }

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

818  {
819  C4_ASSERT(start == npos || (start >= 0 && start <= len));
820  for(size_t i = start; i < len; ++i)
821  {
822  for(size_t j = 0; j < chars.len; ++j)
823  {
824  if(str[i] == chars[j])
825  return i;
826  }
827  }
828  return npos;
829  }

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

833  {
834  C4_ASSERT(start == npos || (start >= 0 && start <= len));
835  if(start == npos)
836  start = len;
837  for(size_t i = start-1; i != size_t(-1); --i)
838  {
839  for(size_t j = 0; j < chars.len; ++j)
840  {
841  if(str[i] == chars[j])
842  return i;
843  }
844  }
845  return npos;
846  }

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

851  {
852  for(size_t i = 0; i < len; ++i)
853  {
854  if(str[i] != c)
855  return i;
856  }
857  return npos;
858  }

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

861  {
862  C4_ASSERT((start >= 0 && start <= len) || (start == len && len == 0));
863  for(size_t i = start; i < len; ++i)
864  {
865  if(str[i] != c)
866  return i;
867  }
868  return npos;
869  }

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

872  {
873  for(size_t i = len-1; i != size_t(-1); --i)
874  {
875  if(str[i] != c)
876  return i;
877  }
878  return npos;
879  }

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

882  {
883  C4_ASSERT(start == npos || (start >= 0 && start <= len));
884  if(start == npos)
885  start = len;
886  for(size_t i = start-1; i != size_t(-1); --i)
887  {
888  if(str[i] != c)
889  return i;
890  }
891  return npos;
892  }

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

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

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

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

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

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

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

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

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

993  {
994  size_t b = find(open);
995  if(b == npos)
996  return basic_substring();
997  size_t e = find(close, b+1);
998  if(e == npos)
999  return basic_substring();
1000  basic_substring ret = range(b, e+1);
1001  C4_ASSERT(ret.sub(1).find(open) == npos);
1002  return ret;
1003  }
basic_substring range(size_t first, size_t last=npos) const noexcept
return [first,last[.
Definition: substr.hpp:338

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

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

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

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

◆ unquoted()

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

Definition at line 1051 of file substr.hpp.

1052  {
1053  constexpr const C dq('"'), sq('\'');
1054  if(len >= 2 && (str[len - 2] != C('\\')) &&
1055  ((begins_with(sq) && ends_with(sq))
1056  ||
1057  (begins_with(dq) && ends_with(dq))))
1058  {
1059  return range(1, len -1);
1060  }
1061  return *this;
1062  }

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

1074  {
1075  if(empty() || (first_non_empty_span().empty()))
1076  return false;
1077  if(first_uint_span() == *this)
1078  return true;
1079  if(first_int_span() == *this)
1080  return true;
1081  if(first_real_span() == *this)
1082  return true;
1083  return false;
1084  }
basic_substring first_uint_span() const
get the first span which can be interpreted as an unsigned integer
Definition: substr.hpp:1134
basic_substring first_real_span() const
get the first span which can be interpreted as a real (floating-point) number
Definition: substr.hpp:1221
basic_substring first_int_span() const
get the first span which can be interpreted as a signed integer
Definition: substr.hpp:1146
basic_substring first_non_empty_span() const
get the first span consisting exclusively of non-empty characters
Definition: substr.hpp:1122

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

1089  {
1090  if(empty() || (first_non_empty_span().empty()))
1091  return false;
1092  if(first_real_span() == *this)
1093  return true;
1094  return false;
1095  }

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

1100  {
1101  if(empty() || (first_non_empty_span().empty()))
1102  return false;
1103  if(first_uint_span() == *this)
1104  return true;
1105  if(first_int_span() == *this)
1106  return true;
1107  return false;
1108  }

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

1113  {
1114  if(empty() || (first_non_empty_span().empty()))
1115  return false;
1116  if(first_uint_span() == *this)
1117  return true;
1118  return false;
1119  }

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

1123  {
1124  constexpr const ro_substr empty_chars(" \n\r\t");
1125  size_t pos = first_not_of(empty_chars);
1126  if(pos == npos)
1127  return first(0);
1128  auto ret = sub(pos);
1129  pos = ret.first_of(empty_chars);
1130  return ret.first(pos);
1131  }

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

1135  {
1137  if(ne.empty())
1138  return ne;
1139  if(ne.str[0] == '-')
1140  return first(0);
1141  size_t skip_start = size_t(ne.str[0] == '+');
1142  return ne._first_integral_span(skip_start);
1143  }

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

1147  {
1149  if(ne.empty())
1150  return ne;
1151  size_t skip_start = size_t(ne.str[0] == '+' || ne.str[0] == '-');
1152  return ne._first_integral_span(skip_start);
1153  }

◆ _first_integral_span()

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

Definition at line 1155 of file substr.hpp.

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

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

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

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

1277  {
1278  return c == ' ' || c == '\n'
1279  || c == ']' || c == ')' || c == '}'
1280  || c == ',' || c == ';' || c == '\r' || c == '\t' || c == '\0';
1281  }

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

1285  {
1286  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
1287  }

◆ _word_follows()

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

Definition at line 1289 of file substr.hpp.

1290  {
1291  size_t posend = pos + word.len;
1292  if(len >= posend && sub(pos, word.len) == word)
1293  if(len == posend || _is_delim_char(str[posend]))
1294  return first(posend);
1295  return first(0);
1296  }

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

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

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

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

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

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

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

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

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

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

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

1770  {
1771  C4_XASSERT((start_pos >= 0 && start_pos < len) || empty());
1772  auto ss = sub(0, len);
1773  auto it = split_proxy(ss, start_pos, sep);
1774  return it;
1775  }
split_proxy_impl split_proxy
Definition: substr.hpp:1766

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

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

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

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

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

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

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

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

◆ basename()

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

Definition at line 1940 of file substr.hpp.

1941  {
1942  auto ss = pop_right(sep, /*skip_empty*/true);
1943  ss = ss.trimr(sep);
1944  return ss;
1945  }

◆ dirname()

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

Definition at line 1947 of file substr.hpp.

1948  {
1949  auto ss = basename(sep);
1950  ss = ss.empty() ? *this : left_of(ss);
1951  return ss;
1952  }
basic_substring basename(C sep=C('/')) const
Definition: substr.hpp:1940

◆ name_wo_extshort()

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

Definition at line 1954 of file substr.hpp.

1955  {
1956  return gpop_left('.');
1957  }
basic_substring gpop_left(C sep=C('/'), bool skip_empty=false) const
greedy pop left.
Definition: substr.hpp:1890

◆ name_wo_extlong()

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

Definition at line 1959 of file substr.hpp.

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

◆ extshort()

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

Definition at line 1964 of file substr.hpp.

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

◆ extlong()

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

Definition at line 1969 of file substr.hpp.

1970  {
1971  return gpop_right('.');
1972  }
basic_substring gpop_right(C sep=C('/'), bool skip_empty=false) const
greedy pop right.
Definition: substr.hpp:1912

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

1984  {
1985  for(size_t i = 0; i < len; ++i)
1986  {
1987  str[i] = static_cast<C>(::toupper(str[i]));
1988  }
1989  }
void toupper()
convert the string to upper-case
Definition: substr.hpp:1983

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

1994  {
1995  for(size_t i = 0; i < len; ++i)
1996  {
1997  str[i] = static_cast<C>(::tolower(str[i]));
1998  }
1999  }
void tolower()
convert the string to lower-case
Definition: substr.hpp:1993

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

2006  {
2007  for(size_t i = 0; i < len; ++i)
2008  str[i] = val;
2009  }

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

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

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

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

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

2046  {
2047  if(len == 0) return;
2048  detail::_do_reverse(str, str + len - 1);
2049  }

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

2054  {
2055  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2056  C4_ASSERT(ifirst + num >= 0 && ifirst + num <= len);
2057  if(num == 0) return;
2058  detail::_do_reverse(str + ifirst, str + ifirst + num - 1);
2059  }

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

2064  {
2065  C4_ASSERT(ifirst >= 0 && ifirst <= len);
2066  C4_ASSERT(ilast >= 0 && ilast <= len);
2067  if(ifirst == ilast) return;
2068  detail::_do_reverse(str + ifirst, str + ilast - 1);
2069  }

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

2077  {
2078  C4_ASSERT(pos >= 0 && pos+num <= len);
2079  size_t num_to_move = len - pos - num;
2080  memmove(str + pos, str + pos + num, sizeof(C) * num_to_move);
2081  return basic_substring{str, len - num};
2082  }

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

2086  {
2087  C4_ASSERT(first <= last);
2088  return erase(first, static_cast<size_t>(last-first)); // NOLINT
2089  }
basic_substring erase(size_t pos, size_t num)
erase part of the string.
Definition: substr.hpp:2076

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

2095  {
2096  C4_ASSERT(is_super(sub));
2097  C4_ASSERT(sub.str >= str);
2098  return erase(static_cast<size_t>(sub.str - str), sub.len);
2099  }

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

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

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

2123  {
2124  C4_ASSERT((pos >= 0 && pos <= len) || pos == npos);
2125  size_t did_it = 0;
2126  while((pos = first_of(chars, pos)) != npos)
2127  {
2128  str[pos++] = repl;
2129  ++did_it;
2130  }
2131  return did_it;
2132  }

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

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

Member Data Documentation

◆ str

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

a restricted pointer to the first character of the substring

Definition at line 73 of file substr.hpp.

◆ len

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

the length of the substring

Definition at line 75 of file substr.hpp.


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