43template <
bool B,
class T =
void>
using enable_if_t =
typename std::enable_if<B, T>::type;
54template <
bool B,
class T,
class F>
using conditional_t =
typename std::conditional<B, T, F>::type;
57template <
typename T>
struct is_bool : std::false_type {};
60template <>
struct is_bool<bool> : std::true_type {};
66template <
typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
69template <
typename T>
struct is_shared_ptr<const std::shared_ptr<T>> : std::true_type {};
99 using type =
typename std::pointer_traits<T>::element_type;
109template <
typename T,
typename _ =
void>
struct pair_adaptor : std::false_type {
111 using first_type =
typename std::remove_const<value_type>::type;
132 using first_type =
typename std::remove_const<typename value_type::first_type>::type;
133 using second_type =
typename std::remove_const<typename value_type::second_type>::type;
137 return std::get<0>(std::forward<Q>(
pair_value));
141 return std::get<1>(std::forward<Q>(
pair_value));
152#pragma GCC diagnostic push
153#pragma GCC diagnostic ignored "-Wnarrowing"
157 template <
typename TT,
typename CC>
158 static auto test(
int, std::true_type) ->
decltype(
161#pragma diag_suppress 2361
163 TT{std::declval<CC>()}
165#pragma diag_default 2361
168 std::is_move_assignable<TT>());
170 template <
typename TT,
typename CC>
static auto test(
int, std::false_type) -> std::false_type;
172 template <
typename,
typename>
static auto test(...) -> std::false_type;
178#pragma GCC diagnostic pop
185 template <
typename TT,
typename SS>
186 static auto test(
int) ->
decltype(std::declval<SS &>() << std::declval<TT>(), std::true_type());
188 template <
typename,
typename>
static auto test(...) -> std::false_type;
196 template <
typename TT,
typename SS>
197 static auto test(
int) ->
decltype(std::declval<SS &>() >> std::declval<TT &>(), std::true_type());
199 template <
typename,
typename>
static auto test(...) -> std::false_type;
207 template <
typename TT>
208 static auto test(
int) ->
decltype(std::declval<TT>().real(), std::declval<TT>().imag(), std::true_type());
210 template <
typename>
static auto test(...) -> std::false_type;
219 std::istringstream
is;
222 return !
is.fail() && !
is.rdbuf()->in_avail();
242 decltype(std::declval<T>().clear()),
243 decltype(std::declval<T>().insert(std::declval<decltype(std::declval<T>().end())>(),
244 std::declval<const typename T::value_type &>()))>,
246 :
public conditional_t<std::is_constructible<T, std::string>::value, std::false_type, std::true_type> {};
258 :
public std::true_type {};
261template <
typename T,
typename _ =
void>
struct is_wrapper : std::false_type {};
269 template <
typename SS>
272 static auto test(
int) ->
decltype(std::tuple_size<typename std::decay<SS>::type>
::value, std::true_type{});
273 template <
typename>
static auto test(...) -> std::false_type;
281auto to_string(T &&value) ->
decltype(std::forward<T>(value)) {
282 return std::forward<T>(value);
290 return std::string(value);
316 is_readable_container<T>::value,
333template <
typename T1,
338 return to_string(std::forward<T>(value));
342template <
typename T1,
347 return std::string{};
352 return std::to_string(value);
357 return std::to_string(
static_cast<typename std::underlying_type<T>::type
>(value));
367template <
typename T,
typename def,
typename Enable =
void>
struct wrapped_type {
373 using type =
typename T::value_type;
384 typename std::
enable_if<!is_tuple_like<T>::value && !is_mutable_container<T>::value &&
385 !std::is_void<T>::value>::type> {
392 static constexpr int value{std::tuple_size<T>::value};
409template <
typename T,
typename Enable =
void>
struct type_count {
416 typename std::
enable_if<!is_wrapper<T>::value && !is_tuple_like<T>::value && !is_complex<T>::value &&
417 !std::is_void<T>::value>::type> {
434 typename std::
enable_if<is_wrapper<T>::value && !is_complex<T>::value && !is_tuple_like<T>::value &&
435 !is_mutable_container<T>::value>::type> {
440template <
typename T, std::
size_t I>
441constexpr typename std::enable_if<I == type_count_base<T>::value,
int>::type
tuple_type_size() {
446template <
typename T, std::
size_t I>
447 constexpr typename std::enable_if < I<type_count_base<T>::value,
int>::type
tuple_type_size() {
452template <
typename T>
struct type_count<T,
typename std::
enable_if<is_tuple_like<T>::value>::type> {
457template <
typename T>
struct subtype_count {
462template <
typename T,
typename Enable =
void>
struct type_count_min {
463 static const int value{0};
470 typename std::
enable_if<!is_mutable_container<T>::value && !is_tuple_like<T>::value && !is_wrapper<T>::value &&
471 !is_complex<T>::value && !std::is_void<T>::value>::type> {
477 static constexpr int value{1};
484 typename std::
enable_if<is_wrapper<T>::value && !is_complex<T>::value && !is_tuple_like<T>::value>::type> {
485 static constexpr int value{subtype_count_min<typename T::value_type>::value};
489template <
typename T, std::
size_t I>
490constexpr typename std::enable_if<I == type_count_base<T>::value,
int>::type
tuple_type_size_min() {
495template <
typename T, std::
size_t I>
496 constexpr typename std::enable_if < I<type_count_base<T>::value,
int>::type
tuple_type_size_min() {
506template <
typename T>
struct subtype_count_min {
507 static constexpr int value{is_mutable_container<T>::value
513template <
typename T,
typename Enable =
void>
struct expected_count {
514 static const int value{0};
520 typename std::
enable_if<!is_mutable_container<T>::value && !is_wrapper<T>::value &&
521 !std::is_void<T>::value>::type> {
522 static constexpr int value{1};
532 static constexpr int value{expected_count<typename T::value_type>::value};
562 static constexpr object_category value{object_category::other};
569 typename std::
enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value && std::is_signed<T>::value &&
570 !is_bool<T>::value && !std::is_enum<T>::value>::type> {
571 static constexpr object_category value{object_category::integral_value};
577 typename std::
enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value &&
578 !std::is_same<T, char>::value && !is_bool<T>::value>::type> {
579 static constexpr object_category value{object_category::unsigned_integral};
585 static constexpr object_category value{object_category::char_value};
590 static constexpr object_category value{object_category::boolean_value};
595 static constexpr object_category value{object_category::floating_point};
601 typename std::
enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
602 std::is_assignable<T &, std::string>::value>::type> {
603 static constexpr object_category value{object_category::string_assignable};
610 typename std::
enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
611 !std::is_assignable<T &, std::string>::value && (type_count<T>::value == 1) &&
612 std::is_constructible<T, std::string>::value>::type> {
613 static constexpr object_category value{object_category::string_constructible};
618 static constexpr object_category value{object_category::enumeration};
622 static constexpr object_category value{object_category::complex_number};
628 using type =
typename std::conditional<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
629 !std::is_assignable<T &, std::string>::value &&
630 !std::is_constructible<T, std::string>::value && !is_complex<T>::value &&
631 !is_mutable_container<T>::value && !std::is_enum<T>::value,
633 std::false_type>::type;
634 static constexpr bool value = type::value;
640 typename std::
enable_if<(!is_mutable_container<T>::value && is_wrapper<T>::value &&
641 !is_tuple_like<T>::value && uncommon_type<T>::value)>::type> {
642 static constexpr object_category value{object_category::wrapper_value};
649 !is_wrapper<T>::value && is_direct_constructible<T, double>::value &&
650 is_direct_constructible<T, int>::value>::type> {
651 static constexpr object_category value{object_category::number_constructible};
658 !is_wrapper<T>::value && !is_direct_constructible<T, double>::value &&
659 is_direct_constructible<T, int>::value>::type> {
660 static constexpr object_category value{object_category::integer_constructible};
667 !is_wrapper<T>::value && is_direct_constructible<T, double>::value &&
668 !is_direct_constructible<T, int>::value>::type> {
669 static constexpr object_category value{object_category::double_constructible};
677 ((type_count<T>::value >= 2 && !is_wrapper<T>::value) ||
678 (uncommon_type<T>::value && !is_direct_constructible<T, double>::value &&
679 !is_direct_constructible<T, int>::value) ||
680 (uncommon_type<T>::value && type_count<T>::value >= 2))>::type> {
681 static constexpr object_category value{object_category::tuple_value};
691 static constexpr object_category value{object_category::container_value};
702constexpr const char *type_name() {
708 classify_object<T>::value == object_category::integer_constructible,
710constexpr const char *type_name() {
716constexpr const char *type_name() {
722 classify_object<T>::value == object_category::number_constructible ||
723 classify_object<T>::value == object_category::double_constructible,
725constexpr const char *type_name() {
732constexpr const char *type_name() {
739constexpr const char *type_name() {
746constexpr const char *type_name() {
753 classify_object<T>::value <= object_category::other,
755constexpr const char *type_name() {
762std::string type_name();
767 classify_object<T>::value == object_category::wrapper_value,
769std::string type_name();
775inline std::string type_name() {
780template <
typename T, std::
size_t I>
781inline typename std::enable_if<I == type_count_base<T>::value, std::string>::type
tuple_name() {
782 return std::string{};
786template <
typename T, std::
size_t I>
790 if(
str.back() ==
',')
799inline std::string type_name() {
801 tname.push_back(
']');
808 classify_object<T>::value == object_category::wrapper_value,
810inline std::string type_name() {
857 if(
input ==
"true") {
859 output =
static_cast<T
>(1);
876 std::int64_t
ret = 0;
877 if(
val.size() == 1) {
878 if(
val[0] >=
'1' &&
val[0] <=
'9') {
879 return (
static_cast<std::int64_t
>(
val[0]) -
'0');
894 throw std::invalid_argument(
"unrecognized character");
911 classify_object<T>::value == object_category::unsigned_integral,
921 if(
input.size() == 1) {
936 }
catch(
const std::invalid_argument &) {
938 }
catch(
const std::out_of_range &) {
967 auto nloc =
str1.find_last_of(
"+-");
968 if(
nloc != std::string::npos &&
nloc > 0) {
971 if(
str1.back() ==
'i' ||
str1.back() ==
'j')
975 if(
str1.back() ==
'i' ||
str1.back() ==
'j') {
1009template <
typename T,
1012 typename std::underlying_type<T>::type
val;
1021template <
typename T,
1023 std::is_assignable<T &, typename T::value_type>::value,
1026 typename T::value_type
val;
1034template <
typename T,
1036 !std::is_assignable<T &, typename T::value_type>::value && std::is_assignable<T &, T>::value,
1039 typename T::value_type
val;
1094template <
typename T,
1101#pragma warning(push)
1102#pragma warning(disable : 4800)
1120template <
typename T,
1125 "option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
1126 "is convertible from another type use the add_option<T, XC>(...) with XC being the known type");
1135 (classify_object<AssignTo>::value == object_category::string_assignable ||
1136 classify_object<AssignTo>::value == object_category::string_constructible),
1146 classify_object<AssignTo>::value != object_category::string_assignable &&
1147 classify_object<AssignTo>::value != object_category::string_constructible,
1162 classify_object<AssignTo>::value == object_category::wrapper_value,
1166 typename AssignTo::value_type
emptyVal{};
1178 classify_object<AssignTo>::value != object_category::wrapper_value &&
1179 std::is_assignable<AssignTo &, int>::value,
1213 std::is_move_assignable<AssignTo>::value,
1228 classify_object<AssignTo>::value <= object_category::wrapper_value,
1243 typename std::remove_const<typename std::tuple_element<0, ConvertTo>::type>::type
v1;
1244 typename std::tuple_element<1, ConvertTo>::type
v2;
1271 typename AssignTo::value_type
out;
1281 return (!
output.empty());
1292 if(
str1.back() ==
'i' ||
str1.back() ==
'j') {
1356 classify_object<ConvertTo>::value != object_category::wrapper_value &&
1372template <
class AssignTo,
class ConvertTo, std::
size_t I>
1379template <
class AssignTo,
class ConvertTo>
1388template <
class AssignTo,
class ConvertTo>
1399template <
class AssignTo,
class ConvertTo>
1400inline typename std::enable_if<is_mutable_container<ConvertTo>::value ||
1405 std::size_t index{subtype_count_min<ConvertTo>::value};
1406 const std::size_t
mx_count{subtype_count<ConvertTo>::value};
1416 std::vector<std::string>(
strings.begin(),
strings.begin() +
static_cast<std::ptrdiff_t
>(index)),
output);
1422template <
class AssignTo,
class ConvertTo, std::
size_t I>
1427 conditional<is_tuple_like<ConvertTo>::value,
typename std::tuple_element<I, ConvertTo>::type,
ConvertTo>::type;
1446 typename std::remove_const<typename std::tuple_element<0, typename ConvertTo::value_type>::type>::type
v1;
1447 typename std::tuple_element<1, typename ConvertTo::value_type>::type
v2;
1453 output.insert(
output.end(),
typename AssignTo::value_type{v1, v2});
1458 return (!
output.empty());
1471 "if the conversion type is defined as a tuple it must be the same size as the type you are converting to");
1486 std::vector<std::string>
temp;
1496 if(
static_cast<int>(
xcm) > type_count_min<ConvertTo>::value &&
is_separator(
temp.back())) {
1499 typename AssignTo::value_type
temp_out;
1517 std::is_assignable<ConvertTo &, ConvertTo>::value,
1524 typename ConvertTo::value_type
val;
1536 !std::is_assignable<AssignTo &, ConvertTo>::value,
1539 using ConvertType =
typename ConvertTo::value_type;
1563 }
catch(
const std::exception &) {
1575 if(
val <=
static_cast<double>((std::numeric_limits<std::int64_t>::min)()) ||
1576 val >=
static_cast<double>((std::numeric_limits<std::int64_t>::max)()) ||
1577 std::ceil(
val) == std::floor(
val)) {
Check for complex.
Definition TypeTools.hpp:206
static constexpr bool value
Definition TypeTools.hpp:213
Definition TypeTools.hpp:156
static constexpr bool value
Definition TypeTools.hpp:175
Check for input streamability.
Definition TypeTools.hpp:195
static constexpr bool value
Definition TypeTools.hpp:202
Definition TypeTools.hpp:184
static constexpr bool value
Definition TypeTools.hpp:191
Definition TypeTools.hpp:268
static constexpr bool value
Definition TypeTools.hpp:276
constexpr enabler dummy
An instance to use in EnableIf.
Definition TypeTools.hpp:35
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:281
auto checked_to_string(T &&value) -> decltype(to_string(std::forward< T >(value)))
special template overload
Definition TypeTools.hpp:337
bool is_separator(const std::string &str)
check if a string is a container segment separator (empty or "%%")
Definition StringTools.hpp:163
bool from_stream(const std::string &istring, T &obj)
Templated operation to get a value from a stream.
Definition TypeTools.hpp:218
constexpr int expected_max_vector_size
Definition StringTools.hpp:45
std::string value_string(const T &value)
get a string as a convertible value for arithmetic types
Definition TypeTools.hpp:351
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition StringTools.hpp:51
bool lexical_assign(const std::string &input, AssignTo &output)
Assign a value through lexical cast operations.
Definition TypeTools.hpp:1138
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition StringTools.hpp:174
enabler
Simple empty scoped class.
Definition TypeTools.hpp:32
bool lexical_cast(const std::string &input, T &output)
Integer conversion.
Definition TypeTools.hpp:913
std::int64_t to_flag_value(std::string val)
Convert a flag into an integer value typically binary flags.
Definition TypeTools.hpp:866
constexpr std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size()
0 if the index > tuple size
Definition TypeTools.hpp:441
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)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::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() { auto 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, ' integral_conversion[')+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()||input.front()=='-') { return false;} char *val=nullptr;errno=0;std::uint64_t output_ll=std::strtoull(input.c_str(), &val, 0);if(errno==ERANGE) { return false;} 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) :static_cast< T >(output_sll);return(static_cast< std::int64_t >(output)==output_sll);} return false;}template< typename T, enable_if_t< std::is_signed< T >::value, detail::enabler >=detail::dummy > bool(const std::string &input, T &output) noexcept
Recursively generate the tuple type name.
Definition TypeTools.hpp:843
typename make_void< Ts... >::type void_t
A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine.
Definition TypeTools.hpp:51
typename std::enable_if< B, T >::type enable_if_t
Definition TypeTools.hpp:43
typename std::conditional< B, T, F >::type conditional_t
A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine...
Definition TypeTools.hpp:54
std::string type
Definition TypeTools.hpp:83
This can be specialized to override the type deduction for IsMember.
Definition TypeTools.hpp:77
T type
Definition TypeTools.hpp:78
typename std::pointer_traits< T >::element_type type
Definition TypeTools.hpp:99
not a pointer
Definition TypeTools.hpp:94
T type
Definition TypeTools.hpp:95
Definition TypeTools.hpp:104
typename element_type< T >::type::value_type type
Definition TypeTools.hpp:105
Definition TypeTools.hpp:231
Definition TypeTools.hpp:249
Definition TypeTools.hpp:261
typename std::remove_const< typename value_type::first_type >::type first_type
Definition TypeTools.hpp:132
static auto first(Q &&pair_value) -> decltype(std::get< 0 >(std::forward< Q >(pair_value)))
Get the first value (really just the underlying value)
Definition TypeTools.hpp:136
static auto second(Q &&pair_value) -> decltype(std::get< 1 >(std::forward< Q >(pair_value)))
Get the second value (really just the underlying value)
Definition TypeTools.hpp:140
typename T::value_type value_type
Definition TypeTools.hpp:131
typename std::remove_const< typename value_type::second_type >::type second_type
Definition TypeTools.hpp:133
Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost ...
Definition TypeTools.hpp:109
typename T::value_type value_type
Definition TypeTools.hpp:110
typename std::remove_const< value_type >::type second_type
Definition TypeTools.hpp:112
static auto second(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the second value (really just the underlying value)
Definition TypeTools.hpp:119
typename std::remove_const< value_type >::type first_type
Definition TypeTools.hpp:111
static auto first(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the first value (really just the underlying value)
Definition TypeTools.hpp:115
forward declare the subtype_count_min structure
Definition TypeTools.hpp:406
Set of overloads to get the type size of an object.
Definition TypeTools.hpp:403
This will only trigger for actual void type.
Definition TypeTools.hpp:377
static const int value
Definition TypeTools.hpp:378
This will only trigger for actual void type.
Definition TypeTools.hpp:409
static const int value
Definition TypeTools.hpp:410
typename T::value_type type
Definition TypeTools.hpp:373
template to get the underlying value type if it exists or use a default
Definition TypeTools.hpp:367
def type
Definition TypeTools.hpp:368
Check to see if something is bool (fail check by default)
Definition TypeTools.hpp:57
Check to see if something is copyable pointer.
Definition TypeTools.hpp:72
static bool const value
Definition TypeTools.hpp:73
Check to see if something is a shared pointer.
Definition TypeTools.hpp:63
A copy of std::void_t from C++17 (helper for C++11 and C++14)
Definition TypeTools.hpp:46
void type
Definition TypeTools.hpp:47