From 94e76f5a1a7496a2b10548c65ecd202eb51d7f43 Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 28 Apr 2018 13:07:48 +0200 Subject: [PATCH] Add experimental methods to convert argument values * Currently lacks error handling * Needs testing --- application/argumentparser.h | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/application/argumentparser.h b/application/argumentparser.h index 37f355b..430bebb 100644 --- a/application/argumentparser.h +++ b/application/argumentparser.h @@ -1,7 +1,9 @@ #ifndef APPLICATION_UTILITIES_ARGUMENTPARSER_H #define APPLICATION_UTILITIES_ARGUMENTPARSER_H +#include "../conversion/stringconversion.h" #include "../global.h" +#include "../misc/traits.h" #include #include @@ -122,8 +124,27 @@ constexpr bool operator&(ValueCompletionBehavior lhs, ValueCompletionBehavior rh } /// \endcond +// TODO v5: Make function private Argument CPP_UTILITIES_EXPORT *firstPresentUncombinableArg(const ArgumentVector &args, const Argument *except); +/*! + * \brief Contains functions to convert raw argument values to certain types. + * \remarks Still experimental. Might be removed/adjusted in next minor release. + */ +namespace ValueConversion { +template TargetType convert(const char *value); + +template >> TargetType convert(const char *value) +{ + return std::string(value); +} + +template >> TargetType convert(const char *value) +{ + return ConversionUtilities::stringToNumber(value); +} +} // namespace ValueConversion + /*! * \brief The ArgumentOccurrence struct holds argument values for an occurrence of an argument. */ @@ -146,8 +167,44 @@ struct CPP_UTILITIES_EXPORT ArgumentOccurrence { * \remarks Empty for top-level occurrences. */ std::vector path; + + template std::tuple convertValues() const; + template std::tuple convertValues() const; + +private: + template + std::tuple convertValues(std::vector::const_iterator firstValue) const; }; +/*! + * \brief Converts the present value to the specified target type. There must be at least one value present. + * \remarks Still experimental. Might be removed/adjusted in next minor release. + */ +template std::tuple ArgumentOccurrence::convertValues() const +{ + return std::make_tuple(ValueConversion::convert(values.front())); +} + +/*! + * \brief Converts the present values to the specified target types. There must be as many values present as types are specified. + * \remarks Still experimental. Might be removed/adjusted in next minor release. + */ +template +std::tuple ArgumentOccurrence::convertValues() const +{ + return std::tuple_cat(std::make_tuple(ValueConversion::convert(values.front())), + convertValues(values.cbegin() + 1)); +} + +/// \cond +template +std::tuple ArgumentOccurrence::convertValues(std::vector::const_iterator firstValue) const +{ + return std::tuple_cat(std::make_tuple(ValueConversion::convert(*firstValue)), + convertValues(firstValue + 1)); +} +/// \endcond + /*! * \brief Constructs an argument occurrence for the specified \a index. */ @@ -234,6 +291,9 @@ public: // declare getter/read-only properties for parsing results: those properties will be populated when parsing const std::vector &values(std::size_t occurrence = 0) const; + template std::tuple convertValues(std::size_t occurrence = 0) const; + template std::vector> convertAllValues() const; + const char *firstValue() const; bool allRequiredValuesPresent(std::size_t occurrence = 0) const; bool isPresent() const; @@ -282,6 +342,29 @@ private: const char *m_preDefinedCompletionValues; }; +/*! + * \brief Converts the present values for the specified \a occurrence to the specified target types. There must be as many values present as types are specified. + * \remarks Still experimental. Might be removed/adjusted in next minor release. + */ +template std::tuple Argument::convertValues(std::size_t occurrence) const +{ + return m_occurrences[occurrence].convertValues(); +} + +/*! + * \brief Converts the present values for all occurrence to the specified target types. For each occurrence, there must be as many values present as types are specified. + * \remarks Still experimental. Might be removed/adjusted in next minor release. + */ +template std::vector> Argument::convertAllValues() const +{ + std::vector> res; + res.reserve(m_occurrences.size()); + for (const auto &occurrence : m_occurrences) { + res.emplace_back(occurrence.convertValues()); + } + return res; +} + class CPP_UTILITIES_EXPORT ArgumentParser { friend ArgumentParserTests; friend ArgumentReader;