#pragma once #include #include #include #include namespace program::detail { template struct has_cast : std::false_type {}; template struct has_cast()))>> : std::true_type {}; } namespace program { inline std::string join(std::string const & tok, std::vector const & data) { std::string accum = data.empty() ? "" : data.front(); for (size_t i = 1; i < data.size(); ++i) { accum += tok; accum += data[i]; } return accum; } template struct conversion_helper; /** * \brief Conversion method for positional arguments. Positional arguments are * always represented with a singular string. * \param name The name of the argument being parsed, for logging purposes * \param data A string containing the value to be processed. * \return An object of the given type */ template T convert(std::string const & name, std::string const & data) { if (auto [rval, success] = string_utils::cast(data); success) { return rval; } else { throw ArgumentStructureError("unable to parse", name); } } /** * \brief Conversion method for command-line options. Because some options are * repeatable, we need to pass in a vector of objects that might be used. * \param name The name of the option being parsed, for logging purposes * \param data A vector of arguments assigned to this option. * \invariant data.size() > 0 * \return An object of the given type * \throws ArgumentStructureError if the argument has been repeated but is * not a repeatable type. */ template T convert(std::string const & name, std::vector const & data) { if constexpr (detail::has_cast{}) { if (data.size() != 1) { throw ArgumentStructureError("repeated option not allowed", name); } else { return convert(name, data.front()); } } else { if (auto [rval, success] = string_utils::cast(data); success) { return rval; } else { throw ArgumentStructureError("unable to parse", name); } } } using std::to_string; template std::string to_string(T const &) { return "?"; } inline std::string to_string(char const * str) { return str; } inline std::string const & to_string(std::string const & str) { return str; } }