rapidyaml  0.9.0
parse and emit YAML, and do it fast
c4::basic_substring< C > Struct Template Reference

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

#include <substr.hpp>

Classes

struct  first_of_any_result
 

Public Member Functions

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

Public Attributes

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

Types

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

Splitting methods

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

Number-matching query methods

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

Detailed Description

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

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

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

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

◆ ro_substr

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

Definition at line 89 of file substr.hpp.

◆ rw_substr

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

Definition at line 90 of file substr.hpp.

◆ char_type

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

Definition at line 92 of file substr.hpp.

◆ size_type

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

Definition at line 93 of file substr.hpp.

◆ iterator

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

Definition at line 95 of file substr.hpp.

◆ const_iterator

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

Definition at line 96 of file substr.hpp.

◆ split_proxy

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

Definition at line 1758 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

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

Definition at line 98 of file substr.hpp.

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

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

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

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

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

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

144 : 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 152 of file substr.hpp.

152 : 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 102 of file substr.hpp.

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

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

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

◆ clear()

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

Definition at line 124 of file substr.hpp.

124 { 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 158 of file substr.hpp.

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

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

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

◆ assign() [4/4]

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

Assign from a C-string (zero-terminated string)

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

Definition at line 173 of file substr.hpp.

173 { 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 178 of file substr.hpp.

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

◆ operator=() [5/5]

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

Assign from a C-string (zero-terminated string)

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

Definition at line 186 of file substr.hpp.

186 { 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 195 of file substr.hpp.

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

◆ empty()

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

◆ not_empty()

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

Definition at line 197 of file substr.hpp.

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

◆ size()

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

◆ begin() [1/2]

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

Definition at line 200 of file substr.hpp.

200 { return str; }

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

◆ end() [1/2]

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

Definition at line 201 of file substr.hpp.

201 { return str + len; }

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

◆ begin() [2/2]

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

Definition at line 203 of file substr.hpp.

203 { return str; }

◆ end() [2/2]

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

Definition at line 204 of file substr.hpp.

204 { return str + len; }

◆ data() [1/2]

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

Definition at line 206 of file substr.hpp.

206 { return str; }

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

◆ data() [2/2]

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

Definition at line 207 of file substr.hpp.

207 { return str; }

◆ operator[]() [1/2]

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

Definition at line 209 of file substr.hpp.

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

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

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

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

◆ back() [1/2]

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

Definition at line 215 of file substr.hpp.

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

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

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

◆ compare() [2/3]

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

Definition at line 234 of file substr.hpp.

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

◆ compare() [3/3]

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

Definition at line 261 of file substr.hpp.

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

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

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

◆ operator==() [1/4]

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

Definition at line 263 of file substr.hpp.

263 { return str == nullptr; }

◆ operator!=() [1/4]

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

Definition at line 264 of file substr.hpp.

264 { return str != nullptr; }

◆ operator==() [2/4]

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

Definition at line 266 of file substr.hpp.

266 { 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 267 of file substr.hpp.

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

268 { 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 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==() [3/4]

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

Definition at line 273 of file substr.hpp.

273 { 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 274 of file substr.hpp.

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

275 { 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 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==() [4/4]

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

Definition at line 280 of file substr.hpp.

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

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

282 { 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 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; }

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

296  {
297  return that.is_super(*this);
298  }

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

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

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

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

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

◆ sub() [1/2]

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

return [first,len[

Definition at line 319 of file substr.hpp.

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

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

◆ sub() [2/2]

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

return [first,first+num[.

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

Definition at line 326 of file substr.hpp.

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

References c4::yml::npos.

◆ range()

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

return [first,last[.

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

Definition at line 336 of file substr.hpp.

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

References c4::yml::npos.

◆ first()

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

return the first num elements: [0,num[

Definition at line 346 of file substr.hpp.

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

References c4::yml::npos.

◆ last()

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

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

Definition at line 353 of file substr.hpp.

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

References c4::yml::npos.

◆ offs()

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

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

This is equivalent to python's negative list indices.

Definition at line 364 of file substr.hpp.

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

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

◆ left_of() [1/3]

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

return [0, pos[ .

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

Definition at line 373 of file substr.hpp.

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

References c4::yml::npos.

◆ left_of() [2/3]

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

return [0, pos+include_pos[ .

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

Definition at line 382 of file substr.hpp.

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

References c4::yml::npos.

◆ right_of() [1/3]

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

return [pos+1, len[

Definition at line 391 of file substr.hpp.

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

References c4::yml::npos.

◆ right_of() [2/3]

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

return [pos+!include_pos, len[

Definition at line 400 of file substr.hpp.

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

References c4::yml::npos.

◆ left_of() [3/3]

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

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

Definition at line 412 of file substr.hpp.

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

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

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

◆ triml() [1/2]

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

trim left

Definition at line 446 of file substr.hpp.

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

References c4::yml::npos.

◆ triml() [2/2]

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

trim left ANY of the characters.

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

Definition at line 458 of file substr.hpp.

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

References c4::yml::npos.

◆ trimr() [1/2]

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

trim the character c from the right

Definition at line 470 of file substr.hpp.

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

References c4::yml::npos.

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

◆ trimr() [2/2]

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

trim right ANY of the characters

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

Definition at line 482 of file substr.hpp.

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

References c4::yml::npos.

◆ trim() [1/2]

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

trim the character c left and right

Definition at line 494 of file substr.hpp.

495  {
496  return triml(c).trimr(c);
497  }
basic_substring triml(const C c) const
trim left
Definition: substr.hpp:446
basic_substring trimr(const C c) const
trim the character c from the right
Definition: substr.hpp:470

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

◆ trim() [2/2]

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

trim left and right ANY of the characters

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

Definition at line 500 of file substr.hpp.

501  {
502  return triml(chars).trimr(chars);
503  }

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

◆ stripl()

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

remove a pattern from the left

See also
triml() to remove characters

Definition at line 507 of file substr.hpp.

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

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

◆ stripr()

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

remove a pattern from the right

See also
trimr() to remove characters

Definition at line 516 of file substr.hpp.

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

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

◆ find() [1/2]

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

Definition at line 530 of file substr.hpp.

531  {
532  return first_of(c, start_pos);
533  }
size_t first_of(const C c, size_t start=0) const
Definition: substr.hpp:783

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

◆ find() [2/2]

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

Definition at line 534 of file substr.hpp.

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

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

◆ count() [1/2]

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

count the number of occurrences of c

Definition at line 561 of file substr.hpp.

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

References c4::yml::npos.

◆ count() [2/2]

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

count the number of occurrences of s

Definition at line 575 of file substr.hpp.

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

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

◆ select() [1/2]

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

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

Definition at line 589 of file substr.hpp.

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

References c4::yml::npos.

◆ select() [2/2]

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

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

Definition at line 596 of file substr.hpp.

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

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

◆ first_of_any() [1/4]

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

Definition at line 611 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

◆ begins_with() [1/3]

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

true if the first character of the string is c

Definition at line 667 of file substr.hpp.

668  {
669  return len > 0 ? str[0] == c : false;
670  }

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

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

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

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

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

◆ begins_with_any()

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

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

Definition at line 707 of file substr.hpp.

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

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

◆ ends_with() [1/3]

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

true if the last character of the string is c

Definition at line 724 of file substr.hpp.

725  {
726  return len > 0 ? str[len-1] == c : false;
727  }

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

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

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

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

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

◆ ends_with_any()

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

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

Definition at line 764 of file substr.hpp.

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

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

◆ first_of() [1/2]

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

Definition at line 783 of file substr.hpp.

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

References c4::yml::npos.

◆ last_of() [1/2]

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

Definition at line 795 of file substr.hpp.

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

References c4::yml::npos.

◆ first_of() [2/2]

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

Definition at line 809 of file substr.hpp.

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

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

◆ last_of() [2/2]

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

Definition at line 824 of file substr.hpp.

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

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

◆ first_not_of() [1/4]

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

Definition at line 842 of file substr.hpp.

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

References c4::yml::npos.

◆ first_not_of() [2/4]

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

Definition at line 852 of file substr.hpp.

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

References c4::yml::npos.

◆ last_not_of() [1/4]

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

Definition at line 863 of file substr.hpp.

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

References c4::yml::npos.

◆ last_not_of() [2/4]

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

Definition at line 873 of file substr.hpp.

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

References c4::yml::npos.

◆ first_not_of() [3/4]

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

Definition at line 886 of file substr.hpp.

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

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

◆ first_not_of() [4/4]

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

Definition at line 907 of file substr.hpp.

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

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

◆ last_not_of() [3/4]

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

Definition at line 929 of file substr.hpp.

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

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

◆ last_not_of() [4/4]

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

Definition at line 950 of file substr.hpp.

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

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

◆ pair_range()

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

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

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

Definition at line 984 of file substr.hpp.

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

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

◆ pair_range_esc()

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

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

Note
The open-close character can be escaped.

Definition at line 999 of file substr.hpp.

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

References c4::yml::npos.

◆ pair_range_nested()

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

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

No checks for escapes are performed.

Definition at line 1020 of file substr.hpp.

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

References c4::yml::npos.

◆ unquoted()

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

Definition at line 1043 of file substr.hpp.

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

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

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

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

1081  {
1082  if(empty() || (first_non_empty_span().empty()))
1083  return false;
1084  if(first_real_span() == *this)
1085  return true;
1086  return false;
1087  }

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

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

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

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

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

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

References c4::yml::npos.

◆ first_uint_span()

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

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

Definition at line 1126 of file substr.hpp.

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

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

◆ first_int_span()

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

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

Definition at line 1138 of file substr.hpp.

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

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

◆ _first_integral_span()

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

Definition at line 1147 of file substr.hpp.

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

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

◆ first_real_span()

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

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

Definition at line 1213 of file substr.hpp.

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

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

◆ _is_delim_char()

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

true if the character is a delimiter character at the end

Definition at line 1268 of file substr.hpp.

1269  {
1270  return c == ' ' || c == '\n'
1271  || c == ']' || c == ')' || c == '}'
1272  || c == ',' || c == ';' || c == '\r' || c == '\t' || c == '\0';
1273  }

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

1277  {
1278  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
1279  }

◆ _word_follows()

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

Definition at line 1281 of file substr.hpp.

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

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

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

◆ _first_real_span_dec()

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

Definition at line 1291 of file substr.hpp.

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

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

◆ _first_real_span_hex()

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

Definition at line 1378 of file substr.hpp.

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

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

◆ _first_real_span_bin()

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

Definition at line 1468 of file substr.hpp.

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

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

◆ _first_real_span_oct()

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

Definition at line 1558 of file substr.hpp.

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

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

◆ next_split()

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

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

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

Definition at line 1658 of file substr.hpp.

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

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

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

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

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

References c4::yml::npos.

◆ pop_left()

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

return the first split from the left.

Use gpop_right() to get the reciprocal part.

Definition at line 1827 of file substr.hpp.

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

References c4::yml::npos.

◆ gpop_left()

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

greedy pop left.

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

Definition at line 1882 of file substr.hpp.

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

References c4::yml::npos.

◆ gpop_right()

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

greedy pop right.

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

Definition at line 1904 of file substr.hpp.

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

References c4::yml::npos.

◆ basename()

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

Definition at line 1932 of file substr.hpp.

1933  {
1934  auto ss = pop_right(sep, /*skip_empty*/true);
1935  ss = ss.trimr(sep);
1936  return ss;
1937  }

◆ dirname()

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

Definition at line 1939 of file substr.hpp.

1940  {
1941  auto ss = basename(sep);
1942  ss = ss.empty() ? *this : left_of(ss);
1943  return ss;
1944  }
basic_substring basename(C sep=C('/')) const
Definition: substr.hpp:1932

◆ name_wo_extshort()

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

Definition at line 1946 of file substr.hpp.

1947  {
1948  return gpop_left('.');
1949  }
basic_substring gpop_left(C sep=C('/'), bool skip_empty=false) const
greedy pop left.
Definition: substr.hpp:1882

◆ name_wo_extlong()

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

Definition at line 1951 of file substr.hpp.

1952  {
1953  return pop_left('.');
1954  }

◆ extshort()

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

Definition at line 1956 of file substr.hpp.

1957  {
1958  return pop_right('.');
1959  }

◆ extlong()

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

Definition at line 1961 of file substr.hpp.

1962  {
1963  return gpop_right('.');
1964  }
basic_substring gpop_right(C sep=C('/'), bool skip_empty=false) const
greedy pop right.
Definition: substr.hpp:1904

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

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

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

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

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

1998  {
1999  for(size_t i = 0; i < len; ++i)
2000  {
2001  str[i] = val;
2002  }
2003  }

◆ copy_from()

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

set the current substring to a copy of the given csubstr

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

Definition at line 2009 of file substr.hpp.

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

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

◆ reverse()

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

reverse in place

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

Definition at line 2026 of file substr.hpp.

2027  {
2028  if(len == 0) return;
2029  detail::_do_reverse(str, str + len - 1);
2030  }

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

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

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

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

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

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

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

2067  {
2068  C4_ASSERT(first <= last);
2069  return erase(first, static_cast<size_t>(last-first)); // NOLINT
2070  }
basic_substring erase(size_t pos, size_t num)
erase part of the string.
Definition: substr.hpp:2057

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

2076  {
2077  C4_ASSERT(is_super(sub));
2078  C4_ASSERT(sub.str >= str);
2079  return erase(static_cast<size_t>(sub.str - str), sub.len);
2080  }

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

◆ replace() [1/2]

template<class C >
size_t c4::basic_substring< C >::replace ( value,
repl,
size_t  pos = 0 
)
inline

replace every occurrence of character value with the character repl

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

Definition at line 2087 of file substr.hpp.

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

References c4::yml::npos.

◆ replace() [2/2]

template<class C >
size_t c4::basic_substring< C >::replace ( ro_substr  chars,
repl,
size_t  pos = 0 
)
inline

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

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

Definition at line 2103 of file substr.hpp.

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

References c4::yml::npos.

◆ replace_all()

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

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

pattern and repl don't need equal sizes.

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

<

<

Definition at line 2121 of file substr.hpp.

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

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

Member Data Documentation

◆ str

◆ len


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