cli11
Loading...
Searching...
No Matches
string_tools.cpp File Reference
module cli11

Low-level string manipulation shared across the library. More...

#include <cstdlib>
import std;

Functions

template<typename T>
requires std::is_enum_v<T>
auto cli::enums::operator<< (std::ostream &in, const T &item) -> std::ostream &
 Streams any enumeration as its underlying integer value.
constexpr auto cli::detail::hex_convert (char hc) -> std::uint32_t
 Converts a single hexadecimal digit to its value.
constexpr auto cli::detail::make_char (std::uint32_t code) -> char
 Truncates a code unit to a char without sign-extension surprises.
constexpr auto cli::detail::append_codepoint (std::string &str, std::uint32_t code) -> void
 Appends a Unicode code point to a string as UTF-8.
constexpr auto cli::detail::remove_outer (std::string &str, char key) -> std::string &
 Strips a matched pair of key characters from both ends.
constexpr auto cli::detail::close_string_quote (const std::string &str, std::size_t start, char closure_char) -> std::size_t
 Finds the closing quote of a string literal, honouring backslash escapes.
constexpr auto cli::detail::close_literal_quote (const std::string &str, std::size_t start, char closure_char) -> std::size_t
 Finds the closing quote of a literal string, ignoring escapes.
constexpr auto cli::detail::handle_secondary_array (std::string &str) -> void
 Doubles every character of a bracketed sequence, marking it as nested.
auto cli::detail::split (const std::string &s, char delim) -> std::vector< std::string >
 Splits a string on a delimiter.
template<typename T>
auto cli::detail::join (const T &v, std::string_view delim=",") -> std::string
 Joins a range into a delimited string.
template<typename T, typename callable_t>
requires (!std::is_constructible_v<std::string, callable_t>)
auto cli::detail::join (const T &v, callable_t func, std::string_view delim=",") -> std::string
 Joins a range into a delimited string, transforming each element.
template<typename T>
auto cli::detail::rjoin (const T &v, std::string_view delim=",") -> std::string
 Joins a range into a delimited string in reverse order.
auto cli::detail::ltrim (std::string &str) -> std::string &
 Removes leading whitespace in place.
constexpr auto cli::detail::ltrim (std::string &str, std::string_view filter) -> std::string &
 Removes leading characters that appear in filter, in place.
auto cli::detail::rtrim (std::string &str) -> std::string &
 Removes trailing whitespace in place.
constexpr auto cli::detail::rtrim (std::string &str, std::string_view filter) -> std::string &
 Removes trailing characters that appear in filter, in place.
auto cli::detail::trim (std::string &str) -> std::string &
 Removes whitespace from both ends, in place.
constexpr auto cli::detail::trim (std::string &str, std::string_view filter) -> std::string &
 Removes characters in filter from both ends, in place.
auto cli::detail::trim_copy (const std::string &str) -> std::string
 Returns a copy with whitespace removed from both ends.
constexpr auto cli::detail::trim_copy (const std::string &str, std::string_view filter) -> std::string
 Returns a copy with characters in filter removed from both ends.
constexpr auto cli::detail::remove_quotes (std::string &str) -> std::string &
 Strips one matched pair of surrounding quotes, in place.
auto cli::detail::fix_newlines (const std::string &leader, std::string input) -> std::string
 Inserts leader after every newline.
auto cli::detail::format_aliases (std::ostream &out, const std::vector< std::string > &aliases, std::size_t wid) -> std::ostream &
 Writes an indented, comma-separated alias list.
template<typename T>
constexpr auto cli::detail::valid_first_char (T c) -> bool
 Tests whether a character may begin an option name.
template<typename T>
constexpr auto cli::detail::valid_later_char (T c) -> bool
 Tests whether a character may appear after the first in an option name.
constexpr auto cli::detail::valid_name_string (const std::string &str) -> bool
 Tests whether a string is a usable option or subcommand name.
constexpr auto cli::detail::valid_alias_name_string (const std::string &str) -> bool
 Tests whether a string is usable as an alias.
constexpr auto cli::detail::is_separator (const std::string &str) -> bool
 Tests whether an argument is a group separator.
auto cli::detail::isalpha (const std::string &str) -> bool
 Tests whether every character is alphabetic in the current locale.
