30 #if defined CLI11_CPP17 && defined __has_include && !defined CLI11_HAS_FILESYSTEM 31 #if __has_include(<filesystem>) 33 #if defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 34 #define CLI11_HAS_FILESYSTEM 0 37 #if defined __cpp_lib_filesystem && __cpp_lib_filesystem >= 201703 38 #if defined _GLIBCXX_RELEASE && _GLIBCXX_RELEASE >= 9 39 #define CLI11_HAS_FILESYSTEM 1 40 #elif defined(__GLIBCXX__) 42 #define CLI11_HAS_FILESYSTEM 0 44 #define CLI11_HAS_FILESYSTEM 1 47 #define CLI11_HAS_FILESYSTEM 0 53 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 57 #include <sys/types.h> 84 std::function<std::string(std::string &)>
func_{[](std::string &) {
return std::string{}; }};
99 Validator(std::function<std::string(std::string &)> op, std::string validator_desc, std::string validator_name =
"")
101 name_(std::move(validator_name)) {}
104 func_ = std::move(op);
110 std::string retstring;
113 std::string value = str;
114 retstring =
func_(value);
116 retstring =
func_(str);
125 std::string value = str;
137 newval.
desc_function_ = [validator_desc]() {
return validator_desc; };
145 return std::string{};
149 name_ = std::move(validator_name);
155 newval.
name_ = std::move(validator_name);
201 newval._merge_description(*
this, other,
" AND ");
204 const std::function<std::string(std::string & filename)> &f1 =
func_;
205 const std::function<std::string(std::string & filename)> &f2 = other.
func_;
207 newval.
func_ = [f1, f2](std::string &input) {
208 std::string s1 = f1(input);
209 std::string s2 = f2(input);
210 if(!s1.empty() && !s2.empty())
211 return std::string(
"(") + s1 +
") AND (" + s2 +
")";
226 newval._merge_description(*
this, other,
" OR ");
229 const std::function<std::string(std::string &)> &f1 =
func_;
230 const std::function<std::string(std::string &)> &f2 = other.
func_;
232 newval.
func_ = [f1, f2](std::string &input) {
233 std::string s1 = f1(input);
234 std::string s2 = f2(input);
235 if(s1.empty() || s2.empty())
236 return std::string();
238 return std::string(
"(") + s1 +
") OR (" + s2 +
")";
251 return (!str.empty()) ? std::string(
"NOT ") + str : std::string{};
254 const std::function<std::string(std::string & res)> &f1 =
func_;
256 newval.
func_ = [f1, dfunc1](std::string &test) -> std::string {
257 std::string s1 = f1(test);
259 return std::string(
"check ") + dfunc1() +
" succeeded improperly";
261 return std::string{};
269 void _merge_description(
const Validator &val1,
const Validator &val2,
const std::string &merger) {
275 std::string f1 = dfunc1();
276 std::string f2 = dfunc2();
277 if((f1.empty()) || (f2.empty())) {
280 return std::string(1,
'(') + f1 +
')' + merger +
'(' + f2 +
')';
297 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 301 auto stat = std::filesystem::status(file, ec);
305 switch(stat.type()) {
306 case std::filesystem::file_type::none:
307 case std::filesystem::file_type::not_found:
309 case std::filesystem::file_type::directory:
311 case std::filesystem::file_type::symlink:
312 case std::filesystem::file_type::block:
313 case std::filesystem::file_type::character:
314 case std::filesystem::file_type::fifo:
315 case std::filesystem::file_type::socket:
316 case std::filesystem::file_type::regular:
317 case std::filesystem::file_type::unknown:
325 #if defined(_MSC_VER) 326 struct __stat64 buffer;
327 if(_stat64(file, &buffer) == 0) {
332 if(stat(file, &buffer) == 0) {
339 class ExistingFileValidator :
public Validator {
343 func_ = [](std::string &filename) {
344 auto path_result =
check_path(filename.c_str());
346 return "File does not exist: " + filename;
349 return "File is actually a directory: " + filename;
351 return std::string();
360 func_ = [](std::string &filename) {
361 auto path_result =
check_path(filename.c_str());
363 return "Directory does not exist: " + filename;
366 return "Directory is actually a file: " + filename;
368 return std::string();
377 func_ = [](std::string &filename) {
378 auto path_result =
check_path(filename.c_str());
380 return "Path does not exist: " + filename;
382 return std::string();
391 func_ = [](std::string &filename) {
392 auto path_result =
check_path(filename.c_str());
394 return "Path already exists: " + filename;
396 return std::string();
405 func_ = [](std::string &ip_addr) {
407 if(result.size() != 4) {
408 return std::string(
"Invalid IPV4 address must have four parts (") + ip_addr +
')';
411 for(
const auto &var : result) {
414 return std::string(
"Failed parsing number (") + var +
')';
416 if(num < 0 || num > 255) {
417 return std::string(
"Each IP number must be between 0 and 255 ") + var;
420 return std::string();
448 func_ = [](std::string &input_string) {
449 auto val = DesiredType();
451 return std::string(
"Failed parsing ") + input_string +
" as a " + detail::type_name<DesiredType>();
453 return std::string();
460 const TypeValidator<double>
Number(
"NUMBER");
469 template <
typename T>
470 Range(T min_val, T max_val,
const std::string &validator_name = std::string{}) :
Validator(validator_name) {
471 if(validator_name.empty()) {
472 std::stringstream out;
473 out << detail::type_name<T>() <<
" in [" << min_val <<
" - " << max_val <<
"]";
477 func_ = [min_val, max_val](std::string &input) {
480 if((!converted) || (val < min_val || val > max_val))
481 return std::string(
"Value ") + input +
" not in range " +
std::to_string(min_val) +
" to " +
484 return std::string{};
489 template <
typename T>
490 explicit Range(T max_val,
const std::string &validator_name = std::string{})
491 :
Range(static_cast<T>(0), max_val, validator_name) {}
495 const Range
NonNegativeNumber((std::numeric_limits<double>::max)(),
"NONNEGATIVE");
498 const Range
PositiveNumber((std::numeric_limits<double>::min)(), (std::numeric_limits<double>::max)(),
"POSITIVE");
507 template <
typename T>
Bound(T min_val, T max_val) {
508 std::stringstream out;
509 out << detail::type_name<T>() <<
" bounded to [" << min_val <<
" - " << max_val <<
"]";
512 func_ = [min_val, max_val](std::string &input) {
516 return std::string(
"Value ") + input +
" could not be converted";
520 else if(val > max_val)
523 return std::string{};
528 template <
typename T>
explicit Bound(T max_val) :
Bound(static_cast<T>(0), max_val) {}
532 template <
typename T,
548 std::string out(1,
'{');
558 template <
typename T> std::string
generate_map(
const T &map,
bool key_only =
false) {
561 std::string out(1,
'{');
564 [key_only](
const iteration_type_t &v) {
578 template <
typename C,
typename V>
struct has_find {
579 template <
typename CC,
typename VV>
580 static auto test(
int) -> decltype(std::declval<CC>().find(std::declval<VV>()), std::true_type());
581 template <
typename,
typename>
static auto test(...) -> decltype(std::false_type());
584 using type = std::integral_constant<bool, value>;
589 auto search(
const T &
set,
const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
592 auto it = std::find_if(std::begin(setref), std::end(setref), [&val](decltype(*std::begin(setref)) v) {
595 return {(it != std::end(setref)), it};
600 auto search(
const T &
set,
const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
602 auto it = setref.find(val);
603 return {(it != std::end(setref)), it};
607 template <
typename T,
typename V>
608 auto search(
const T &
set,
const V &val,
const std::function<V(V)> &filter_function)
609 -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
612 auto res =
search(
set, val);
613 if((res.first) || (!(filter_function))) {
618 auto it = std::find_if(std::begin(setref), std::end(setref), [&](decltype(*std::begin(setref)) v) {
620 a = filter_function(a);
623 return {(it != std::end(setref)), it};
630 template <
typename T>
631 inline typename std::enable_if<std::is_signed<T>::value, T>::type
overflowCheck(
const T &a,
const T &b) {
632 if((a > 0) == (b > 0)) {
633 return ((std::numeric_limits<T>::max)() / (std::abs)(a) < (std::abs)(b));
635 return ((std::numeric_limits<T>::min)() / (std::abs)(a) > -(std::abs)(b));
639 template <
typename T>
640 inline typename std::enable_if<!std::is_signed<T>::value, T>::type
overflowCheck(
const T &a,
const T &b) {
641 return ((std::numeric_limits<T>::max)() / a < b);
645 template <
typename T>
typename std::enable_if<std::is_integral<T>::value,
bool>::type
checked_multiply(T &a, T b) {
646 if(a == 0 || b == 0 || a == 1 || b == 1) {
650 if(a == (std::numeric_limits<T>::min)() || b == (std::numeric_limits<T>::min)()) {
661 template <
typename T>
662 typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
checked_multiply(T &a, T b) {
664 if(std::isinf(c) && !std::isinf(a) && !std::isinf(b)) {
678 template <
typename T,
typename... Args>
679 IsMember(std::initializer_list<T> values, Args &&...args)
680 :
IsMember(
std::vector<T>(values),
std::forward<Args>(args)...) {}
687 template <
typename T,
typename F>
explicit IsMember(T
set, F filter_function) {
698 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
705 func_ = [
set, filter_fn](std::string &input) {
721 return std::string{};
730 template <
typename T,
typename... Args>
733 std::forward<T>(set),
734 [filter_fn_1, filter_fn_2](
std::string a) {
return filter_fn_2(filter_fn_1(a)); },
739 template <
typename T>
using TransformPairs = std::vector<std::pair<std::string, T>>;
747 template <
typename... Args>
748 Transformer(std::initializer_list<std::pair<std::string, std::string>> values, Args &&...args)
756 template <
typename T,
typename F>
explicit Transformer(T mapping, F filter_function) {
759 "mapping must produce value pairs");
768 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
773 func_ = [mapping, filter_fn](std::string &input) {
776 return std::string();
786 return std::string{};
791 template <
typename T,
typename... Args>
794 std::forward<T>(mapping),
795 [filter_fn_1, filter_fn_2](
std::string a) {
return filter_fn_2(filter_fn_1(a)); },
805 template <
typename... Args>
806 CheckedTransformer(std::initializer_list<std::pair<std::string, std::string>> values, Args &&...args)
817 "mapping must produce value pairs");
827 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
829 auto tfunc = [mapping]() {
830 std::string out(
"value in ");
842 func_ = [mapping, tfunc, filter_fn](std::string &input) {
852 return std::string{};
857 if(output_string == input) {
858 return std::string();
862 return "Check " + input +
" " + tfunc() +
" FAILED";
867 template <
typename T,
typename... Args>
870 std::forward<T>(mapping),
871 [filter_fn_1, filter_fn_2](
std::string a) {
return filter_fn_2(filter_fn_1(a)); },
883 item.erase(std::remove(std::begin(item), std::end(item),
' '), std::end(item));
884 item.erase(std::remove(std::begin(item), std::end(item),
'\t'), std::end(item));
913 template <
typename Number>
916 const std::string &unit_name =
"UNIT") {
917 description(generate_description<Number>(unit_name, opts));
918 validate_mapping(mapping, opts);
921 func_ = [mapping, opts](std::string &input) -> std::string {
930 auto unit_begin = input.end();
931 while(unit_begin > input.begin() &&
std::isalpha(*(unit_begin - 1), std::locale())) {
935 std::string unit{unit_begin, input.end()};
936 input.resize(static_cast<std::size_t>(std::distance(input.begin(), unit_begin)));
947 throw ValidationError(std::string(
"Value ") + input +
" could not be converted to " +
948 detail::type_name<Number>());
955 auto it = mapping.find(unit);
956 if(it == mapping.end()) {
958 " unit not recognized. " 966 throw ValidationError(std::string(
"Value ") + input +
" could not be converted to " +
967 detail::type_name<Number>());
973 " factor would cause number overflow. Use smaller value.");
976 num =
static_cast<Number>(it->second);
988 template <
typename Number>
static void validate_mapping(std::map<std::string, Number> &mapping,
Options opts) {
989 for(
auto &kv : mapping) {
990 if(kv.first.empty()) {
1000 std::map<std::string, Number> lower_mapping;
1001 for(
auto &kv : mapping) {
1003 if(lower_mapping.count(s)) {
1004 throw ValidationError(std::string(
"Several matching lowercase unit representations are found: ") +
1009 mapping = std::move(lower_mapping);
1014 template <
typename Number>
static std::string generate_description(
const std::string &
name,
Options opts) {
1015 std::stringstream out;
1016 out << detail::type_name<Number>() <<
' ';
1020 out <<
'[' <<
name <<
']';
1050 description(
"SIZE [b, kb(=1000b), kib(=1024b), ...]");
1058 static std::map<std::string, result_t> init_mapping(
bool kb_is_1000) {
1059 std::map<std::string, result_t> m;
1060 result_t k_factor = kb_is_1000 ? 1000 : 1024;
1065 for(std::string p : {
"k",
"m",
"g",
"t",
"p",
"e"}) {
1077 static std::map<std::string, result_t> get_mapping(
bool kb_is_1000) {
1079 static auto m = init_mapping(
true);
1082 static auto m = init_mapping(
false);
1095 std::pair<std::string, std::string> vals;
1097 auto esp = commandline.find_first_of(
' ', 1);
1099 esp = commandline.find_first_of(
' ', esp + 1);
1100 if(esp == std::string::npos) {
1103 if(commandline[0] ==
'"' || commandline[0] ==
'\'' || commandline[0] ==
'`') {
1104 bool embeddedQuote =
false;
1105 auto keyChar = commandline[0];
1106 auto end = commandline.find_first_of(keyChar, 1);
1107 while((end != std::string::npos) && (commandline[end - 1] ==
'\\')) {
1108 end = commandline.find_first_of(keyChar, end + 1);
1109 embeddedQuote =
true;
1111 if(end != std::string::npos) {
1112 vals.first = commandline.substr(1, end - 1);
1115 vals.first =
find_and_replace(vals.first, std::string(
"\\") + keyChar, std::string(1, keyChar));
1118 esp = commandline.find_first_of(
' ', 1);
1121 esp = commandline.find_first_of(
' ', 1);
1127 if(vals.first.empty()) {
1128 vals.first = commandline.substr(0, esp);
1133 vals.second = (esp != std::string::npos) ? commandline.substr(esp + 1) : std::string{};
std::uint64_t result_t
Definition: Validators.hpp:1039
Definition: Validators.hpp:899
path_type
CLI enumeration of different file types.
Definition: Validators.hpp:295
std::string name_
The name for search purposes of the Validator.
Definition: Validators.hpp:86
std::enable_if< std::is_signed< T >::value, T >::type overflowCheck(const T &a, const T &b)
Do a check for overflow on signed numbers.
Definition: Validators.hpp:631
TypeValidator(const std::string &validator_name)
Definition: Validators.hpp:447
Options
Definition: Validators.hpp:905
Validate the input as a particular type.
Definition: Validators.hpp:445
ExistingDirectoryValidator()
Definition: Validators.hpp:359
const detail::NonexistentPathValidator NonexistentPath
Check for an non-existing path.
Definition: Validators.hpp:439
const std::string & get_name() const
Get the name of the Validator.
Definition: Validators.hpp:159
std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
Definition: StringTools.hpp:46
int get_application_index() const
Get the current value of the application index.
Definition: Validators.hpp:189
Range(T max_val, const std::string &validator_name=std::string{})
Range of one value is 0 to value.
Definition: Validators.hpp:490
Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost ...
Definition: TypeTools.hpp:97
enabler
Simple empty scoped class.
Definition: TypeTools.hpp:30
Check for an existing directory (returns error message if check fails)
Definition: Validators.hpp:357
Validator(std::string validator_desc)
Construct a Validator with just the description string.
Definition: Validators.hpp:97
bool non_modifying_
specify that a validator should not modify the input
Definition: Validators.hpp:92
const TypeValidator< double > Number("NUMBER")
Check for a number.
std::string ignore_space(std::string item)
Helper function to allow checks to ignore spaces to be passed to IsMember or Transform.
Definition: Validators.hpp:882
Produce a bounded range (factory). Min and max are inclusive.
Definition: Validators.hpp:501
std::string generate_set(const T &set)
Generate a string representation of a set.
Definition: Validators.hpp:545
Class wrapping some of the accessors of Validator.
Definition: Validators.hpp:286
TypeValidator()
Definition: Validators.hpp:456
Validator name(std::string validator_name) const
Specify the type string.
Definition: Validators.hpp:153
std::function< std::string(std::string)> filter_fn_t
Definition: Validators.hpp:675
AsNumberWithUnit(std::map< std::string, Number > mapping, Options opts=DEFAULT, const std::string &unit_name="UNIT")
Definition: Validators.hpp:914
Validator operator|(const Validator &other) const
Definition: Validators.hpp:223
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
Definition: Validators.hpp:876
Validator application_index(int app_index) const
Specify the application index of a validator.
Definition: Validators.hpp:183
IPV4Validator()
Definition: Validators.hpp:404
Check for an non-existing path.
Definition: Validators.hpp:388
AsSizeValue(bool kb_is_1000)
Definition: Validators.hpp:1048
std::function< std::string(std::string &)> func_
Definition: Validators.hpp:84
ExistingPathValidator()
Definition: Validators.hpp:376
auto smart_deref(T value) -> decltype(*value)
Definition: Validators.hpp:534
typename std::remove_const< value_type >::type first_type
Definition: TypeTools.hpp:99
Validate the given string is a legal ipv4 address.
Definition: Validators.hpp:402
bool lexical_cast(const std::string &input, T &output)
Integer conversion.
Definition: TypeTools.hpp:862
constexpr enabler dummy
An instance to use in EnableIf.
Definition: TypeTools.hpp:33
Definition: Validators.hpp:1037
std::string & ltrim(std::string &str)
Trim whitespace from left of string.
Definition: StringTools.hpp:109
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: TypeTools.hpp:269
std::integral_constant< bool, value > type
Definition: Validators.hpp:584
Definition: Validators.hpp:908
int application_index_
A Validator will only apply to an indexed value (-1 is all elements)
Definition: Validators.hpp:88
static const auto value
Definition: Validators.hpp:583
Definition: Validators.hpp:578
path_type check_path(const char *file) noexcept
get the type of the path from a file name
Definition: Validators.hpp:324
IsMember(T set, F filter_function)
Definition: Validators.hpp:687
Validator operator &(const Validator &other) const
Definition: Validators.hpp:198
const detail::IPV4Validator ValidIPV4
Check for an IP4 address.
Definition: Validators.hpp:442
Bound(T max_val)
Range of one value is 0 to value.
Definition: Validators.hpp:528
const detail::ExistingFileValidator ExistingFile
Check for existing file (returns error message if check fails)
Definition: Validators.hpp:430
std::string ignore_underscore(std::string item)
Helper function to allow ignore_underscore to be passed to IsMember or Transform. ...
Definition: Validators.hpp:879
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: StringTools.hpp:63
ExistingFileValidator()
Definition: Validators.hpp:342
Produce a range (factory). Min and max are inclusive.
Definition: Validators.hpp:463
Check for an existing path.
Definition: Validators.hpp:374
Validator description(std::string validator_desc) const
Specify the type string.
Definition: Validators.hpp:135
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size() { return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type > { static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count { static constexpr int value{is_mutable_container< T >::value ? expected_max_vector_size :type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min { static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type > { static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type > { static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type > { static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min() { return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min() { return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type > { static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min { static constexpr int value{is_mutable_container< T >::value ?((type_count< T >::value< expected_max_vector_size) ? type_count< T >::value :0) :type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count { static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type > { static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type > { static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type > { static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category :int { char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object { static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type > { static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type > { static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type > { static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type > { static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type > { static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type > { static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1) &&std::is_constructible< T, std::string >::value >::type > { static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type > { static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type > { static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type { using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type > { static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type > { static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type > { static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type > { static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value))>::type > { static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type > { static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name() { return "TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name() { return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name() { return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name() { std::string str=std::string(type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >))+','+tuple_name< T, I+1 >);if(str.back()==',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: TypeTools.hpp:773
std::string & rtrim(std::string &str)
Trim whitespace from right of string.
Definition: StringTools.hpp:123
static auto test(int) -> decltype(std::declval< CC >().find(std::declval< VV >()), std::true_type())
NonexistentPathValidator()
Definition: Validators.hpp:390
std::string get_description() const
Generate type description information for the Validator.
Definition: Validators.hpp:141
Bound(T min_val, T max_val)
Definition: Validators.hpp:507
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
Definition: Validators.hpp:589
std::pair< std::string, std::string > split_program_name(std::string commandline)
Definition: Validators.hpp:1093
const detail::ExistingPathValidator ExistingPath
Check for an existing path.
Definition: Validators.hpp:436
std::string & trim(std::string &str)
Trim whitespace from string.
Definition: StringTools.hpp:138
std::string remove_underscore(std::string str)
remove underscores from a string
Definition: StringTools.hpp:267
Validator(std::function< std::string(std::string &)> op, std::string validator_desc, std::string validator_name="")
Construct Validator from basic information.
Definition: Validators.hpp:99
Definition: Validators.hpp:906
Validator & name(std::string validator_name)
Specify the type string.
Definition: Validators.hpp:148
typename std::enable_if< B, T >::type enable_if_t
Definition: TypeTools.hpp:41
std::vector< std::pair< std::string, T > > TransformPairs
definition of the default transformation object
Definition: Validators.hpp:739
std::string operator()(std::string &str) const
Definition: Validators.hpp:109
IsMember(T &&set)
This checks to see if an item is in a set (empty function)
Definition: Validators.hpp:683
IsMember(std::initializer_list< T > values, Args &&...args)
This allows in-place construction using an initializer list.
Definition: Validators.hpp:679
Validator & application_index(int app_index)
Specify the application index of a validator.
Definition: Validators.hpp:178
Definition: Validators.hpp:910
IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&...other)
You can pass in as many filter functions as you like, they nest (string only currently) ...
Definition: Validators.hpp:731
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition: StringTools.hpp:259
Verify items are in a set.
Definition: Validators.hpp:673
static auto first(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the first value (really just the underlying value)
Definition: TypeTools.hpp:103
Some validators that are provided.
Definition: Validators.hpp:77
bool get_modifying() const
Get a boolean if the validator is allowed to modify the input returns true if it can modify the input...
Definition: Validators.hpp:194
Definition: Validators.hpp:907
bool active_
Enable for Validator to allow it to be disabled if need be.
Definition: Validators.hpp:90
Validator active(bool active_val=true) const
Specify whether the Validator is active or not.
Definition: Validators.hpp:166
const Range PositiveNumber((std::numeric_limits< double >::min)(),(std::numeric_limits< double >::max)(), "POSITIVE")
Check for a positive valued number (val>0.0), min() her is the smallest positive number.
std::string value_string(const T &value)
get a string as a convertible value for arithmetic types
Definition: TypeTools.hpp:336
const detail::ExistingDirectoryValidator ExistingDirectory
Check for an existing directory (returns error message if check fails)
Definition: Validators.hpp:433
T type
Definition: TypeTools.hpp:73
Check for an existing file (returns error message if check fails)
Definition: Validators.hpp:340
Validator & active(bool active_val=true)
Specify whether the Validator is active or not.
Definition: Validators.hpp:161
std::string find_and_replace(std::string str, std::string from, std::string to)
Find and replace a substring with another substring.
Definition: StringTools.hpp:273
Validator & operation(std::function< std::string(std::string &)> op)
Set the Validator operation function.
Definition: Validators.hpp:103
std::function< std::string()> desc_function_
This is the description function, if empty the description_ will be used.
Definition: Validators.hpp:80
std::string operator()(const std::string &str) const
Definition: Validators.hpp:124
const Range NonNegativeNumber((std::numeric_limits< double >::max)(), "NONNEGATIVE")
Check for a non negative number.
std::enable_if< std::is_integral< T >::value, bool >::type checked_multiply(T &a, T b)
Performs a *= b; if it doesn't cause integer overflow. Returns false otherwise.
Definition: Validators.hpp:645
typename T::value_type value_type
Definition: TypeTools.hpp:98
Validator operator!() const
Create a validator that fails when a given validator succeeds.
Definition: Validators.hpp:246
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition: Validators.hpp:173
Range(T min_val, T max_val, const std::string &validator_name=std::string{})
Definition: Validators.hpp:470
std::string generate_map(const T &map, bool key_only=false)
Generate a string representation of a map.
Definition: Validators.hpp:558
Definition: Validators.hpp:909
bool isalpha(const std::string &str)
Verify that str consists of letters only.
Definition: StringTools.hpp:254
T type
Definition: TypeTools.hpp:86
Validator & description(std::string validator_desc)
Specify the type string.
Definition: Validators.hpp:130
bool get_active() const
Get a boolean if the validator is active.
Definition: Validators.hpp:191