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

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

#include <substr.hpp>

Classes

struct  first_of_any_result

Public Member Functions

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

Public Attributes

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

Types

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

Splitting methods

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

Number-matching query methods

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

Detailed Description

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

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

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

Definition at line 211 of file substr.hpp.

Member Typedef Documentation

◆ CC

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

CC=const char.

Definition at line 225 of file substr.hpp.

◆ NCC_

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

NCC_=non const char.

Definition at line 226 of file substr.hpp.

◆ ro_substr

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

Definition at line 228 of file substr.hpp.

◆ rw_substr

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

Definition at line 229 of file substr.hpp.

◆ value_type

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

Definition at line 231 of file substr.hpp.

◆ char_type

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

Definition at line 232 of file substr.hpp.

◆ size_type

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

Definition at line 233 of file substr.hpp.

◆ iterator

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

Definition at line 235 of file substr.hpp.

◆ const_iterator

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

Definition at line 236 of file substr.hpp.

◆ split_proxy

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

Definition at line 1910 of file substr.hpp.

Member Enumeration Documentation

◆ anonymous enum

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

Definition at line 238 of file substr.hpp.

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

Constructor & Destructor Documentation

◆ basic_substring() [1/8]

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

Definition at line 255 of file substr.hpp.

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

◆ basic_substring() [2/8]

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

◆ basic_substring() [3/8]

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

◆ basic_substring() [4/8]

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

Definition at line 259 of file substr.hpp.

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

◆ basic_substring() [5/8]

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

Construct from an array.

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

Definition at line 278 of file substr.hpp.

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

◆ basic_substring() [6/8]

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

Construct from a pointer and length.

Warning
the input string need not be zero terminated.

Definition at line 281 of file substr.hpp.

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

◆ basic_substring() [7/8]

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

Construct from two pointers.

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

Definition at line 285 of file substr.hpp.

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

◆ basic_substring() [8/8]

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

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

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

Definition at line 293 of file substr.hpp.

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

Member Function Documentation

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

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

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

Definition at line 242 of file substr.hpp.

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

◆ operator=() [1/5]

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

◆ operator=() [2/5]

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

◆ operator=() [3/5]

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

Definition at line 263 of file substr.hpp.

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

◆ clear()

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

Definition at line 265 of file substr.hpp.

265{ str = nullptr; len = 0; }

◆ assign() [1/4]

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

Assign from an array.

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

Definition at line 300 of file substr.hpp.

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

◆ assign() [2/4]

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

Assign from a pointer and length.

Warning
the input string need not be zero terminated.

Definition at line 303 of file substr.hpp.

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

◆ assign() [3/4]

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

Assign from two pointers.

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

Definition at line 307 of file substr.hpp.

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

◆ assign() [4/4]

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

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

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

Definition at line 315 of file substr.hpp.

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

◆ operator=() [4/5]

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

Assign from an array.

Warning
the input string need not be zero terminated.

Definition at line 329 of file substr.hpp.

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

◆ operator=() [5/5]

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

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

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

Definition at line 337 of file substr.hpp.

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

◆ has_str()

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

Definition at line 355 of file substr.hpp.

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

◆ empty()

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

Definition at line 356 of file substr.hpp.

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

◆ not_empty()

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

Definition at line 357 of file substr.hpp.

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

◆ size()

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

Definition at line 358 of file substr.hpp.

358{ return len; }

◆ begin() [1/2]

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

Definition at line 360 of file substr.hpp.

360{ return str; }

◆ end() [1/2]

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

Definition at line 361 of file substr.hpp.

361{ return str + len; }

◆ begin() [2/2]

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

Definition at line 363 of file substr.hpp.

363{ return str; }

◆ end() [2/2]

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

Definition at line 364 of file substr.hpp.

364{ return str + len; }

◆ data() [1/2]

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

Definition at line 366 of file substr.hpp.

366{ return str; }

◆ data() [2/2]

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

Definition at line 367 of file substr.hpp.

367{ return str; }

◆ operator[]() [1/2]

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

Definition at line 369 of file substr.hpp.

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

◆ operator[]() [2/2]

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

Definition at line 370 of file substr.hpp.

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

◆ front() [1/2]

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

Definition at line 372 of file substr.hpp.

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

◆ front() [2/2]

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

Definition at line 373 of file substr.hpp.

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

◆ back() [1/2]

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

Definition at line 375 of file substr.hpp.

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