auto cli::detail::to_lower (std::string str) -> std::string
 Returns a lowercased copy, using the current locale.
constexpr auto cli::detail::remove_underscore (std::string str) -> std::string
 Returns a copy with every underscore removed.
auto cli::detail::get_group_separators () -> std::string
 Returns the characters treated as digit-group separators.
constexpr auto cli::detail::find_and_replace (std::string str, std::string_view from, std::string_view to) -> std::string
 Replaces every occurrence of from with to.
constexpr auto cli::detail::has_default_flag_values (const std::string &flags) -> bool
 Tests whether a flag specification carries default values.
constexpr auto cli::detail::remove_default_flag_values (std::string &flags) -> void
 Strips {...} default values and ! negation markers, in place.
auto cli::detail::find_member (std::string name, const std::vector< std::string > &names, bool ignore_case=false, bool ignore_underscore=false) -> std::optional< std::size_t >
 Finds a name in a list, optionally ignoring case and underscores.
template<typename callable_t>
auto cli::detail::find_and_modify (std::string str, std::string_view trigger, callable_t modify) -> std::string
 Repeatedly applies modify at each occurrence of trigger.
constexpr auto cli::detail::has_escapable_character (const std::string &str) -> bool
 Tests whether a string contains a character needing an escape.
constexpr auto cli::detail::add_escaped_characters (const std::string &str) -> std::string
 Returns a copy with backslash escapes applied.
constexpr auto cli::detail::remove_escaped_characters (const std::string &str) -> std::string
 Returns a copy with backslash escapes resolved.
constexpr auto cli::detail::remove_quotes (std::vector< std::string > &args) -> void
 Strips surrounding quotes from every argument, in place.
constexpr auto cli::detail::close_sequence (const std::string &str, std::size_t start, char closure_char) -> std::size_t
 Finds the index closing a quoted or bracketed sequence.
auto cli::detail::split_up (std::string str, char delimiter='\0') -> std::vector< std::string >
 Splits a command line into arguments, respecting quotes and brackets.
constexpr auto cli::detail::escape_detect (std::string &str, std::size_t offset) -> std::size_t
 Neutralises a separator that begins a quoted value.
auto cli::detail::binary_escape_string (const std::string &string_to_escape, bool force=false) -> std::string
 Encodes non-printable characters as a binary-escaped string.
constexpr auto cli::detail::is_binary_escaped_string (const std::string &escaped_string) -> bool
 Tests whether a string carries the binary-escape wrapper.
constexpr auto cli::detail::extract_binary_string (const std::string &escaped_string) -> std::string
 Decodes a binary-escaped string.
constexpr auto cli::detail::process_quoted_string (std::string &str, char string_char='\"', char literal_char = '\'', bool disable_secondary_array_processing = false) -> bool
 Unwraps a quoted, literal, or binary-escaped string in place.
auto cli::detail::get_environment_value (const std::string &env_name) -> std::string
 Reads an environment variable.
auto cli::detail::stream_out_as_paragraph (std::ostream &out, const std::string &text, std::size_t paragraph_width, const std::string &line_prefix="", bool skip_prefix_on_first_line=false) -> std::ostream &
 Writes text word-wrapped to a fixed width, prefixing each line.
template<typename T>
requires std::is_enum_v<T>
auto cli::operator<< (std::ostream &in, const T &item) -> std::ostream &
 Streams any enumeration as its underlying integer value.

Variables

constexpr std::string_view cli::detail::escaped_chars = "\b\t\n\f\r\"\\"
 Characters that require a backslash escape.
constexpr std::string_view cli::detail::escaped_chars_code = "btnfr\"\\"
 Escape codes, index-aligned with escaped_chars.
constexpr std::string_view cli::detail::bracket_chars = "\"'`[(<{"
 Characters that open a quoted or bracketed sequence.
constexpr std::string_view cli::detail::match_bracket_chars = "\"'`])>}"
 Closing characters, index-aligned with bracket_chars.
constexpr int cli::detail::expected_max_vector_size {1 << 29}
 Upper bound on how many values a vector-like option may consume.

Detailed Description

Low-level string manipulation shared across the library.

Everything here is free-standing text processing: splitting, joining, trimming, quote handling, escape encoding and decoding, and the paragraph wrapper used by the help formatter. Nothing in this partition knows about options or applications.

