#pragma once // Distributed under the LGPL v2.1 license. See accompanying // file LICENSE or https://github.com/henryiii/CLI11 for details. #include #include #include #include namespace CLI { // Type tools // Copied from C++14 #if __cplusplus < 201402L template< bool B, class T = void > using enable_if_t = typename std::enable_if::type; #else // If your compiler supports C++14, you can use that definition instead using std::enable_if_t; #endif template struct is_vector { static const bool value = false; }; template struct is_vector > { static bool const value = true; }; template struct is_bool { static const bool value = false; }; template<> struct is_bool { static bool const value = true; }; namespace detail { // Based generally on https://rmf.io/cxx11/almost-static-if /// Simple empty scoped class enum class enabler {}; /// An instance to use in EnableIf constexpr enabler dummy = {}; // Type name print /// Was going to be based on /// http://stackoverflow.com/questions/1055452/c-get-name-of-type-in-template /// But this is cleaner and works better in this case template::value && std::is_signed::value, detail::enabler> = detail::dummy> constexpr const char* type_name() { return "INT"; } template::value && std::is_unsigned::value, detail::enabler> = detail::dummy> constexpr const char* type_name() { return "UINT"; } template::value, detail::enabler> = detail::dummy> constexpr const char* type_name() { return "FLOAT"; } /// This one should not be used, since vector types print the internal type template::value, detail::enabler> = detail::dummy> constexpr const char* type_name() { return "VECTOR"; } template::value && !std::is_integral::value && !is_vector::value , detail::enabler> = detail::dummy> constexpr const char* type_name() { return "TEXT"; } // Lexical cast /// Integers template::value, detail::enabler> = detail::dummy> bool lexical_cast(std::string input, T& output) { try{ output = (T) std::stoll(input); return true; } catch (std::invalid_argument) { return false; } catch (std::out_of_range) { return false; } } /// Floats template::value, detail::enabler> = detail::dummy> bool lexical_cast(std::string input, T& output) { try{ output = (T) std::stold(input); return true; } catch (std::invalid_argument) { return false; } catch (std::out_of_range) { return false; } } /// String and similar template::value && !std::is_integral::value , detail::enabler> = detail::dummy> bool lexical_cast(std::string input, T& output) { output = input; return true; } } }