CLI11 2.2.0
Loading...
Searching...
No Matches
TypeTools.hpp File Reference
#include <cstdint>
#include <exception>
#include <limits>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "StringTools.hpp"
Include dependency graph for TypeTools.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  CLI::make_void< Ts >
 A copy of std::void_t from C++17 (helper for C++11 and C++14) More...
 
struct  CLI::is_bool< T >
 Check to see if something is bool (fail check by default) More...
 
struct  CLI::is_bool< bool >
 Check to see if something is bool (true if actually a bool) More...
 
struct  CLI::is_shared_ptr< T >
 Check to see if something is a shared pointer. More...
 
struct  CLI::is_shared_ptr< std::shared_ptr< T > >
 Check to see if something is a shared pointer (True if really a shared pointer) More...
 
struct  CLI::is_shared_ptr< const std::shared_ptr< T > >
 Check to see if something is a shared pointer (True if really a shared pointer) More...
 
struct  CLI::is_copyable_ptr< T >
 Check to see if something is copyable pointer. More...
 
struct  CLI::IsMemberType< T >
 This can be specialized to override the type deduction for IsMember. More...
 
struct  CLI::IsMemberType< const char * >
 The main custom type needed here is const char * should be a string. More...
 
struct  CLI::detail::element_type< T, Enable >
 not a pointer More...
 
struct  CLI::detail::element_type< T, typename std::enable_if< is_copyable_ptr< T >::value >::type >
 
struct  CLI::detail::element_value_type< T >
 
struct  CLI::detail::pair_adaptor< T, _ >
 Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost nothing. More...
 
struct  CLI::detail::pair_adaptor< T, conditional_t< false, void_t< typename T::value_type::first_type, typename T::value_type::second_type >, void > >
 
class  CLI::detail::is_direct_constructible< T, C >
 
class  CLI::detail::is_ostreamable< T, S >
 
class  CLI::detail::is_istreamable< T, S >
 Check for input streamability. More...
 
class  CLI::detail::is_complex< T >
 Check for complex. More...
 
struct  CLI::detail::is_mutable_container< T, _ >
 
struct  CLI::detail::is_mutable_container< T, conditional_t< false, void_t< typename T::value_type, decltype(std::declval< T >().end()), decltype(std::declval< T >().clear()), decltype(std::declval< T >().insert(std::declval< decltype(std::declval< T >().end())>(), std::declval< const typename T::value_type & >()))>, void > >
 
struct  CLI::detail::is_readable_container< T, _ >
 
struct  CLI::detail::is_readable_container< T, conditional_t< false, void_t< decltype(std::declval< T >().end()), decltype(std::declval< T >().begin())>, void > >
 
struct  CLI::detail::is_wrapper< T, _ >
 
struct  CLI::detail::is_wrapper< T, conditional_t< false, void_t< typename T::value_type >, void > >
 
class  CLI::detail::is_tuple_like< S >
 
struct  CLI::detail::wrapped_type< T, def, Enable >
 template to get the underlying value type if it exists or use a default More...
 
struct  CLI::detail::wrapped_type< T, def, typename std::enable_if< is_wrapper< T >::value >::type >
 Type size for regular object types that do not look like a tuple. More...
 
struct  CLI::detail::type_count_base< T, Enable >
 This will only trigger for actual void type. More...
 
struct  CLI::detail::type_count_base< T, typename std::enable_if<!is_tuple_like< T >::value &&!is_mutable_container< T >::value &&!std::is_void< T >::value >::type >
 Type size for regular object types that do not look like a tuple. More...
 
struct  CLI::detail::type_count_base< T, typename std::enable_if< is_tuple_like< T >::value &&!is_mutable_container< T >::value >::type >
 the base tuple size More...
 
struct  CLI::detail::type_count_base< T, typename std::enable_if< is_mutable_container< T >::value >::type >
 Type count base for containers is the type_count_base of the individual element. More...
 
struct  CLI::detail::type_count< T, Enable >
 This will only trigger for actual void type. More...
 
struct  CLI::detail::type_count< T, typename std::enable_if<!is_wrapper< T >::value &&!is_tuple_like< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >
 Type size for regular object types that do not look like a tuple. More...
 
struct  CLI::detail::type_count< T, typename std::enable_if< is_complex< T >::value >::type >
 Type size for complex since it sometimes looks like a wrapper. More...
 
struct  CLI::detail::type_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >
 Type size of types that are wrappers,except complex and tuples(which can also be wrappers sometimes) More...
 
struct  CLI::detail::type_count< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value &&!is_mutable_container< T >::value >::type >
 Type size of types that are wrappers,except containers complex and tuples(which can also be wrappers sometimes) More...
 

Namespaces

namespace  CLI
 
namespace  CLI::detail
 