Most helpers are constexpr. The ones that are not depend on std::locale or std::format, neither of which is usable during constant evaluation.

Function Documentation

◆ add_escaped_characters()

auto cli::detail::add_escaped_characters ( const std::string & str) -> std::string
constexprexport

Returns a copy with backslash escapes applied.

Parameters
strThe string to escape.
Returns
The escaped string.

◆ append_codepoint()

auto cli::detail::append_codepoint ( std::string & str,
std::uint32_t code ) -> void
constexpr

Appends a Unicode code point to a string as UTF-8.

Parameters
[in,out]strThe string to append to.
[in]codeThe code point to encode.
Exceptions
std::invalid_argumentIf code is a surrogate.

◆ binary_escape_string()

auto cli::detail::binary_escape_string ( const std::string & string_to_escape,
bool force = false ) -> std::string
export

Encodes non-printable characters as a binary-escaped string.

When anything is escaped, or when force is set, the result is wrapped as 'B"(...)"'.

Parameters
string_to_escapeThe string to encode.
forceWrap the result even when nothing needed escaping.
Returns
The encoded string.

◆ close_literal_quote()

auto cli::detail::close_literal_quote ( const std::string & str,
std::size_t start,
char closure_char ) -> std::size_t
constexpr

Finds the closing quote of a literal string, ignoring escapes.

Parameters
strThe text to scan.
startIndex of the opening quote.
closure_charThe quote character to match.
Returns
Index of the closing quote, or str.size() if unterminated.

◆ close_sequence()

auto cli::detail::close_sequence ( const std::string & str,
std::size_t start,
char closure_char ) -> std::size_t
constexprexport

Finds the index closing a quoted or bracketed sequence.

Nested brackets and quotes are tracked, so the returned index matches the opener at start rather than the first candidate encountered.

Parameters
strThe text to scan.
startIndex of the opening character.
closure_charThe character that closes the sequence.
Returns
Index of the closing character, or str.size() if unterminated.

◆ close_string_quote()

auto cli::detail::close_string_quote ( const std::string & str,
std::size_t start,
char closure_char ) -> std::size_t
constexpr

Finds the closing quote of a string literal, honouring backslash escapes.

Parameters
strThe text to scan.
startIndex of the opening quote.
closure_charThe quote character to match.
Returns
Index of the closing quote, or str.size() if unterminated.

◆ escape_detect()

auto cli::detail::escape_detect ( std::string & str,
std::size_t offset ) -> std::size_t
constexprexport

Neutralises a separator that begins a quoted value.

Parameters
[in,out]strThe text being scanned.
[in]offsetIndex of the candidate separator.
Returns
The index to resume scanning from.

◆ extract_binary_string()

auto cli::detail::extract_binary_string ( const std::string & escaped_string) -> std::string
constexprexport

Decodes a binary-escaped string.

Parameters
escaped_stringThe string to decode.
Returns
The decoded string, or escaped_string unchanged if it is not wrapped.

◆ find_and_modify()

template<typename callable_t>
auto cli::detail::find_and_modify ( std::string str,
std::string_view trigger,
callable_t modify ) -> std::string
export

Repeatedly applies modify at each occurrence of trigger.

Template Parameters
callable_tCallable taking the string and a position, returning the position to resume searching from.
Parameters
strThe string to rewrite.
triggerThe text to search for.
modifyApplied at each occurrence.
Returns
The rewritten string.

◆ find_and_replace()

auto cli::detail::find_and_replace ( std::string str,
std::string_view from,
std::string_view to ) -> std::string
constexprexport

Replaces every occurrence of from with to.

Parameters
strThe string to rewrite.
fromThe text to search for.
toThe replacement text.
Returns
The rewritten string.

◆ find_member()

auto cli::detail::find_member ( std::string name,
const std::vector< std::string > & names,
bool ignore_case = false,
bool ignore_underscore = false ) -> std::optional< std::size_t >
export

Finds a name in a list, optionally ignoring case and underscores.

Parameters
nameThe name to search for.
namesThe list to search.
ignore_caseCompare case-insensitively.
ignore_underscoreIgnore underscores on both sides of the comparison.
Returns
The index of the match, or std::nullopt if there is none.

◆ fix_newlines()