◆ back() [2/2]

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

Definition at line 376 of file substr.hpp.

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

◆ compare() [1/4]

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

Definition at line 385 of file substr.hpp.

386 {
387 C4_XASSERT((str != nullptr) || len == 0);
388 if(C4_LIKELY(str != nullptr && len > 0))
389 return (*str != c) ? *str - c : (static_cast<int>(len) - 1);
390 else
391 return -1;
392 }

◆ compare() [2/4]

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

Definition at line 394 of file substr.hpp.

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

◆ compare() [3/4]

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

Definition at line 428 of file substr.hpp.

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

◆ compare() [4/4]

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

Definition at line 435 of file substr.hpp.

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

◆ operator==() [1/5]

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

Definition at line 440 of file substr.hpp.

440{ return str == nullptr; }

◆ operator!=() [1/5]

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

Definition at line 441 of file substr.hpp.

441{ return str != nullptr; }

◆ operator==() [2/5]

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

Definition at line 443 of file substr.hpp.

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

◆ operator!=() [2/5]

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

Definition at line 444 of file substr.hpp.

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

◆ operator<() [1/4]

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

Definition at line 445 of file substr.hpp.

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

◆ operator>() [1/4]

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

Definition at line 446 of file substr.hpp.

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

◆ operator<=() [1/4]

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

Definition at line 447 of file substr.hpp.

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

◆ operator>=() [1/4]

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

Definition at line 448 of file substr.hpp.

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

◆ operator==() [3/5]

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

Definition at line 450 of file substr.hpp.

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

◆ operator!=() [3/5]

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

Definition at line 451 of file substr.hpp.

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

◆ operator<() [2/4]

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

Definition at line 452 of file substr.hpp.

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

◆ operator>() [2/4]

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

Definition at line 453 of file substr.hpp.

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

◆ operator<=() [2/4]

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

Definition at line 454 of file substr.hpp.

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

◆ operator>=() [2/4]

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

Definition at line 455 of file substr.hpp.

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

◆ operator==() [4/5]

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

Definition at line 457 of file substr.hpp.

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

◆ operator!=() [4/5]

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

Definition at line 458 of file substr.hpp.

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

◆ operator<() [3/4]

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

Definition at line 459 of file substr.hpp.

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

◆ operator>() [3/4]

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

Definition at line 460 of file substr.hpp.

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

◆ operator<=() [3/4]

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

Definition at line 461 of file substr.hpp.

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

◆ operator>=() [3/4]

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

Definition at line 462 of file substr.hpp.

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

◆ operator==() [5/5]

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

Definition at line 464 of file substr.hpp.

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

◆ operator!=() [5/5]

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

Definition at line 465 of file substr.hpp.

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

◆ operator<() [4/4]

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

Definition at line 466 of file substr.hpp.

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

◆ operator>() [4/4]

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

Definition at line 467 of file substr.hpp.

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

◆ operator<=() [4/4]

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

Definition at line 468 of file substr.hpp.

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

◆ operator>=() [4/4]

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

Definition at line 469 of file substr.hpp.

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

◆ is_sub()

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

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

Definition at line 479 of file substr.hpp.

480 {
481 return that.is_super(*this);
482 }
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:485

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

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

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

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

◆ sub() [1/2]

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

