mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 12:13:52 +00:00
fix some warnings generated from klocwork static analyzer (#350)
* fix some warnings generated from klocwork static analyzer * Some more visual studio static analyzer and clang-tidy fixes * some formatting updates
This commit is contained in:
parent
d621658e6d
commit
5f696596d7
@ -751,10 +751,11 @@ class App {
|
|||||||
std::string flag_description = "") {
|
std::string flag_description = "") {
|
||||||
|
|
||||||
CLI::callback_t fun = [function](const CLI::results_t &res) {
|
CLI::callback_t fun = [function](const CLI::results_t &res) {
|
||||||
bool trigger;
|
bool trigger{false};
|
||||||
auto result = CLI::detail::lexical_cast(res[0], trigger);
|
auto result = CLI::detail::lexical_cast(res[0], trigger);
|
||||||
if(trigger)
|
if(result && trigger) {
|
||||||
function();
|
function();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
|
return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
|
||||||
|
@ -311,7 +311,7 @@ template <typename T> struct expected_count<T, typename std::enable_if<is_vector
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Enumeration of the different supported categorizations of objects
|
// Enumeration of the different supported categorizations of objects
|
||||||
enum objCategory : int {
|
enum class object_category : int {
|
||||||
integral_value = 2,
|
integral_value = 2,
|
||||||
unsigned_integral = 4,
|
unsigned_integral = 4,
|
||||||
enumeration = 6,
|
enumeration = 6,
|
||||||
@ -330,14 +330,16 @@ enum objCategory : int {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// some type that is not otherwise recognized
|
/// some type that is not otherwise recognized
|
||||||
template <typename T, typename Enable = void> struct classify_object { static constexpr objCategory value{other}; };
|
template <typename T, typename Enable = void> struct classify_object {
|
||||||
|
static constexpr object_category value{object_category::other};
|
||||||
|
};
|
||||||
|
|
||||||
/// Set of overloads to classify an object according to type
|
/// Set of overloads to classify an object according to type
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct classify_object<T,
|
struct classify_object<T,
|
||||||
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value &&
|
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value &&
|
||||||
!is_bool<T>::value && !std::is_enum<T>::value>::type> {
|
!is_bool<T>::value && !std::is_enum<T>::value>::type> {
|
||||||
static constexpr objCategory value{integral_value};
|
static constexpr object_category value{object_category::integral_value};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unsigned integers
|
/// Unsigned integers
|
||||||
@ -345,17 +347,17 @@ template <typename T>
|
|||||||
struct classify_object<
|
struct classify_object<
|
||||||
T,
|
T,
|
||||||
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value && !is_bool<T>::value>::type> {
|
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value && !is_bool<T>::value>::type> {
|
||||||
static constexpr objCategory value{unsigned_integral};
|
static constexpr object_category value{object_category::unsigned_integral};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Boolean values
|
/// Boolean values
|
||||||
template <typename T> struct classify_object<T, typename std::enable_if<is_bool<T>::value>::type> {
|
template <typename T> struct classify_object<T, typename std::enable_if<is_bool<T>::value>::type> {
|
||||||
static constexpr objCategory value{boolean_value};
|
static constexpr object_category value{object_category::boolean_value};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Floats
|
/// Floats
|
||||||
template <typename T> struct classify_object<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
|
template <typename T> struct classify_object<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
|
||||||
static constexpr objCategory value{floating_point};
|
static constexpr object_category value{object_category::floating_point};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// String and similar direct assignment
|
/// String and similar direct assignment
|
||||||
@ -364,7 +366,7 @@ struct classify_object<
|
|||||||
T,
|
T,
|
||||||
typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
|
typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
|
||||||
std::is_assignable<T &, std::string>::value && !is_vector<T>::value>::type> {
|
std::is_assignable<T &, std::string>::value && !is_vector<T>::value>::type> {
|
||||||
static constexpr objCategory value{string_assignable};
|
static constexpr object_category value{object_category::string_assignable};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// String and similar constructible and copy assignment
|
/// String and similar constructible and copy assignment
|
||||||
@ -374,12 +376,12 @@ struct classify_object<
|
|||||||
typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
|
typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
|
||||||
!std::is_assignable<T &, std::string>::value &&
|
!std::is_assignable<T &, std::string>::value &&
|
||||||
std::is_constructible<T, std::string>::value && !is_vector<T>::value>::type> {
|
std::is_constructible<T, std::string>::value && !is_vector<T>::value>::type> {
|
||||||
static constexpr objCategory value{string_constructible};
|
static constexpr object_category value{object_category::string_constructible};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Enumerations
|
/// Enumerations
|
||||||
template <typename T> struct classify_object<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
template <typename T> struct classify_object<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
||||||
static constexpr objCategory value{enumeration};
|
static constexpr object_category value{object_category::enumeration};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handy helper to contain a bunch of checks that rule out many common types (integers, string like, floating point,
|
/// Handy helper to contain a bunch of checks that rule out many common types (integers, string like, floating point,
|
||||||
@ -400,7 +402,7 @@ struct classify_object<T,
|
|||||||
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
||||||
is_direct_constructible<T, double>::value &&
|
is_direct_constructible<T, double>::value &&
|
||||||
is_direct_constructible<T, int>::value>::type> {
|
is_direct_constructible<T, int>::value>::type> {
|
||||||
static constexpr objCategory value{number_constructible};
|
static constexpr object_category value{object_category::number_constructible};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Assignable from int
|
/// Assignable from int
|
||||||
@ -409,7 +411,7 @@ struct classify_object<T,
|
|||||||
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
||||||
!is_direct_constructible<T, double>::value &&
|
!is_direct_constructible<T, double>::value &&
|
||||||
is_direct_constructible<T, int>::value>::type> {
|
is_direct_constructible<T, int>::value>::type> {
|
||||||
static constexpr objCategory value{integer_constructible};
|
static constexpr object_category value{object_category::integer_constructible};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Assignable from double
|
/// Assignable from double
|
||||||
@ -418,7 +420,7 @@ struct classify_object<T,
|
|||||||
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
|
||||||
is_direct_constructible<T, double>::value &&
|
is_direct_constructible<T, double>::value &&
|
||||||
!is_direct_constructible<T, int>::value>::type> {
|
!is_direct_constructible<T, int>::value>::type> {
|
||||||
static constexpr objCategory value{double_constructible};
|
static constexpr object_category value{object_category::double_constructible};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Tuple type
|
/// Tuple type
|
||||||
@ -428,12 +430,12 @@ struct classify_object<T,
|
|||||||
(is_tuple_like<T>::value && uncommon_type<T>::value &&
|
(is_tuple_like<T>::value && uncommon_type<T>::value &&
|
||||||
!is_direct_constructible<T, double>::value &&
|
!is_direct_constructible<T, double>::value &&
|
||||||
!is_direct_constructible<T, int>::value)>::type> {
|
!is_direct_constructible<T, int>::value)>::type> {
|
||||||
static constexpr objCategory value{tuple_value};
|
static constexpr object_category value{object_category::tuple_value};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Vector type
|
/// Vector type
|
||||||
template <typename T> struct classify_object<T, typename std::enable_if<is_vector<T>::value>::type> {
|
template <typename T> struct classify_object<T, typename std::enable_if<is_vector<T>::value>::type> {
|
||||||
static constexpr objCategory value{vector_value};
|
static constexpr object_category value{object_category::vector_value};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type name print
|
// Type name print
|
||||||
@ -443,48 +445,53 @@ template <typename T> struct classify_object<T, typename std::enable_if<is_vecto
|
|||||||
/// But this is cleaner and works better in this case
|
/// But this is cleaner and works better in this case
|
||||||
|
|
||||||
template <typename T,
|
template <typename T,
|
||||||
enable_if_t<classify_object<T>::value == integral_value || classify_object<T>::value == integer_constructible,
|
enable_if_t<classify_object<T>::value == object_category::integral_value ||
|
||||||
|
classify_object<T>::value == object_category::integer_constructible,
|
||||||
detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "INT";
|
return "INT";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == unsigned_integral, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::unsigned_integral, detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "UINT";
|
return "UINT";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <typename T,
|
||||||
typename T,
|
enable_if_t<classify_object<T>::value == object_category::floating_point ||
|
||||||
enable_if_t<classify_object<T>::value == floating_point || classify_object<T>::value == number_constructible ||
|
classify_object<T>::value == object_category::number_constructible ||
|
||||||
classify_object<T>::value == double_constructible,
|
classify_object<T>::value == object_category::double_constructible,
|
||||||
detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "FLOAT";
|
return "FLOAT";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print name for enumeration types
|
/// Print name for enumeration types
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == enumeration, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::enumeration, detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "ENUM";
|
return "ENUM";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print name for enumeration types
|
/// Print name for enumeration types
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == boolean_value, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::boolean_value, detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "BOOLEAN";
|
return "BOOLEAN";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print for all other types
|
/// Print for all other types
|
||||||
template <typename T, enable_if_t<classify_object<T>::value >= string_assignable, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value >= object_category::string_assignable, detail::enabler> = detail::dummy>
|
||||||
constexpr const char *type_name() {
|
constexpr const char *type_name() {
|
||||||
return "TEXT";
|
return "TEXT";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print name for single element tuple types
|
/// Print name for single element tuple types
|
||||||
template <
|
template <typename T,
|
||||||
typename T,
|
enable_if_t<classify_object<T>::value == object_category::tuple_value && type_count<T>::value == 1,
|
||||||
enable_if_t<classify_object<T>::value == tuple_value && type_count<T>::value == 1, detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
inline std::string type_name() {
|
inline std::string type_name() {
|
||||||
return type_name<typename std::tuple_element<0, T>::type>();
|
return type_name<typename std::tuple_element<0, T>::type>();
|
||||||
}
|
}
|
||||||
@ -505,9 +512,9 @@ template <typename T, std::size_t I>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Print type name for tuples with 2 or more elements
|
/// Print type name for tuples with 2 or more elements
|
||||||
template <
|
template <typename T,
|
||||||
typename T,
|
enable_if_t<classify_object<T>::value == object_category::tuple_value && type_count<T>::value >= 2,
|
||||||
enable_if_t<classify_object<T>::value == tuple_value && type_count<T>::value >= 2, detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
std::string type_name() {
|
std::string type_name() {
|
||||||
auto tname = std::string(1, '[') + tuple_name<T, 0>();
|
auto tname = std::string(1, '[') + tuple_name<T, 0>();
|
||||||
tname.push_back(']');
|
tname.push_back(']');
|
||||||
@ -515,7 +522,8 @@ std::string type_name() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This one should not be used normally, since vector types print the internal type
|
/// This one should not be used normally, since vector types print the internal type
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == vector_value, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::vector_value, detail::enabler> = detail::dummy>
|
||||||
inline std::string type_name() {
|
inline std::string type_name() {
|
||||||
return type_name<typename T::value_type>();
|
return type_name<typename T::value_type>();
|
||||||
}
|
}
|
||||||
@ -566,7 +574,8 @@ inline int64_t to_flag_value(std::string val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signed integers
|
/// Signed integers
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == integral_value, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::integral_value, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
try {
|
try {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
@ -581,7 +590,8 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Unsigned integers
|
/// Unsigned integers
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == unsigned_integral, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::unsigned_integral, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
if(!input.empty() && input.front() == '-')
|
if(!input.empty() && input.front() == '-')
|
||||||
return false; // std::stoull happily converts negative values to junk without any errors.
|
return false; // std::stoull happily converts negative values to junk without any errors.
|
||||||
@ -599,7 +609,8 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Boolean values
|
/// Boolean values
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == boolean_value, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::boolean_value, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
try {
|
try {
|
||||||
auto out = to_flag_value(input);
|
auto out = to_flag_value(input);
|
||||||
@ -616,7 +627,8 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Floats
|
/// Floats
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == floating_point, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::floating_point, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
try {
|
try {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
@ -630,21 +642,25 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// String and similar direct assignment
|
/// String and similar direct assignment
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == string_assignable, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::string_assignable, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
output = input;
|
output = input;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// String and similar constructible and copy assignment
|
/// String and similar constructible and copy assignment
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == string_constructible, detail::enabler> = detail::dummy>
|
template <
|
||||||
|
typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::string_constructible, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
output = T(input);
|
output = T(input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enumerations
|
/// Enumerations
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == enumeration, detail::enabler> = detail::dummy>
|
template <typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::enumeration, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
typename std::underlying_type<T>::type val;
|
typename std::underlying_type<T>::type val;
|
||||||
bool retval = detail::lexical_cast(input, val);
|
bool retval = detail::lexical_cast(input, val);
|
||||||
@ -656,7 +672,9 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assignable from double or int
|
/// Assignable from double or int
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == number_constructible, detail::enabler> = detail::dummy>
|
template <
|
||||||
|
typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::number_constructible, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
int val;
|
int val;
|
||||||
if(lexical_cast(input, val)) {
|
if(lexical_cast(input, val)) {
|
||||||
@ -673,7 +691,9 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assignable from int
|
/// Assignable from int
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == integer_constructible, detail::enabler> = detail::dummy>
|
template <
|
||||||
|
typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::integer_constructible, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
int val;
|
int val;
|
||||||
if(lexical_cast(input, val)) {
|
if(lexical_cast(input, val)) {
|
||||||
@ -684,7 +704,9 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assignable from double
|
/// Assignable from double
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == double_constructible, detail::enabler> = detail::dummy>
|
template <
|
||||||
|
typename T,
|
||||||
|
enable_if_t<classify_object<T>::value == object_category::double_constructible, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
double val;
|
double val;
|
||||||
if(lexical_cast(input, val)) {
|
if(lexical_cast(input, val)) {
|
||||||
@ -695,7 +717,7 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Non-string parsable by a stream
|
/// Non-string parsable by a stream
|
||||||
template <typename T, enable_if_t<classify_object<T>::value == other, detail::enabler> = detail::dummy>
|
template <typename T, enable_if_t<classify_object<T>::value == object_category::other, detail::enabler> = detail::dummy>
|
||||||
bool lexical_cast(const std::string &input, T &output) {
|
bool lexical_cast(const std::string &input, T &output) {
|
||||||
static_assert(is_istreamable<T>::value,
|
static_assert(is_istreamable<T>::value,
|
||||||
"option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
|
"option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
|
||||||
@ -704,11 +726,12 @@ bool lexical_cast(const std::string &input, T &output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assign a value through lexical cast operations
|
/// Assign a value through lexical cast operations
|
||||||
template <typename T,
|
template <
|
||||||
typename XC,
|
typename T,
|
||||||
enable_if_t<std::is_same<T, XC>::value && (classify_object<T>::value == string_assignable ||
|
typename XC,
|
||||||
classify_object<T>::value == string_constructible),
|
enable_if_t<std::is_same<T, XC>::value && (classify_object<T>::value == object_category::string_assignable ||
|
||||||
detail::enabler> = detail::dummy>
|
classify_object<T>::value == object_category::string_constructible),
|
||||||
|
detail::enabler> = detail::dummy>
|
||||||
bool lexical_assign(const std::string &input, T &output) {
|
bool lexical_assign(const std::string &input, T &output) {
|
||||||
return lexical_cast(input, output);
|
return lexical_cast(input, output);
|
||||||
}
|
}
|
||||||
@ -716,8 +739,8 @@ bool lexical_assign(const std::string &input, T &output) {
|
|||||||
/// Assign a value through lexical cast operations
|
/// Assign a value through lexical cast operations
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename XC,
|
typename XC,
|
||||||
enable_if_t<std::is_same<T, XC>::value && classify_object<T>::value != string_assignable &&
|
enable_if_t<std::is_same<T, XC>::value && classify_object<T>::value != object_category::string_assignable &&
|
||||||
classify_object<T>::value != string_constructible,
|
classify_object<T>::value != object_category::string_constructible,
|
||||||
detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
bool lexical_assign(const std::string &input, T &output) {
|
bool lexical_assign(const std::string &input, T &output) {
|
||||||
if(input.empty()) {
|
if(input.empty()) {
|
||||||
@ -774,7 +797,7 @@ bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
|||||||
typename std::tuple_element<1, XC>::type v2;
|
typename std::tuple_element<1, XC>::type v2;
|
||||||
bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[0], v1);
|
bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[0], v1);
|
||||||
if(strings.size() > 1) {
|
if(strings.size() > 1) {
|
||||||
retval &= lexical_assign<decltype(v2), decltype(v2)>(strings[1], v2);
|
retval = retval && lexical_assign<decltype(v2), decltype(v2)>(strings[1], v2);
|
||||||
}
|
}
|
||||||
if(retval) {
|
if(retval) {
|
||||||
output = T{v1, v2};
|
output = T{v1, v2};
|
||||||
@ -789,15 +812,17 @@ template <class T,
|
|||||||
expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 1,
|
expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 1,
|
||||||
detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
||||||
bool retval = true;
|
|
||||||
output.clear();
|
output.clear();
|
||||||
output.reserve(strings.size());
|
output.reserve(strings.size());
|
||||||
for(const auto &elem : strings) {
|
for(const auto &elem : strings) {
|
||||||
|
|
||||||
output.emplace_back();
|
output.emplace_back();
|
||||||
retval &= lexical_assign<typename T::value_type, typename XC::value_type>(elem, output.back());
|
bool retval = lexical_assign<typename T::value_type, typename XC::value_type>(elem, output.back());
|
||||||
|
if(!retval) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (!output.empty()) && retval;
|
return (!output.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lexical conversion of a vector types with type size of two
|
/// Lexical conversion of a vector types with type size of two
|
||||||
@ -807,15 +832,14 @@ template <class T,
|
|||||||
expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 2,
|
expected_count<XC>::value == expected_max_vector_size && type_count<XC>::value == 2,
|
||||||
detail::enabler> = detail::dummy>
|
detail::enabler> = detail::dummy>
|
||||||
bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
||||||
bool retval = true;
|
|
||||||
output.clear();
|
output.clear();
|
||||||
for(size_t ii = 0; ii < strings.size(); ii += 2) {
|
for(size_t ii = 0; ii < strings.size(); ii += 2) {
|
||||||
|
|
||||||
typename std::tuple_element<0, typename XC::value_type>::type v1;
|
typename std::tuple_element<0, typename XC::value_type>::type v1;
|
||||||
typename std::tuple_element<1, typename XC::value_type>::type v2;
|
typename std::tuple_element<1, typename XC::value_type>::type v2;
|
||||||
retval = lexical_assign<decltype(v1), decltype(v1)>(strings[ii], v1);
|
bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[ii], v1);
|
||||||
if(strings.size() > ii + 1) {
|
if(strings.size() > ii + 1) {
|
||||||
retval &= lexical_assign<decltype(v2), decltype(v2)>(strings[ii + 1], v2);
|
retval = retval && lexical_assign<decltype(v2), decltype(v2)>(strings[ii + 1], v2);
|
||||||
}
|
}
|
||||||
if(retval) {
|
if(retval) {
|
||||||
output.emplace_back(v1, v2);
|
output.emplace_back(v1, v2);
|
||||||
@ -823,7 +847,7 @@ bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (!output.empty()) && retval;
|
return (!output.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conversion to a vector type using a particular single type as the conversion type
|
/// Conversion to a vector type using a particular single type as the conversion type
|
||||||
@ -839,7 +863,7 @@ bool lexical_conversion(const std::vector<std ::string> &strings, T &output) {
|
|||||||
for(const auto &elem : strings) {
|
for(const auto &elem : strings) {
|
||||||
|
|
||||||
output.emplace_back();
|
output.emplace_back();
|
||||||
retval &= lexical_assign<typename T::value_type, XC>(elem, output.back());
|
retval = retval && lexical_assign<typename T::value_type, XC>(elem, output.back());
|
||||||
}
|
}
|
||||||
return (!output.empty()) && retval;
|
return (!output.empty()) && retval;
|
||||||
}
|
}
|
||||||
@ -873,12 +897,12 @@ template <class T, class XC, std::size_t I>
|
|||||||
I<type_count<T>::value, bool>::type tuple_conversion(const std::vector<std::string> &strings, T &output) {
|
I<type_count<T>::value, bool>::type tuple_conversion(const std::vector<std::string> &strings, T &output) {
|
||||||
bool retval = true;
|
bool retval = true;
|
||||||
if(strings.size() > I) {
|
if(strings.size() > I) {
|
||||||
retval &= lexical_assign<
|
retval = retval && lexical_assign<typename std::tuple_element<I, T>::type,
|
||||||
typename std::tuple_element<I, T>::type,
|
typename std::conditional<is_tuple_like<XC>::value,
|
||||||
typename std::conditional<is_tuple_like<XC>::value, typename std::tuple_element<I, XC>::type, XC>::type>(
|
typename std::tuple_element<I, XC>::type,
|
||||||
strings[I], std::get<I>(output));
|
XC>::type>(strings[I], std::get<I>(output));
|
||||||
}
|
}
|
||||||
retval &= tuple_conversion<T, XC, I + 1>(strings, output);
|
retval = retval && tuple_conversion<T, XC, I + 1>(strings, output);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,17 +373,16 @@ class IPV4Validator : public Validator {
|
|||||||
func_ = [](std::string &ip_addr) {
|
func_ = [](std::string &ip_addr) {
|
||||||
auto result = CLI::detail::split(ip_addr, '.');
|
auto result = CLI::detail::split(ip_addr, '.');
|
||||||
if(result.size() != 4) {
|
if(result.size() != 4) {
|
||||||
return "Invalid IPV4 address must have four parts (" + ip_addr + ')';
|
return std::string("Invalid IPV4 address must have four parts (") + ip_addr + ')';
|
||||||
}
|
}
|
||||||
int num;
|
int num;
|
||||||
bool retval = true;
|
|
||||||
for(const auto &var : result) {
|
for(const auto &var : result) {
|
||||||
retval &= detail::lexical_cast(var, num);
|
bool retval = detail::lexical_cast(var, num);
|
||||||
if(!retval) {
|
if(!retval) {
|
||||||
return "Failed parsing number (" + var + ')';
|
return std::string("Failed parsing number (") + var + ')';
|
||||||
}
|
}
|
||||||
if(num < 0 || num > 255) {
|
if(num < 0 || num > 255) {
|
||||||
return "Each IP number must be between 0 and 255 " + var;
|
return std::string("Each IP number must be between 0 and 255 ") + var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
@ -398,10 +397,10 @@ class PositiveNumber : public Validator {
|
|||||||
func_ = [](std::string &number_str) {
|
func_ = [](std::string &number_str) {
|
||||||
double number;
|
double number;
|
||||||
if(!detail::lexical_cast(number_str, number)) {
|
if(!detail::lexical_cast(number_str, number)) {
|
||||||
return "Failed parsing number: (" + number_str + ')';
|
return std::string("Failed parsing number: (") + number_str + ')';
|
||||||
}
|
}
|
||||||
if(number <= 0) {
|
if(number <= 0) {
|
||||||
return "Number less or equal to 0: (" + number_str + ')';
|
return std::string("Number less or equal to 0: (") + number_str + ')';
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
};
|
};
|
||||||
@ -414,10 +413,10 @@ class NonNegativeNumber : public Validator {
|
|||||||
func_ = [](std::string &number_str) {
|
func_ = [](std::string &number_str) {
|
||||||
double number;
|
double number;
|
||||||
if(!detail::lexical_cast(number_str, number)) {
|
if(!detail::lexical_cast(number_str, number)) {
|
||||||
return "Failed parsing number: (" + number_str + ')';
|
return std::string("Failed parsing number: (") + number_str + ')';
|
||||||
}
|
}
|
||||||
if(number < 0) {
|
if(number < 0) {
|
||||||
return "Number less than 0: (" + number_str + ')';
|
return std::string("Number less than 0: (") + number_str + ')';
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
};
|
};
|
||||||
@ -431,7 +430,7 @@ class Number : public Validator {
|
|||||||
func_ = [](std::string &number_str) {
|
func_ = [](std::string &number_str) {
|
||||||
double number;
|
double number;
|
||||||
if(!detail::lexical_cast(number_str, number)) {
|
if(!detail::lexical_cast(number_str, number)) {
|
||||||
return "Failed parsing as a number (" + number_str + ')';
|
return std::string("Failed parsing as a number (") + number_str + ')';
|
||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
};
|
};
|
||||||
@ -482,7 +481,8 @@ class Range : public Validator {
|
|||||||
T val;
|
T val;
|
||||||
bool converted = detail::lexical_cast(input, val);
|
bool converted = detail::lexical_cast(input, val);
|
||||||
if((!converted) || (val < min || val > max))
|
if((!converted) || (val < min || val > max))
|
||||||
return "Value " + input + " not in range " + std::to_string(min) + " to " + std::to_string(max);
|
return std::string("Value ") + input + " not in range " + std::to_string(min) + " to " +
|
||||||
|
std::to_string(max);
|
||||||
|
|
||||||
return std::string();
|
return std::string();
|
||||||
};
|
};
|
||||||
@ -508,7 +508,7 @@ class Bound : public Validator {
|
|||||||
T val;
|
T val;
|
||||||
bool converted = detail::lexical_cast(input, val);
|
bool converted = detail::lexical_cast(input, val);
|
||||||
if(!converted) {
|
if(!converted) {
|
||||||
return "Value " + input + " could not be converted";
|
return std::string("Value ") + input + " could not be converted";
|
||||||
}
|
}
|
||||||
if(val < min)
|
if(val < min)
|
||||||
input = detail::to_string(min);
|
input = detail::to_string(min);
|
||||||
@ -943,7 +943,8 @@ class AsNumberWithUnit : public Validator {
|
|||||||
|
|
||||||
bool converted = detail::lexical_cast(input, num);
|
bool converted = detail::lexical_cast(input, num);
|
||||||
if(!converted) {
|
if(!converted) {
|
||||||
throw ValidationError("Value " + input + " could not be converted to " + detail::type_name<Number>());
|
throw ValidationError(std::string("Value ") + input + " could not be converted to " +
|
||||||
|
detail::type_name<Number>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unit.empty()) {
|
if(unit.empty()) {
|
||||||
@ -991,7 +992,8 @@ class AsNumberWithUnit : public Validator {
|
|||||||
for(auto &kv : mapping) {
|
for(auto &kv : mapping) {
|
||||||
auto s = detail::to_lower(kv.first);
|
auto s = detail::to_lower(kv.first);
|
||||||
if(lower_mapping.count(s)) {
|
if(lower_mapping.count(s)) {
|
||||||
throw ValidationError("Several matching lowercase unit representations are found: " + s);
|
throw ValidationError(std::string("Several matching lowercase unit representations are found: ") +
|
||||||
|
s);
|
||||||
}
|
}
|
||||||
lower_mapping[detail::to_lower(kv.first)] = kv.second;
|
lower_mapping[detail::to_lower(kv.first)] = kv.second;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ TEST_F(TApp, OneStringEqualVersionSingleString) {
|
|||||||
TEST_F(TApp, OneStringEqualVersionSingleStringQuoted) {
|
TEST_F(TApp, OneStringEqualVersionSingleStringQuoted) {
|
||||||
std::string str;
|
std::string str;
|
||||||
app.add_option("-s,--string", str);
|
app.add_option("-s,--string", str);
|
||||||
app.parse("--string=\"this is my quoted string\"");
|
app.parse(R"raw(--string="this is my quoted string")raw");
|
||||||
EXPECT_EQ(1u, app.count("-s"));
|
EXPECT_EQ(1u, app.count("-s"));
|
||||||
EXPECT_EQ(1u, app.count("--string"));
|
EXPECT_EQ(1u, app.count("--string"));
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
@ -305,7 +305,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultiple) {
|
|||||||
app.add_option("-s,--string", str);
|
app.add_option("-s,--string", str);
|
||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.parse("--string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"`");
|
app.parse(R"raw(--string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -316,12 +316,12 @@ TEST_F(TApp, OneStringEqualVersionSingleStringEmbeddedEqual) {
|
|||||||
app.add_option("-s,--string", str);
|
app.add_option("-s,--string", str);
|
||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.parse("--string=\"app=\\\"test1 b\\\" test2=\\\"frogs\\\"\" -t 'qstring 2' -m=`\"quoted string\"`");
|
app.parse(R"raw(--string="app=\"test1 b\" test2=\"frogs\"" -t 'qstring 2' -m=`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "app=\"test1 b\" test2=\"frogs\"");
|
EXPECT_EQ(str, "app=\"test1 b\" test2=\"frogs\"");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
|
|
||||||
app.parse("--string=\"app='test1 b' test2='frogs'\" -t 'qstring 2' -m=`\"quoted string\"`");
|
app.parse(R"raw(--string="app='test1 b' test2='frogs'" -t 'qstring 2' -m=`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "app='test1 b' test2='frogs'");
|
EXPECT_EQ(str, "app='test1 b' test2='frogs'");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -333,12 +333,12 @@ TEST_F(TApp, OneStringEqualVersionSingleStringEmbeddedEqualWindowsStyle) {
|
|||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("--mstr", str3);
|
app.add_option("--mstr", str3);
|
||||||
app.allow_windows_style_options();
|
app.allow_windows_style_options();
|
||||||
app.parse("/string:\"app:\\\"test1 b\\\" test2:\\\"frogs\\\"\" /t 'qstring 2' /mstr:`\"quoted string\"`");
|
app.parse(R"raw(/string:"app:\"test1 b\" test2:\"frogs\"" /t 'qstring 2' /mstr:`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "app:\"test1 b\" test2:\"frogs\"");
|
EXPECT_EQ(str, "app:\"test1 b\" test2:\"frogs\"");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
|
|
||||||
app.parse("/string:\"app:'test1 b' test2:'frogs'\" /t 'qstring 2' /mstr:`\"quoted string\"`");
|
app.parse(R"raw(/string:"app:'test1 b' test2:'frogs'" /t 'qstring 2' /mstr:`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "app:'test1 b' test2:'frogs'");
|
EXPECT_EQ(str, "app:'test1 b' test2:'frogs'");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -350,7 +350,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleMixedStyle) {
|
|||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.allow_windows_style_options();
|
app.allow_windows_style_options();
|
||||||
app.parse("/string:\"this is my quoted string\" /t 'qstring 2' -m=`\"quoted string\"`");
|
app.parse(R"raw(/string:"this is my quoted string" /t 'qstring 2' -m=`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -361,7 +361,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleInMiddle) {
|
|||||||
app.add_option("-s,--string", str);
|
app.add_option("-s,--string", str);
|
||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.parse(R"raw(--string="this is my quoted string" -t "qst\"ring 2" -m=`"quoted string"`")raw");
|
app.parse(R"raw(--string="this is my quoted string" -t "qst\"ring 2" -m=`"quoted string"`)raw");
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
EXPECT_EQ(str2, "qst\"ring 2");
|
EXPECT_EQ(str2, "qst\"ring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -384,7 +384,7 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleWithEqual) {
|
|||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.add_option("-j,--jstr", str4);
|
app.add_option("-j,--jstr", str4);
|
||||||
app.parse("--string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"` --jstr=Unquoted");
|
app.parse(R"raw(--string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"` --jstr=Unquoted)raw");
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
@ -397,8 +397,9 @@ TEST_F(TApp, OneStringEqualVersionSingleStringQuotedMultipleWithEqualAndProgram)
|
|||||||
app.add_option("-t,--tstr", str2);
|
app.add_option("-t,--tstr", str2);
|
||||||
app.add_option("-m,--mstr", str3);
|
app.add_option("-m,--mstr", str3);
|
||||||
app.add_option("-j,--jstr", str4);
|
app.add_option("-j,--jstr", str4);
|
||||||
app.parse("program --string=\"this is my quoted string\" -t 'qstring 2' -m=`\"quoted string\"` --jstr=Unquoted",
|
app.parse(
|
||||||
true);
|
R"raw(program --string="this is my quoted string" -t 'qstring 2' -m=`"quoted string"` --jstr=Unquoted)raw",
|
||||||
|
true);
|
||||||
EXPECT_EQ(str, "this is my quoted string");
|
EXPECT_EQ(str, "this is my quoted string");
|
||||||
EXPECT_EQ(str2, "qstring 2");
|
EXPECT_EQ(str2, "qstring 2");
|
||||||
EXPECT_EQ(str3, "\"quoted string\"");
|
EXPECT_EQ(str3, "\"quoted string\"");
|
||||||
|
@ -704,7 +704,7 @@ class Unstreamable {
|
|||||||
int x_ = -1;
|
int x_ = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Unstreamable() {}
|
Unstreamable() = default;
|
||||||
int get_x() const { return x_; }
|
int get_x() const { return x_; }
|
||||||
void set_x(int x) { x_ = x; }
|
void set_x(int x) { x_ = x; }
|
||||||
};
|
};
|
||||||
@ -719,7 +719,8 @@ std::istream &operator>>(std::istream &in, Unstreamable &value) {
|
|||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
// these need to be different classes otherwise the definitions conflict
|
// these need to be different classes otherwise the definitions conflict
|
||||||
static_assert(CLI::detail::is_istreamable<Unstreamable>::value, "Unstreamable type is still unstreamable");
|
static_assert(CLI::detail::is_istreamable<Unstreamable>::value,
|
||||||
|
"Unstreamable type is still unstreamable and it should be");
|
||||||
|
|
||||||
TEST_F(TApp, MakeUnstreamableOptions) {
|
TEST_F(TApp, MakeUnstreamableOptions) {
|
||||||
Unstreamable value;
|
Unstreamable value;
|
||||||
|
@ -859,7 +859,7 @@ TEST(Types, TypeName) {
|
|||||||
EXPECT_EQ("FLOAT", vector_name);
|
EXPECT_EQ("FLOAT", vector_name);
|
||||||
|
|
||||||
static_assert(CLI::detail::classify_object<std::pair<int, std::string>>::value ==
|
static_assert(CLI::detail::classify_object<std::pair<int, std::string>>::value ==
|
||||||
CLI::detail::objCategory::tuple_value,
|
CLI::detail::object_category::tuple_value,
|
||||||
"pair<int,string> does not read like a tuple");
|
"pair<int,string> does not read like a tuple");
|
||||||
|
|
||||||
std::string pair_name = CLI::detail::type_name<std::vector<std::pair<int, std::string>>>();
|
std::string pair_name = CLI::detail::type_name<std::vector<std::pair<int, std::string>>>();
|
||||||
@ -869,16 +869,16 @@ TEST(Types, TypeName) {
|
|||||||
EXPECT_EQ("UINT", vector_name);
|
EXPECT_EQ("UINT", vector_name);
|
||||||
|
|
||||||
auto vclass = CLI::detail::classify_object<std::vector<std::vector<unsigned char>>>::value;
|
auto vclass = CLI::detail::classify_object<std::vector<std::vector<unsigned char>>>::value;
|
||||||
EXPECT_EQ(vclass, CLI::detail::objCategory::vector_value);
|
EXPECT_EQ(vclass, CLI::detail::object_category::vector_value);
|
||||||
|
|
||||||
auto tclass = CLI::detail::classify_object<std::tuple<double>>::value;
|
auto tclass = CLI::detail::classify_object<std::tuple<double>>::value;
|
||||||
EXPECT_EQ(tclass, CLI::detail::objCategory::number_constructible);
|
EXPECT_EQ(tclass, CLI::detail::object_category::number_constructible);
|
||||||
|
|
||||||
std::string tuple_name = CLI::detail::type_name<std::tuple<double>>();
|
std::string tuple_name = CLI::detail::type_name<std::tuple<double>>();
|
||||||
EXPECT_EQ("FLOAT", tuple_name);
|
EXPECT_EQ("FLOAT", tuple_name);
|
||||||
|
|
||||||
static_assert(CLI::detail::classify_object<std::tuple<int, std::string>>::value ==
|
static_assert(CLI::detail::classify_object<std::tuple<int, std::string>>::value ==
|
||||||
CLI::detail::objCategory::tuple_value,
|
CLI::detail::object_category::tuple_value,
|
||||||
"tuple<int,string> does not read like a tuple");
|
"tuple<int,string> does not read like a tuple");
|
||||||
tuple_name = CLI::detail::type_name<std::tuple<int, std::string>>();
|
tuple_name = CLI::detail::type_name<std::tuple<int, std::string>>();
|
||||||
EXPECT_EQ("[INT,TEXT]", tuple_name);
|
EXPECT_EQ("[INT,TEXT]", tuple_name);
|
||||||
@ -906,8 +906,8 @@ TEST(Types, TypeName) {
|
|||||||
EXPECT_EQ("ENUM", enum_name);
|
EXPECT_EQ("ENUM", enum_name);
|
||||||
|
|
||||||
vclass = CLI::detail::classify_object<std::tuple<test>>::value;
|
vclass = CLI::detail::classify_object<std::tuple<test>>::value;
|
||||||
EXPECT_EQ(vclass, CLI::detail::objCategory::tuple_value);
|
EXPECT_EQ(vclass, CLI::detail::object_category::tuple_value);
|
||||||
static_assert(CLI::detail::classify_object<std::tuple<test>>::value == CLI::detail::objCategory::tuple_value,
|
static_assert(CLI::detail::classify_object<std::tuple<test>>::value == CLI::detail::object_category::tuple_value,
|
||||||
"tuple<test> does not classify as a tuple");
|
"tuple<test> does not classify as a tuple");
|
||||||
std::string enum_name2 = CLI::detail::type_name<std::tuple<test>>();
|
std::string enum_name2 = CLI::detail::type_name<std::tuple<test>>();
|
||||||
EXPECT_EQ("ENUM", enum_name2);
|
EXPECT_EQ("ENUM", enum_name2);
|
||||||
|
@ -198,6 +198,7 @@ TEST_F(TApp, BuiltinComplexSingleImag) {
|
|||||||
EXPECT_DOUBLE_EQ(0, comp.imag());
|
EXPECT_DOUBLE_EQ(0, comp.imag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simple class containing two strings useful for testing lexical cast and conversions
|
||||||
class spair {
|
class spair {
|
||||||
public:
|
public:
|
||||||
spair() = default;
|
spair() = default;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user