auto cli::detail::fix_newlines ( const std::string & leader,
std::string input ) -> std::string
export

Inserts leader after every newline.

Parameters
leaderThe text to insert after each line break.
inputThe text to reflow.
Returns
The reflowed text.

◆ format_aliases()

auto cli::detail::format_aliases ( std::ostream & out,
const std::vector< std::string > & aliases,
std::size_t wid ) -> std::ostream &
export

Writes an indented, comma-separated alias list.

Writes nothing when aliases is empty.

Parameters
outThe stream to write to.
aliasesThe aliases to list.
widField width for the leading label.
Returns
out, for chaining.

◆ get_environment_value()

auto cli::detail::get_environment_value ( const std::string & env_name) -> std::string
export

Reads an environment variable.

Parameters
env_nameThe variable to read.
Returns
The variable's value, or an empty string if it is not set.

◆ get_group_separators()

auto cli::detail::get_group_separators ( ) -> std::string
export

Returns the characters treated as digit-group separators.

Always includes _ and ', plus the locale's thousands separator.

Returns
The separator characters.

◆ handle_secondary_array()

auto cli::detail::handle_secondary_array ( std::string & str) -> void
constexpr

Doubles every character of a bracketed sequence, marking it as nested.

Parameters
[in,out]strThe string to rewrite in place; left alone unless it is bracketed with [ and ].

◆ has_default_flag_values()

auto cli::detail::has_default_flag_values ( const std::string & flags) -> bool
constexprexport

Tests whether a flag specification carries default values.

