File indexing completed on 2025-12-15 10:11:14
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010
0011
0012 #include <algorithm>
0013 #include <iomanip>
0014 #include <locale>
0015 #include <sstream>
0016 #include <stdexcept>
0017 #include <string>
0018 #include <type_traits>
0019 #include <vector>
0020
0021
0022 #include "Macros.hpp"
0023
0024 namespace CLI {
0025
0026
0027
0028
0029
0030 namespace enums {
0031
0032
0033 template <typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
0034 std::ostream &operator<<(std::ostream &in, const T &item) {
0035
0036 return in << static_cast<typename std::underlying_type<T>::type>(item);
0037 }
0038
0039 }
0040
0041
0042 using enums::operator<<;
0043
0044 namespace detail {
0045
0046
0047 constexpr int expected_max_vector_size{1 << 29};
0048
0049
0050 CLI11_INLINE std::vector<std::string> split(const std::string &s, char delim);
0051
0052
0053 template <typename T> std::string join(const T &v, std::string delim = ",") {
0054 std::ostringstream s;
0055 auto beg = std::begin(v);
0056 auto end = std::end(v);
0057 if(beg != end)
0058 s << *beg++;
0059 while(beg != end) {
0060 s << delim << *beg++;
0061 }
0062 auto rval = s.str();
0063 if(!rval.empty() && delim.size() == 1 && rval.back() == delim[0]) {
0064
0065 rval.pop_back();
0066 }
0067 return rval;
0068 }
0069
0070
0071 template <typename T,
0072 typename Callable,
0073 typename = typename std::enable_if<!std::is_constructible<std::string, Callable>::value>::type>
0074 std::string join(const T &v, Callable func, std::string delim = ",") {
0075 std::ostringstream s;
0076 auto beg = std::begin(v);
0077 auto end = std::end(v);
0078 auto loc = s.tellp();
0079 while(beg != end) {
0080 auto nloc = s.tellp();
0081 if(nloc > loc) {
0082 s << delim;
0083 loc = nloc;
0084 }
0085 s << func(*beg++);
0086 }
0087 return s.str();
0088 }
0089
0090
0091 template <typename T> std::string rjoin(const T &v, std::string delim = ",") {
0092 std::ostringstream s;
0093 for(std::size_t start = 0; start < v.size(); start++) {
0094 if(start > 0)
0095 s << delim;
0096 s << v[v.size() - start - 1];
0097 }
0098 return s.str();
0099 }
0100
0101
0102
0103
0104 CLI11_INLINE std::string <rim(std::string &str);
0105
0106
0107 CLI11_INLINE std::string <rim(std::string &str, const std::string &filter);
0108
0109
0110 CLI11_INLINE std::string &rtrim(std::string &str);
0111
0112
0113 CLI11_INLINE std::string &rtrim(std::string &str, const std::string &filter);
0114
0115
0116 inline std::string &trim(std::string &str) { return ltrim(rtrim(str)); }
0117
0118
0119 inline std::string &trim(std::string &str, const std::string filter) { return ltrim(rtrim(str, filter), filter); }
0120
0121
0122 inline std::string trim_copy(const std::string &str) {
0123 std::string s = str;
0124 return trim(s);
0125 }
0126
0127
0128 CLI11_INLINE std::string &remove_quotes(std::string &str);
0129
0130
0131 CLI11_INLINE void remove_quotes(std::vector<std::string> &args);
0132
0133
0134
0135
0136
0137 CLI11_INLINE std::string fix_newlines(const std::string &leader, std::string input);
0138
0139
0140 inline std::string trim_copy(const std::string &str, const std::string &filter) {
0141 std::string s = str;
0142 return trim(s, filter);
0143 }
0144
0145
0146 CLI11_INLINE std::ostream &format_aliases(std::ostream &out, const std::vector<std::string> &aliases, std::size_t wid);
0147
0148
0149
0150 template <typename T> bool valid_first_char(T c) {
0151 return ((c != '-') && (static_cast<unsigned char>(c) > 33));
0152 }
0153
0154
0155 template <typename T> bool valid_later_char(T c) {
0156
0157
0158
0159 return ((c != '=') && (c != ':') && (c != '{') && ((static_cast<unsigned char>(c) > 32) || c == '\t'));
0160 }
0161
0162
0163 CLI11_INLINE bool valid_name_string(const std::string &str);
0164
0165
0166 inline bool valid_alias_name_string(const std::string &str) {
0167 static const std::string badChars(std::string("\n") + '\0');
0168 return (str.find_first_of(badChars) == std::string::npos);
0169 }
0170
0171
0172 inline bool is_separator(const std::string &str) {
0173 static const std::string sep("%%");
0174 return (str.empty() || str == sep);
0175 }
0176
0177
0178 inline bool isalpha(const std::string &str) {
0179 return std::all_of(str.begin(), str.end(), [](char c) { return std::isalpha(c, std::locale()); });
0180 }
0181
0182
0183 inline std::string to_lower(std::string str) {
0184 std::transform(std::begin(str), std::end(str), std::begin(str), [](const std::string::value_type &x) {
0185 return std::tolower(x, std::locale());
0186 });
0187 return str;
0188 }
0189
0190
0191 inline std::string remove_underscore(std::string str) {
0192 str.erase(std::remove(std::begin(str), std::end(str), '_'), std::end(str));
0193 return str;
0194 }
0195
0196
0197 CLI11_INLINE std::string find_and_replace(std::string str, std::string from, std::string to);
0198
0199
0200 inline bool has_default_flag_values(const std::string &flags) {
0201 return (flags.find_first_of("{!") != std::string::npos);
0202 }
0203
0204 CLI11_INLINE void remove_default_flag_values(std::string &flags);
0205
0206
0207 CLI11_INLINE std::ptrdiff_t find_member(std::string name,
0208 const std::vector<std::string> names,
0209 bool ignore_case = false,
0210 bool ignore_underscore = false);
0211
0212
0213
0214 template <typename Callable> inline std::string find_and_modify(std::string str, std::string trigger, Callable modify) {
0215 std::size_t start_pos = 0;
0216 while((start_pos = str.find(trigger, start_pos)) != std::string::npos) {
0217 start_pos = modify(str, start_pos);
0218 }
0219 return str;
0220 }
0221
0222
0223
0224 CLI11_INLINE std::size_t close_sequence(const std::string &str, std::size_t start, char closure_char);
0225
0226
0227
0228 CLI11_INLINE std::vector<std::string> split_up(std::string str, char delimiter = '\0');
0229
0230
0231 CLI11_INLINE std::string get_environment_value(const std::string &env_name);
0232
0233
0234
0235
0236
0237 CLI11_INLINE std::size_t escape_detect(std::string &str, std::size_t offset);
0238
0239
0240
0241
0242 CLI11_INLINE bool has_escapable_character(const std::string &str);
0243
0244
0245
0246
0247 CLI11_INLINE std::string add_escaped_characters(const std::string &str);
0248
0249
0250 CLI11_INLINE std::string remove_escaped_characters(const std::string &str);
0251
0252
0253 CLI11_INLINE std::string binary_escape_string(const std::string &string_to_escape);
0254
0255 CLI11_INLINE bool is_binary_escaped_string(const std::string &escaped_string);
0256
0257
0258 CLI11_INLINE std::string extract_binary_string(const std::string &escaped_string);
0259
0260
0261 CLI11_INLINE bool process_quoted_string(std::string &str, char string_char = '\"', char literal_char = '\'');
0262
0263
0264
0265 CLI11_INLINE std::ostream &streamOutAsParagraph(std::ostream &out,
0266 const std::string &text,
0267 std::size_t paragraphWidth,
0268 const std::string &linePrefix = "",
0269 bool skipPrefixOnFirstLine = false);
0270
0271 }
0272
0273
0274
0275 }
0276
0277 #ifndef CLI11_COMPILE
0278 #include "impl/StringTools_inl.hpp" // IWYU pragma: export
0279 #endif