Loading...
Searching...
No Matches
StringTools.hpp
Go to the documentation of this file.
// Copyright (c) 2017-2025, University of Cincinnati, developed by Henry Schreiner
// under NSF AWARD 1414736 and by the respective contributors.
// All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
// IWYU pragma: private, include "CLI/CLI.hpp"
// [CLI11:public_includes:set]
#include <algorithm>
#include <iomanip>
#include <locale>
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
// [CLI11:public_includes:end]
#include "Macros.hpp"
namespace CLI {
// [CLI11:string_tools_hpp:verbatim]
namespace enums {
template <typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
std::ostream &operator<<(std::ostream &in, const T &item) {
// make sure this is out of the detail namespace otherwise it won't be found when needed
// https://isocpp.org/wiki/faq/input-output#print-char-or-ptr-as-number
return in << +static_cast<typename std::underlying_type<T>::type>(item);
}
} // namespace enums
using enums::operator<<;
namespace detail {
constexpr int expected_max_vector_size{1 << 29};
// Based on http://stackoverflow.com/questions/236129/split-a-string-in-c
CLI11_INLINE std::vector<std::string> split(const std::string &s, char delim);
template <typename T> std::string join(const T &v, std::string delim = ",") {
std::ostringstream s;
auto beg = std::begin(v);
auto end = std::end(v);
if(beg != end)
s << *beg++;
while(beg != end) {
s << delim << *beg++;
}
auto rval = s.str();
if(!rval.empty() && delim.size() == 1 && rval.back() == delim[0]) {
// remove trailing delimiter if the last entry was empty
rval.pop_back();
}
return rval;
}
template <typename T,
typename Callable,
typename = typename std::enable_if<!std::is_constructible<std::string, Callable>::value>::type>
std::string join(const T &v, Callable func, std::string delim = ",") {
std::ostringstream s;
auto beg = std::begin(v);
auto end = std::end(v);
auto loc = s.tellp();
while(beg != end) {
auto nloc = s.tellp();
if(nloc > loc) {
s << delim;
loc = nloc;
}
s << func(*beg++);
}
return s.str();
}
template <typename T> std::string rjoin(const T &v, std::string delim = ",") {
std::ostringstream s;
for(std::size_t start = 0; start < v.size(); start++) {
if(start > 0)
s << delim;
s << v[v.size() - start - 1];
}
return s.str();
}
// Based roughly on http://stackoverflow.com/questions/25829143/c-trim-whitespace-from-a-string
CLI11_INLINE std::string &ltrim(std::string &str);
CLI11_INLINE std::string &ltrim(std::string &str, const std::string &filter);
CLI11_INLINE std::string &rtrim(std::string &str);
CLI11_INLINE std::string &rtrim(std::string &str, const std::string &filter);
inline std::string &trim(std::string &str) { return ltrim(rtrim(str)); }
inline std::string &trim(std::string &str, const std::string filter) { return ltrim(rtrim(str, filter), filter); }
inline std::string trim_copy(const std::string &str) {
std::string s = str;
return trim(s);
}
CLI11_INLINE std::string &remove_quotes(std::string &str);
CLI11_INLINE void remove_quotes(std::vector<std::string> &args);
CLI11_INLINE std::string fix_newlines(const std::string &leader, std::string input);
inline std::string trim_copy(const std::string &str, const std::string &filter) {
std::string s = str;
return trim(s, filter);
}
CLI11_INLINE std::ostream &format_aliases(std::ostream &out, const std::vector<std::string> &aliases, std::size_t wid);
template <typename T> bool valid_first_char(T c) {
return ((c != '-') && (static_cast<unsigned char>(c) > 33)); // space and '!' not allowed
}
template <typename T> bool valid_later_char(T c) {
// = and : are value separators, { has special meaning for option defaults,
// and control codes other than tab would just be annoying to deal with in many places allowing space here has too
// much potential for inadvertent entry errors and bugs
return ((c != '=') && (c != ':') && (c != '{') && ((static_cast<unsigned char>(c) > 32) || c == '\t'));
}
CLI11_INLINE bool valid_name_string(const std::string &str);
inline bool valid_alias_name_string(const std::string &str) {
return ((str.find_first_of('\n') == std::string::npos) && (str.find_first_of('\0') == std::string::npos));
}
inline bool is_separator(const std::string &str) {
return (str.empty() || (str.size() == 2 && str[0] == '%' && str[1] == '%'));
}
inline bool isalpha(const std::string &str) {
return std::all_of(str.begin(), str.end(), [](char c) { return std::isalpha(c, std::locale()); });
}
inline std::string to_lower(std::string str) {
std::transform(std::begin(str), std::end(str), std::begin(str), [](const std::string::value_type &x) {
return std::tolower(x, std::locale());
});
return str;
}
inline std::string remove_underscore(std::string str) {
str.erase(std::remove(std::begin(str), std::end(str), '_'), std::end(str));
return str;
}
CLI11_INLINE std::string get_group_separators();
CLI11_INLINE std::string find_and_replace(std::string str, std::string from, std::string to);
inline bool has_default_flag_values(const std::string &flags) {
return (flags.find_first_of("{!") != std::string::npos);
}
CLI11_INLINE void remove_default_flag_values(std::string &flags);
CLI11_INLINE std::ptrdiff_t find_member(std::string name,
const std::vector<std::string> names,
bool ignore_case = false,
bool ignore_underscore = false);
template <typename Callable> inline std::string find_and_modify(std::string str, std::string trigger, Callable modify) {
std::size_t start_pos = 0;
while((start_pos = str.find(trigger, start_pos)) != std::string::npos) {
start_pos = modify(str, start_pos);
}
return str;
}
CLI11_INLINE std::size_t close_sequence(const std::string &str, std::size_t start, char closure_char);
CLI11_INLINE std::vector<std::string> split_up(std::string str, char delimiter = '\0');
CLI11_INLINE std::string get_environment_value(const std::string &env_name);
CLI11_INLINE std::size_t escape_detect(std::string &str, std::size_t offset);
CLI11_INLINE bool has_escapable_character(const std::string &str);
CLI11_INLINE std::string add_escaped_characters(const std::string &str);
CLI11_INLINE std::string remove_escaped_characters(const std::string &str);
CLI11_INLINE std::string binary_escape_string(const std::string &string_to_escape, bool force = false);
CLI11_INLINE bool is_binary_escaped_string(const std::string &escaped_string);
CLI11_INLINE std::string extract_binary_string(const std::string &escaped_string);
CLI11_INLINE bool process_quoted_string(std::string &str,
char string_char = '\"',
char literal_char = '\'',
bool disable_secondary_array_processing = false);
CLI11_INLINE std::ostream &streamOutAsParagraph(std::ostream &out,
const std::string &text,
std::size_t paragraphWidth,
const std::string &linePrefix = "",
bool skipPrefixOnFirstLine = false);
} // namespace detail
// [CLI11:string_tools_hpp:end]
} // namespace CLI
#ifndef CLI11_COMPILE
#include "impl/StringTools_inl.hpp" // IWYU pragma: export
#endif
Macros.hpp
CLI11_INLINE
#define CLI11_INLINE
Definition Macros.hpp:176
CLI::detail::fix_newlines
CLI11_INLINE std::string fix_newlines(const std::string &leader, std::string input)
CLI::detail::is_binary_escaped_string
CLI11_INLINE bool is_binary_escaped_string(const std::string &escaped_string)
CLI::detail::remove_default_flag_values
CLI11_INLINE void remove_default_flag_values(std::string &flags)
CLI::detail::valid_first_char
bool valid_first_char(T c)
Definition StringTools.hpp:151
CLI::detail::find_and_replace
CLI11_INLINE std::string find_and_replace(std::string str, std::string from, std::string to)
Find and replace a substring with another substring.
CLI::detail::add_escaped_characters
CLI11_INLINE std::string add_escaped_characters(const std::string &str)
escape all escapable characters
CLI::detail::process_quoted_string
CLI11_INLINE bool process_quoted_string(std::string &str, char string_char='\"', char literal_char = '\'', bool disable_secondary_array_processing = false)
process a quoted string, remove the quotes and if appropriate handle escaped characters
CLI::detail::get_group_separators
CLI11_INLINE std::string get_group_separators()
get valid group separators _' + local separator if different
CLI::detail::split
CLI11_INLINE std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
CLI::detail::remove_underscore
std::string remove_underscore(std::string str)
remove underscores from a string
Definition StringTools.hpp:190
CLI::detail::is_separator
bool is_separator(const std::string &str)
check if a string is a container segment separator (empty or "%%")
Definition StringTools.hpp:172
CLI::detail::find_and_modify
std::string find_and_modify(std::string str, std::string trigger, Callable modify)
Definition StringTools.hpp:217
CLI::detail::trim_copy
std::string trim_copy(const std::string &str)
Make a copy of the string and then trim it.
Definition StringTools.hpp:123
CLI::detail::ltrim
CLI11_INLINE std::string & ltrim(std::string &str)
Trim whitespace from left of string.
CLI::detail::trim
std::string & trim(std::string &str)
Trim whitespace from string.
Definition StringTools.hpp:117
CLI::detail::valid_later_char
bool valid_later_char(T c)
Verify following characters of an option.
Definition StringTools.hpp:156
CLI::detail::escape_detect
CLI11_INLINE std::size_t escape_detect(std::string &str, std::size_t offset)
CLI::detail::expected_max_vector_size
constexpr int expected_max_vector_size
Definition StringTools.hpp:48
CLI::detail::join
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition StringTools.hpp:54
CLI::detail::remove_quotes
CLI11_INLINE std::string & remove_quotes(std::string &str)
remove quotes at the front and back of a string either '"' or '\''
CLI::detail::streamOutAsParagraph
CLI11_INLINE std::ostream & streamOutAsParagraph(std::ostream &out, const std::string &text, std::size_t paragraphWidth, const std::string &linePrefix="", bool skipPrefixOnFirstLine=false)
CLI::detail::format_aliases
CLI11_INLINE std::ostream & format_aliases(std::ostream &out, const std::vector< std::string > &aliases, std::size_t wid)
Print subcommand aliases.
CLI::detail::valid_alias_name_string
bool valid_alias_name_string(const std::string &str)
Verify an app name.
Definition StringTools.hpp:167
CLI::detail::isalpha
bool isalpha(const std::string &str)
Verify that str consists of letters only.
Definition StringTools.hpp:177
CLI::detail::find_member
CLI11_INLINE std::ptrdiff_t find_member(std::string name, const std::vector< std::string > names, bool ignore_case=false, bool ignore_underscore=false)
Check if a string is a member of a list of strings and optionally ignore case or ignore underscores.
CLI::detail::has_escapable_character
CLI11_INLINE bool has_escapable_character(const std::string &str)
detect if a string has escapable characters
CLI::detail::valid_name_string
CLI11_INLINE bool valid_name_string(const std::string &str)
Verify an option/subcommand name.
CLI::detail::remove_escaped_characters
CLI11_INLINE std::string remove_escaped_characters(const std::string &str)
replace the escaped characters with their equivalent
CLI::detail::to_lower
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition StringTools.hpp:182
CLI::detail::has_default_flag_values
bool has_default_flag_values(const std::string &flags)
check if the flag definitions has possible false flags
Definition StringTools.hpp:203
CLI::detail::rtrim
CLI11_INLINE std::string & rtrim(std::string &str)
Trim whitespace from right of string.
CLI::detail::rjoin
std::string rjoin(const T &v, std::string delim=",")
Join a string in reverse order.
Definition StringTools.hpp:92
CLI::detail::extract_binary_string
CLI11_INLINE std::string extract_binary_string(const std::string &escaped_string)
extract an escaped binary_string
CLI::detail::binary_escape_string
CLI11_INLINE std::string binary_escape_string(const std::string &string_to_escape, bool force=false)
generate a string with all non printable characters escaped to hex codes
CLI::enums
Definition StringTools.hpp:30
CLI::enums::operator<<
std::ostream & operator<<(std::ostream &in, const T &item)
output streaming for enumerations
Definition StringTools.hpp:34
CLI
Definition App.hpp:36
CLI::ignore_case
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
Definition ExtraValidators.hpp:404
CLI::ignore_underscore
std::string ignore_underscore(std::string item)
Helper function to allow ignore_underscore to be passed to IsMember or Transform.
Definition ExtraValidators.hpp:407