add support for std::optional when extracting

This commit is contained in:
ado 2020-12-11 21:17:07 +01:00
parent 0d84fcf7e8
commit 0c25efd353
2 changed files with 34 additions and 6 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "type_traits.hpp"
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <limits> #include <limits>
@ -313,18 +314,15 @@ struct unsupported_type {
} /* namespace */ } /* namespace */
template <typename T> template <typename T>
std::enable_if_t<!std::is_integral_v<T> && !std::is_floating_point_v<T>, bool> std::enable_if_t<!std::is_integral_v<T> && !std::is_floating_point_v<T> &&
!is_instance_of<T, std::optional>::value,
bool>
extract(const char*, const char*, T&) { extract(const char*, const char*, T&) {
static_assert(error::unsupported_type<T>::value, static_assert(error::unsupported_type<T>::value,
"Conversion for given type is not defined, an " "Conversion for given type is not defined, an "
"\'extract\' function needs to be defined!"); "\'extract\' function needs to be defined!");
} }
////////////////
// extract specialization
////////////////
template <typename T> template <typename T>
std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>, bool> std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>, bool>
extract(const char* begin, const char* end, T& value) { extract(const char* begin, const char* end, T& value) {
@ -336,6 +334,22 @@ extract(const char* begin, const char* end, T& value) {
return true; return true;
} }
template <typename T>
std::enable_if_t<is_instance_of<T, std::optional>::value, bool> extract(
const char* begin, const char* end, T& value) {
typename T::value_type raw_value;
if (extract(begin, end, raw_value)) {
value = raw_value;
} else {
value = std::nullopt;
}
return true;
}
////////////////
// extract specialization
////////////////
template <> template <>
inline bool extract(const char* begin, const char* end, bool& value) { inline bool extract(const char* begin, const char* end, bool& value) {
if (end == begin + 1) { if (end == begin + 1) {

View File

@ -308,6 +308,20 @@ struct none_of<Trait, std::tuple<Ts...>> {
static constexpr bool value = count<Trait, Ts...>::size == 0; static constexpr bool value = count<Trait, Ts...>::size == 0;
}; };
////////////////
// is instance of
////////////////
template <typename, template <class> class>
struct is_instance_of {
constexpr static bool value = false;
};
template <typename T, template <class> class U>
struct is_instance_of<U<T>, U> {
constexpr static bool value = true;
};
//////////////// ////////////////
// tuple to struct // tuple to struct
//////////////// ////////////////