fix(#279): fix compilation with older msvc

by avoiding known SFINAE problem in msvc 2017
This commit is contained in:
ToruNiina
2025-01-13 00:47:58 +09:00
parent c9a00dea5c
commit 844e8fd4e0
5 changed files with 136 additions and 66 deletions

View File

@@ -386,6 +386,35 @@ using return_type_of_t = typename std::result_of<F(Args...)>::type;
} // cxx
} // toml
// ---------------------------------------------------------------------------
// C++17 void_t
#if TOML11_CPLUSPLUS_STANDARD_VERSION >= TOML11_CXX17_VALUE
# if defined(__cpp_lib_void_t)
# if __cpp_lib_void_t >= 201411L
# define TOML11_HAS_STD_VOID_T 1
# endif
# endif
#endif
namespace toml
{
namespace cxx
{
#if defined(TOML11_HAS_STD_VOID_T)
using std::void_t;
#else
template<typename ...>
using void_t = void;
#endif // TOML11_HAS_STD_VOID_T
} // cxx
} // toml
// ----------------------------------------------------------------------------
// (subset of) source_location

View File

@@ -2,6 +2,7 @@
#define TOML11_TYPES_HPP
#include "comments.hpp"
#include "compat.hpp"
#include "error_info.hpp"
#include "format.hpp"
#include "ordered_map.hpp"
@@ -299,77 +300,53 @@ namespace detail
// ----------------------------------------------------------------------------
// check if type T has all the needed member types
struct has_comment_type_impl
{
template<typename T> static std::true_type check(typename T::comment_type*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_comment_type: std::false_type{};
template<typename T>
using has_comment_type = decltype(has_comment_type_impl::check<T>(nullptr));
struct has_comment_type<T, cxx::void_t<typename T::comment_type>>: std::true_type{};
struct has_integer_type_impl
{
template<typename T> static std::true_type check(typename T::integer_type*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_integer_type: std::false_type{};
template<typename T>
using has_integer_type = decltype(has_integer_type_impl::check<T>(nullptr));
struct has_integer_type<T, cxx::void_t<typename T::integer_type>>: std::true_type{};
struct has_floating_type_impl
{
template<typename T> static std::true_type check(typename T::floating_type*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_floating_type: std::false_type{};
template<typename T>
using has_floating_type = decltype(has_floating_type_impl::check<T>(nullptr));
struct has_floating_type<T, cxx::void_t<typename T::floating_type>>: std::true_type{};
struct has_string_type_impl
{
template<typename T> static std::true_type check(typename T::string_type*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_string_type: std::false_type{};
template<typename T>
using has_string_type = decltype(has_string_type_impl::check<T>(nullptr));
struct has_string_type<T, cxx::void_t<typename T::string_type>>: std::true_type{};
struct has_array_type_impl
{
template<typename T> static std::true_type check(typename T::template array_type<int>*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_array_type: std::false_type{};
template<typename T>
using has_array_type = decltype(has_array_type_impl::check<T>(nullptr));
struct has_array_type<T, cxx::void_t<typename T::template array_type<int>>>: std::true_type{};
struct has_table_type_impl
{
template<typename T> static std::true_type check(typename T::template table_type<int, int>*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_table_type: std::false_type{};
template<typename T>
using has_table_type = decltype(has_table_type_impl::check<T>(nullptr));
struct has_table_type<T, cxx::void_t<typename T::template table_type<int, int>>>: std::true_type{};
struct has_parse_int_impl
{
template<typename T> static std::true_type check(decltype(std::declval<T>().parse_int(
std::declval<const std::string&>(),
std::declval<const source_location>(),
std::declval<const std::uint8_t>()
))*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_parse_int: std::false_type{};
template<typename T>
using has_parse_int = decltype(has_parse_int_impl::check<T>(nullptr));
struct has_parse_int<T, cxx::void_t<decltype(std::declval<T>().parse_int(
std::declval<std::string const&>(),
std::declval<::toml::source_location const&>(),
std::declval<std::uint8_t>()
))>>: std::true_type{};
struct has_parse_float_impl
{
template<typename T> static std::true_type check(decltype(std::declval<T>().parse_float(
std::declval<const std::string&>(),
std::declval<const source_location>(),
std::declval<const bool>()
))*);
template<typename T> static std::false_type check(...);
};
template<typename T, typename U = void>
struct has_parse_float: std::false_type{};
template<typename T>
using has_parse_float = decltype(has_parse_float_impl::check<T>(nullptr));
struct has_parse_float<T, cxx::void_t<decltype(std::declval<T>().parse_float(
std::declval<std::string const&>(),
std::declval<::toml::source_location const&>(),
std::declval<bool>()
))>>: std::true_type{};
template<typename T>
using is_type_config = cxx::conjunction<