Parameters
flagsThe flag specification.
Returns
true if flags contains { or !.

◆ has_escapable_character()

auto cli::detail::has_escapable_character ( const std::string & str) -> bool
constexprexport

Tests whether a string contains a character needing an escape.

Parameters
strThe string to test.
Returns
true if any character appears in escaped_chars.

◆ hex_convert()

auto cli::detail::hex_convert ( char hc) -> std::uint32_t
constexpr

Converts a single hexadecimal digit to its value.

Parameters
hcA hexadecimal digit, in either case.
Returns
The digit's value, or a value greater than 0x0F if hc is not a hexadecimal digit.

◆ is_binary_escaped_string()

auto cli::detail::is_binary_escaped_string ( const std::string & escaped_string) -> bool
constexprexport

Tests whether a string carries the binary-escape wrapper.

Parameters
escaped_stringThe string to test.
Returns
true if escaped_string is wrapped as B"(...)" or 'B"(...)"'.

◆ is_separator()

auto cli::detail::is_separator ( const std::string & str) -> bool
constexprexport

Tests whether an argument is a group separator.

Parameters
strThe argument to test.
Returns
true for an empty string or "%%".

◆ isalpha()

auto cli::detail::isalpha ( const std::string & str) -> bool
export

Tests whether every character is alphabetic in the current locale.

Parameters
strThe string to test.
Returns
true if str is entirely alphabetic.

◆ join() [1/2]

template<typename T, typename callable_t>
requires (!std::is_constructible_v<std::string, callable_t>)
auto cli::detail::join ( const T & v,
callable_t func,
std::string_view delim = "," ) -> std::string
export

Joins a range into a delimited string, transforming each element.

Template Parameters
TAny range.
callable_tAny callable mapping an element to something streamable.
Parameters
vThe range to join.
funcApplied to each element before it is written.
delimThe separator placed between elements.
Returns
The joined string.

◆ join() [2/2]

template<typename T>
auto cli::detail::join ( const T & v,
std::string_view delim = "," ) -> std::string
export

Joins a range into a delimited string.

A single trailing delimiter is stripped from the result.

Template Parameters
TAny range whose elements are streamable.
Parameters
vThe range to join.
delimThe separator placed between elements.
Returns
The joined string.

◆ ltrim() [1/2]

auto cli::detail::ltrim ( std::string & str) -> std::string &
export

Removes leading whitespace in place.

Parameters
[in,out]strThe string to trim.
Returns
A reference to str.

◆ ltrim() [2/2]

auto cli::detail::ltrim ( std::string & str,
std::string_view filter ) -> std::string &
constexprexport

Removes leading characters that appear in filter, in place.

Parameters
[in,out]strThe string to trim.
[in]filterThe set of characters to strip.
Returns
A reference to str.

◆ make_char()

auto cli::detail::make_char ( std::uint32_t code) -> char
constexpr

Truncates a code unit to a char without sign-extension surprises.

Parameters
codeThe value to narrow.
Returns
The low byte of code, as a char.

◆ operator<<() [1/2]

template<typename T>
requires std::is_enum_v<T>
auto cli::enums::operator<< ( std::ostream & in,
const T & item ) -> std::ostream &
export

Streams any enumeration as its underlying integer value.

Template Parameters
TAny enumeration type.
Parameters
inThe stream to write to.
itemThe enumerator to write.
Returns
in, for chaining.

◆ operator<<() [2/2]

template<typename T>
requires std::is_enum_v<T>
auto cli::enums::operator<< ( std::ostream & in,
const T & item ) -> std::ostream &

Streams any enumeration as its underlying integer value.

Template Parameters
TAny enumeration type.
Parameters
inThe stream to write to.
itemThe enumerator to write.
Returns
in, for chaining.

◆ process_quoted_string()

auto cli::detail::process_quoted_string ( std::string & str,
char string_char = '\"',
char literal_char = '\'',
bool disable_secondary_array_processing = false ) -> bool
constexprexport

Unwraps a quoted, literal, or binary-escaped string in place.

Parameters
[in,out]strThe string to unwrap.
[in]string_charThe character delimiting escaped strings.
[in]literal_charThe character delimiting literal strings.
[in]disable_secondary_array_processingSkip the nested-array rewrite.
Returns
true if str was wrapped and has been unwrapped.

◆ remove_default_flag_values()

auto cli::detail::remove_default_flag_values ( std::string & flags) -> void
constexprexport

Strips {...} default values and ! negation markers, in place.

Parameters
[in,out]flagsThe flag specification to rewrite.

◆ remove_escaped_characters()

auto cli::detail::remove_escaped_characters ( const std::string & str) -> std::string
constexprexport

Returns a copy with backslash escapes resolved.

Understands the codes in escaped_chars_code, \\0, and the \\uXXXX and \\UXXXXXXXX Unicode forms.

Parameters
strThe string to unescape.
Returns
The unescaped string.
Exceptions
std::invalid_argumentIf an escape sequence is truncated or unknown.

◆ remove_outer()

auto cli::detail::remove_outer ( std::string & str,
char key ) -> std::string &
constexpr

Strips a matched pair of key characters from both ends.

Parameters
[in,out]strThe string to strip in place.
[in]keyThe character to remove.
Returns
A reference to str.

◆ remove_quotes() [1/2]

auto cli::detail::remove_quotes ( std::string & str) -> std::string &
constexprexport

Strips one matched pair of surrounding quotes, in place.

Recognises ", ' and ` .

Parameters
[in,out]strThe string to unquote.
Returns
A reference to str.

◆ remove_quotes() [2/2]

auto cli::detail::remove_quotes ( std::vector< std::string > & args) -> void
constexprexport

Strips surrounding quotes from every argument, in place.

Double-quoted arguments additionally have their escapes resolved.

Parameters
[in,out]argsThe arguments to unquote.

◆ remove_underscore()

auto cli::detail::remove_underscore ( std::string str) -> std::string
constexprexport

Returns a copy with every underscore removed.

Parameters
strThe string to strip.
Returns
The stripped string.

◆ rjoin()

template<typename T>
auto cli::detail::rjoin ( const T & v,
std::string_view delim = "," ) -> std::string
export

Joins a range into a delimited string in reverse order.

Template Parameters
TAny bidirectional range whose elements are streamable.
Parameters
vThe range to join.
delimThe separator placed between elements.
Returns
The joined string.

◆ rtrim() [1/2]

auto cli::detail::rtrim ( std::string & str) -> std::string &
export

Removes trailing whitespace in place.

Parameters
[in,out]strThe string to trim.
Returns
A reference to str.

◆ rtrim() [2/2]

auto cli::detail::rtrim ( std::string & str,
std::string_view filter ) -> std::string &
constexprexport

Removes trailing characters that appear in filter, in place.

Parameters
[in,out]strThe string to trim.
[in]filterThe set of characters to strip.
Returns
A reference to str.

◆ split()

auto cli::detail::split ( const std::string & s,
char delim ) -> std::vector< std::string >
export

Splits a string on a delimiter.

An empty input yields a single empty element.

Parameters
sThe string to split.
delimThe delimiter to split on.
Returns
The resulting elements.
Note
This deliberately keeps the std::getline formulation rather than moving to std::views::split. The two disagree on trailing delimiters: "a,b," yields two elements here and three under views::split.

◆ split_up()

auto cli::detail::split_up ( std::string str,
char delimiter = '\0' ) -> std::vector< std::string >
export

Splits a command line into arguments, respecting quotes and brackets.

Parameters
strThe text to split.
delimiterSeparator to split on; '\0' splits on whitespace.
Returns
The extracted arguments.

◆ stream_out_as_paragraph()

auto cli::detail::stream_out_as_paragraph ( std::ostream & out,
const std::string & text,
std::size_t paragraph_width,
const std::string & line_prefix = "",
bool skip_prefix_on_first_line = false ) -> std::ostream &
export

Writes text word-wrapped to a fixed width, prefixing each line.

Existing line breaks in text are preserved; each resulting line is then wrapped independently.

Parameters
outThe stream to write to.
textThe text to wrap.
paragraph_widthMaximum characters per line, excluding the prefix.
line_prefixWritten at the start of each line.
skip_prefix_on_first_lineOmit the prefix on the first line.
Returns
out, for chaining.

◆ to_lower()

auto cli::detail::to_lower ( std::string str) -> std::string
export

Returns a lowercased copy, using the current locale.

Parameters
strThe string to convert.
Returns
The lowercased string.

◆ trim() [1/2]

auto cli::detail::trim ( std::string & str) -> std::string &
export

Removes whitespace from both ends, in place.

Parameters
[in,out]strThe string to trim.
Returns
A reference to str.

◆ trim() [2/2]

auto cli::detail::trim ( std::string & str,
std::string_view filter ) -> std::string &
constexprexport

Removes characters in filter from both ends, in place.

Parameters
[in,out]strThe string to trim.
[in]filterThe set of characters to strip.
Returns
A reference to str.

◆ trim_copy() [1/2]

auto cli::detail::trim_copy ( const std::string & str) -> std::string
export

Returns a copy with whitespace removed from both ends.

Parameters
strThe string to trim.
Returns
The trimmed copy.

◆ trim_copy() [2/2]

auto cli::detail::trim_copy ( const std::string & str,
std::string_view filter ) -> std::string
constexprexport

Returns a copy with characters in filter removed from both ends.

Parameters
strThe string to trim.
filterThe set of characters to strip.
Returns
The trimmed copy.

◆ valid_alias_name_string()

auto cli::detail::valid_alias_name_string ( const std::string & str) -> bool
constexprexport

Tests whether a string is usable as an alias.

Aliases are unrestricted apart from newlines and embedded nulls.

Parameters
strThe candidate alias.
Returns
true if str contains neither a newline nor a null.

◆ valid_first_char()

template<typename T>
auto cli::detail::valid_first_char ( T c) -> bool
constexprexport

Tests whether a character may begin an option name.

Template Parameters
TA character type.
Parameters
cThe character to test.
Returns
true if c is a valid leading character.

◆ valid_later_char()

template<typename T>
auto cli::detail::valid_later_char ( T c) -> bool
constexprexport

Tests whether a character may appear after the first in an option name.

Template Parameters
TA character type.
Parameters
cThe character to test.
Returns
true if c is a valid subsequent character.

◆ valid_name_string()

auto cli::detail::valid_name_string ( const std::string & str) -> bool
constexprexport

Tests whether a string is a usable option or subcommand name.

Parameters
strThe candidate name.
Returns
true if every character is permitted in its position.

Variable Documentation

◆ bracket_chars

std::string_view cli::detail::bracket_chars = "\"'`[(<{"
constexpr

Characters that open a quoted or bracketed sequence.

Index-aligned with match_bracket_chars: the closing character for bracket_chars[i] is match_bracket_chars[i].

◆ escaped_chars

std::string_view cli::detail::escaped_chars = "\b\t\n\f\r\"\\"
constexpr

Characters that require a backslash escape.

Index-aligned with escaped_chars_code: the escape code for escaped_chars[i] is escaped_chars_code[i].