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