return [first,len[

Definition at line 503 of file substr.hpp.

504 {
505 C4_ASSERT(first >= 0 && first <= len);
506 return basic_substring(str + first, len - first);
507 }
constexpr basic_substring() noexcept
Definition substr.hpp:255
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
Definition substr.hpp:530

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

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

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

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

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

531 {
532 C4_ASSERT(num <= len || num == npos);
533 return basic_substring(str, num != npos ? num : len);
534 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ triml() [1/2]

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

trim left

Definition at line 630 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ begins_with() [1/3]

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

true if the first character of the string is c

Definition at line 851 of file substr.hpp.

852 {
854 #if defined(__GNUC__) && (__GNUC__ >= 6)
855 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
856 #endif
857 return len && str[0] == c;
859 }

◆ begins_with() [2/3]

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

true if the first num characters of the string are c

Definition at line 862 of file substr.hpp.

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

◆ begins_with() [3/3]

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

true if the string begins with the given pattern

Definition at line 873 of file substr.hpp.

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

◆ begins_with_any()

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

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

Definition at line 884 of file substr.hpp.

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

◆ ends_with() [1/3]

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

true if the last character of the string is c

Definition at line 895 of file substr.hpp.

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

◆ ends_with() [2/3]

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

true if the last num characters of the string are c

Definition at line 901 of file substr.hpp.

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

◆ ends_with() [3/3]

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

true if the string ends with the given pattern

Definition at line 912 of file substr.hpp.

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

◆ ends_with_any()

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

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

Definition at line 923 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ pair_range_nested()

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

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

No checks for escapes are performed.

Definition at line 1172 of file substr.hpp.

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

◆ unquoted()

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

Definition at line 1195 of file substr.hpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1291 {
1293 if(ne.empty())
1294 return ne;
1295 size_t skip_start = size_t(ne.str[0] == '+' || ne.str[0] == '-');
1297 }

◆ _first_integral_span()

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

Definition at line 1299 of file substr.hpp.

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

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

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

◆ _is_delim_char()

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

true if the character is a delimiter character at the end

Definition at line 1420 of file substr.hpp.

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

◆ _is_hex_char()

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

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

Definition at line 1428 of file substr.hpp.

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

◆ _word_follows()

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

Definition at line 1433 of file substr.hpp.

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

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

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

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

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

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

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

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

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

◆ next_split()

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

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

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

Definition at line 1810 of file substr.hpp.

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

◆ split()

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

a view into the splits

Definition at line 1913 of file substr.hpp.

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

◆ pop_right()

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

pop right: return the first split from the right.

Use gpop_left() to get the reciprocal part.

Definition at line 1926 of file substr.hpp.

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

◆ pop_left()

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

return the first split from the left.

Use gpop_right() to get the reciprocal part.

Definition at line 1979 of file substr.hpp.

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

◆ gpop_left()

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

greedy pop left.

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

Definition at line 2034 of file substr.hpp.

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

◆ gpop_right()

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

greedy pop right.

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

Definition at line 2056 of file substr.hpp.

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

◆ basename()

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

Definition at line 2084 of file substr.hpp.

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

◆ dirname()

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

Definition at line 2091 of file substr.hpp.

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

◆ name_wo_extshort()

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

Definition at line 2098 of file substr.hpp.

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

◆ name_wo_extlong()

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

Definition at line 2103 of file substr.hpp.

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

◆ extshort()

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

Definition at line 2108 of file substr.hpp.

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

◆ extlong()

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

Definition at line 2113 of file substr.hpp.

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

◆ toupper()

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

convert the string to upper-case

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

Definition at line 2128 of file substr.hpp.

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

◆ tolower()

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

convert the string to lower-case

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

Definition at line 2140 of file substr.hpp.

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

◆ fill()

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

fill the entire contents with the given val

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

Definition at line 2154 of file substr.hpp.

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

◆ copy_from() [1/2]

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

copy a string to this substr, starting at 0

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

Definition at line 2166 of file substr.hpp.

2168 {
2170 size_t num = that.len <= len ? that.len : len;
2171 // calling memcpy with zero len is undefined behavior
2172 // and will wreak havoc in calling code's branches.
2173 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
2174 if(num)
2175 memcpy(str, that.str, sizeof(C) * num);
2176 }
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:494

◆ copy_from() [2/2]

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

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

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

Definition at line 2181 of file substr.hpp.

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

◆ reverse()

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

reverse in place

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

Definition at line 2200 of file substr.hpp.

2202 {
2203 if(len == 0) return;
2205 }

◆ reverse_sub()

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

revert a subpart in place

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

Definition at line 2210 of file substr.hpp.

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

◆ reverse_range()

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

revert a range in place

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

Definition at line 2222 of file substr.hpp.

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

◆ erase() [1/2]

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

erase part of the string.

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

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

Definition at line 2237 of file substr.hpp.

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

◆ erase_range()

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

Definition at line 2248 of file substr.hpp.

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

◆ erase() [2/2]

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

erase a part of the string.

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

Definition at line 2259 of file substr.hpp.

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

◆ replace() [1/2]

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

replace every occurrence of character value with the character repl

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

Definition at line 2273 of file substr.hpp.

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

◆ replace() [2/2]

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

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

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

Definition at line 2291 of file substr.hpp.

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

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

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

Member Data Documentation

◆ str

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

a restricted pointer to the first character of the substring

Definition at line 216 of file substr.hpp.

◆ len

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

the length of the substring

Definition at line 218 of file substr.hpp.


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