mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 17:58:09 +08:00
move return_type_of_t from result to traits
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_RESULT_H
|
#ifndef TOML11_RESULT_H
|
||||||
#define TOML11_RESULT_H
|
#define TOML11_RESULT_H
|
||||||
|
#include "traits.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -13,19 +14,6 @@
|
|||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
#if __cplusplus >= 201703L
|
|
||||||
|
|
||||||
template<typename F, typename ... Args>
|
|
||||||
using return_type_of_t = std::invoke_result_t<F, Args...>;
|
|
||||||
|
|
||||||
#else
|
|
||||||
// result_of is deprecated after C++17
|
|
||||||
template<typename F, typename ... Args>
|
|
||||||
using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct success
|
struct success
|
||||||
{
|
{
|
||||||
@@ -441,21 +429,21 @@ struct result
|
|||||||
// F: T -> U
|
// F: T -> U
|
||||||
// retval: result<U, E>
|
// retval: result<U, E>
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type&>, error_type>
|
result<detail::return_type_of_t<F, value_type&>, error_type>
|
||||||
map(F&& f) &
|
map(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(this->as_ok()));}
|
if(this->is_ok()){return ok(f(this->as_ok()));}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type const&>, error_type>
|
result<detail::return_type_of_t<F, value_type const&>, error_type>
|
||||||
map(F&& f) const&
|
map(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(this->as_ok()));}
|
if(this->is_ok()){return ok(f(this->as_ok()));}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type &&>, error_type>
|
result<detail::return_type_of_t<F, value_type &&>, error_type>
|
||||||
map(F&& f) &&
|
map(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(std::move(this->as_ok())));}
|
if(this->is_ok()){return ok(f(std::move(this->as_ok())));}
|
||||||
@@ -466,21 +454,21 @@ struct result
|
|||||||
// F: E -> F
|
// F: E -> F
|
||||||
// retval: result<T, F>
|
// retval: result<T, F>
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type&>>
|
result<value_type, detail::return_type_of_t<F, error_type&>>
|
||||||
map_err(F&& f) &
|
map_err(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(this->as_err()));}
|
if(this->is_err()){return err(f(this->as_err()));}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type const&>>
|
result<value_type, detail::return_type_of_t<F, error_type const&>>
|
||||||
map_err(F&& f) const&
|
map_err(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(this->as_err()));}
|
if(this->is_err()){return err(f(this->as_err()));}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type&&>>
|
result<value_type, detail::return_type_of_t<F, error_type&&>>
|
||||||
map_err(F&& f) &&
|
map_err(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(std::move(this->as_err())));}
|
if(this->is_err()){return err(f(std::move(this->as_err())));}
|
||||||
@@ -491,21 +479,21 @@ struct result
|
|||||||
// F: T -> U
|
// F: T -> U
|
||||||
// retval: U
|
// retval: U
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type&>
|
detail::return_type_of_t<F, value_type&>
|
||||||
map_or_else(F&& f, U&& opt) &
|
map_or_else(F&& f, U&& opt) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
return f(this->as_ok());
|
return f(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type const&>
|
detail::return_type_of_t<F, value_type const&>
|
||||||
map_or_else(F&& f, U&& opt) const&
|
map_or_else(F&& f, U&& opt) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
return f(this->as_ok());
|
return f(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type&&>
|
detail::return_type_of_t<F, value_type&&>
|
||||||
map_or_else(F&& f, U&& opt) &&
|
map_or_else(F&& f, U&& opt) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
@@ -516,21 +504,21 @@ struct result
|
|||||||
// F: E -> U
|
// F: E -> U
|
||||||
// retval: U
|
// retval: U
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type&>
|
detail::return_type_of_t<F, error_type&>
|
||||||
map_err_or_else(F&& f, U&& opt) &
|
map_err_or_else(F&& f, U&& opt) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
return f(this->as_err());
|
return f(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type const&>
|
detail::return_type_of_t<F, error_type const&>
|
||||||
map_err_or_else(F&& f, U&& opt) const&
|
map_err_or_else(F&& f, U&& opt) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
return f(this->as_err());
|
return f(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type&&>
|
detail::return_type_of_t<F, error_type&&>
|
||||||
map_err_or_else(F&& f, U&& opt) &&
|
map_err_or_else(F&& f, U&& opt) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
@@ -542,21 +530,21 @@ struct result
|
|||||||
// toml::err(error_type) should be convertible to U.
|
// toml::err(error_type) should be convertible to U.
|
||||||
// normally, type U is another result<S, F> and E is convertible to F
|
// normally, type U is another result<S, F> and E is convertible to F
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type&>
|
detail::return_type_of_t<F, value_type&>
|
||||||
and_then(F&& f) &
|
and_then(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(this->as_ok());}
|
if(this->is_ok()){return f(this->as_ok());}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type const&>
|
detail::return_type_of_t<F, value_type const&>
|
||||||
and_then(F&& f) const&
|
and_then(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(this->as_ok());}
|
if(this->is_ok()){return f(this->as_ok());}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type&&>
|
detail::return_type_of_t<F, value_type&&>
|
||||||
and_then(F&& f) &&
|
and_then(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(std::move(this->as_ok()));}
|
if(this->is_ok()){return f(std::move(this->as_ok()));}
|
||||||
@@ -568,21 +556,21 @@ struct result
|
|||||||
// toml::ok(value_type) should be convertible to U.
|
// toml::ok(value_type) should be convertible to U.
|
||||||
// normally, type U is another result<S, F> and T is convertible to S
|
// normally, type U is another result<S, F> and T is convertible to S
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type&>
|
detail::return_type_of_t<F, error_type&>
|
||||||
or_else(F&& f) &
|
or_else(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(this->as_err());}
|
if(this->is_err()){return f(this->as_err());}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type const&>
|
detail::return_type_of_t<F, error_type const&>
|
||||||
or_else(F&& f) const&
|
or_else(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(this->as_err());}
|
if(this->is_err()){return f(this->as_err());}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type&&>
|
detail::return_type_of_t<F, error_type&&>
|
||||||
or_else(F&& f) &&
|
or_else(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(std::move(this->as_err()));}
|
if(this->is_err()){return f(std::move(this->as_err()));}
|
||||||
|
@@ -15,6 +15,9 @@ namespace detail
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
using unwrap_t = typename std::decay<T>::type;
|
using unwrap_t = typename std::decay<T>::type;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// check whether type T is a kind of container/map class
|
||||||
|
|
||||||
struct has_iterator_impl
|
struct has_iterator_impl
|
||||||
{
|
{
|
||||||
template<typename T> static std::true_type check(typename T::iterator*);
|
template<typename T> static std::true_type check(typename T::iterator*);
|
||||||
@@ -63,6 +66,9 @@ struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){}
|
|||||||
#undef decltype(...)
|
#undef decltype(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// C++17 and/or/not
|
||||||
|
|
||||||
template<typename ...> struct conjunction : std::true_type{};
|
template<typename ...> struct conjunction : std::true_type{};
|
||||||
template<typename T> struct conjunction<T> : T{};
|
template<typename T> struct conjunction<T> : T{};
|
||||||
template<typename T, typename ... Ts>
|
template<typename T, typename ... Ts>
|
||||||
@@ -80,6 +86,9 @@ struct disjunction<T, Ts...> :
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
|
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// normal type checker
|
||||||
|
|
||||||
template<typename T> struct is_std_pair : std::false_type{};
|
template<typename T> struct is_std_pair : std::false_type{};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
|
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
|
||||||
@@ -92,7 +101,9 @@ template<typename T> struct is_chrono_duration: std::false_type{};
|
|||||||
template<typename Rep, typename Period>
|
template<typename Rep, typename Period>
|
||||||
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};
|
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};
|
||||||
|
|
||||||
// to use toml::get<std::tuple<T1, T2, ...>> in C++11
|
// ---------------------------------------------------------------------------
|
||||||
|
// C++14 index_sequence
|
||||||
|
|
||||||
template<std::size_t ... Ns> struct index_sequence{};
|
template<std::size_t ... Ns> struct index_sequence{};
|
||||||
|
|
||||||
template<typename IS, std::size_t N> struct push_back_index_sequence{};
|
template<typename IS, std::size_t N> struct push_back_index_sequence{};
|
||||||
@@ -116,6 +127,21 @@ struct index_sequence_maker<0>
|
|||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
using make_index_sequence = typename index_sequence_maker<N-1>::type;
|
using make_index_sequence = typename index_sequence_maker<N-1>::type;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// return_type_of_t
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
|
||||||
|
template<typename F, typename ... Args>
|
||||||
|
using return_type_of_t = std::invoke_result_t<F, Args...>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// result_of is deprecated after C++17
|
||||||
|
template<typename F, typename ... Args>
|
||||||
|
using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}// detail
|
}// detail
|
||||||
}//toml
|
}//toml
|
||||||
#endif // TOML_TRAITS
|
#endif // TOML_TRAITS
|
||||||
|
Reference in New Issue
Block a user