Typedefs

template<bool B, class T = void>
using CLI::enable_if_t = typename std::enable_if<B, T>::type
 
template<typename... Ts>
using CLI::void_t = typename make_void<Ts...>::type
 A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine.
 
template<bool B, class T , class F >
using CLI::conditional_t = typename std::conditional<B, T, F>::type
 A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine.
 

Enumerations

enum class  CLI::detail::enabler
 Simple empty scoped class. More...
 

Functions

template<typename T , enable_if_t< is_istreamable< T >::value, detail::enabler > = detail::dummy>
bool CLI::detail::from_stream (const std::string &istring, T &obj)
 Templated operation to get a value from a stream.
 
template<typename T , enable_if_t< std::is_convertible< T, std::string >::value, detail::enabler > = detail::dummy>
auto CLI::detail::to_string (T &&value) -> decltype(std::forward< T >(value))
 Convert an object to a string (directly forward if this can become a string)
 
template<typename T , enable_if_t< std::is_constructible< std::string, T >::value &&!std::is_convertible< T, std::string >::value, detail::enabler > = detail::dummy>
std::string CLI::detail::to_string (const T &value)
 Construct a string from the object.
 
template<typename T , enable_if_t<!std::is_convertible< std::string, T >::value &&!std::is_constructible< std::string, T >::value &&is_ostreamable< T >::value, detail::enabler > = detail::dummy>
std::string CLI::detail::to_string (T &&value)
 Convert an object to a string (streaming must be supported for that type)
 
template<typename T1 , typename T2 , typename T , enable_if_t< std::is_same< T1, T2 >::value, detail::enabler > = detail::dummy>
auto CLI::detail::checked_to_string (T &&value) -> decltype(to_string(std::forward< T >(value)))
 special template overload
 
template<typename T1 , typename T2 , typename T , enable_if_t<!std::is_same< T1, T2 >::value, detail::enabler > = detail::dummy>
std::string CLI::detail::checked_to_string (T &&)
 special template overload
 
template<typename T , enable_if_t< std::is_arithmetic< T >::value, detail::enabler > = detail::dummy>
std::string CLI::detail::value_string (const T &value)
 get a string as a convertible value for arithmetic types
 
template<typename T , enable_if_t<!std::is_enum< T >::value &&!std::is_arithmetic< T >::value, detail::enabler > = detail::dummy>
auto CLI::detail::value_string (const T &value) -> decltype(to_string(value))
 for other types just use the regular to_string function
 
template<typename T , std::size_t I>
constexpr std::enable_if< I==type_count_base< T >::value, int >::type CLI::detail::tuple_type_size ()
 0 if the index > tuple size
 
template<typename T , std::size_t I>
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 > >inline std::string type_name() { auto tname=std::string(1, '[')+tuple_name< T, 0 >();tname.push_back(']');return tname;}template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler > >inline std::string type_name() { return type_name< typename T::value_type >();}template< typename T, enable_if_t< std::is_unsigned< T >::value, detail::enabler >=detail::dummy >bool integral_conversion(const std::string &input, T &output) noexcept { if(input.empty()) { return false;} char *val=nullptr;std::uint64_t output_ll=std::strtoull(input.c_str(), &val, 0);output=static_cast< T >(output_ll);if(val==(input.c_str()+input.size()) &&static_cast< std::uint64_t >(output)==output_ll) { return true;} val=nullptr;std::int64_t output_sll=std::strtoll(input.c_str(), &val, 0);if(val==(input.c_str()+input.size())) { output=(output_sll< 0) ? static_cast< T >(0) CLI::detail::return (static_cast< std::int64_t >(output)==output_sll)
 Recursively generate the tuple type name.
 
template<typename T , enable_if_t< std::is_signed< T >::value, detail::enabler > = detail::dummy>
bool CLI::detail::integral_conversion (const std::string &input, T &output) noexcept
 Convert to a signed integral.
 
std::int64_t CLI::detail::to_flag_value (std::string val)
 Convert a flag into an integer value typically binary flags.
 
template<typename T , enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::unsigned_integral, detail::enabler > = detail::dummy>
bool CLI::detail::lexical_cast (const std::string &input, T &output)
 Integer conversion.
 
template<typename AssignTo , typename ConvertTo , enable_if_t< std::is_same< AssignTo, ConvertTo >::value &&(classify_object< AssignTo >::value==object_category::string_assignable||classify_object< AssignTo >::value==object_category::string_constructible), detail::enabler > = detail::dummy>
bool CLI::detail::lexical_assign (const std::string &input, AssignTo &output)
 Assign a value through lexical cast operations.
 

Variables

constexpr enabler CLI::detail::dummy = {}
 An instance to use in EnableIf.
 
return CLI::detail::false