mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 00:38:08 +08:00
fix(#279): fix compilation with older msvc
by avoiding known SFINAE problem in msvc 2017
This commit is contained in:
33
appveyor.yml
33
appveyor.yml
@@ -2,27 +2,40 @@ version: "{build}"
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
MSVC_VERSION: 2017
|
||||
CXX_VERSION: 11
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
MSVC_VERSION: 2017
|
||||
CXX_VERSION: 14
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
MSVC_VERSION: 2017
|
||||
CXX_VERSION: 17
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
generator: Visual Studio 16 2019
|
||||
systemver: 10.0.18362.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
generator: Visual Studio 17 2022
|
||||
systemver: 10.0.22621.0
|
||||
MSVC_VERSION: 2019
|
||||
CXX_VERSION: 11
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
MSVC_VERSION: 2019
|
||||
CXX_VERSION: 14
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
MSVC_VERSION: 2019
|
||||
CXX_VERSION: 17
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
- Debug
|
||||
|
||||
clone_depth: 10
|
||||
clone_folder: c:\toml11
|
||||
|
||||
install:
|
||||
- git submodule update --init --recursive
|
||||
- git submodule update --init --recursive
|
||||
|
||||
build_script:
|
||||
- '"C:\Program Files (x86)\Microsoft Visual Studio\%MSVC_VERSION%\Community\VC\Auxiliary\Build\vcvarsall.bat" x64'
|
||||
- cd C:\toml11
|
||||
- cmake -B build -G"%generator%" -DCMAKE_SYSTEM_VERSION="%systemver%" -A x64 -DCMAKE_CXX_STANDARD=11 -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=ON
|
||||
- cmake --build build --config "%configuration%"
|
||||
- cmake -B build -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_CXX_STANDARD=%CXX_VERSION% -DTOML11_BUILD_TESTS=ON -DBUILD_TESTING=ON -DTOML11_PRECOMPILE=ON
|
||||
- cmake --build build
|
||||
|
||||
test_script:
|
||||
- ctest --test-dir build --build-config "%configuration%" --timeout 300 --output-on-failure
|
||||
- cd build\tests\
|
||||
- ctest --timeout 300 --output-on-failure
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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<
|
||||
|
@@ -21,6 +21,7 @@ set(TOML11_TEST_NAMES
|
||||
test_parse_inline_table
|
||||
test_parse_table_keys
|
||||
test_parse_table
|
||||
test_parse
|
||||
test_result
|
||||
test_scanner
|
||||
test_serialize
|
||||
|
50
tests/test_parse.cpp
Normal file
50
tests/test_parse.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include "doctest.h"
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
#include <clocale>
|
||||
|
||||
TEST_CASE("testing toml::parse(file)")
|
||||
{
|
||||
using namespace toml::literals::toml_literals;
|
||||
|
||||
const std::string spec_example(R"(# This is a TOML document
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
dob = 1979-05-27T07:32:00-08:00
|
||||
|
||||
[database]
|
||||
enabled = true
|
||||
ports = [ 8000, 8001, 8002 ]
|
||||
data = [ ["delta", "phi"], [3.14] ]
|
||||
temp_targets = { cpu = 79.5, case = 72.0 }
|
||||
|
||||
[servers]
|
||||
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
role = "frontend"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
role = "backend"
|
||||
)");
|
||||
|
||||
{
|
||||
std::ofstream ofs("test_parse.toml");
|
||||
ofs << spec_example;
|
||||
}
|
||||
|
||||
const auto u = toml::parse_str(spec_example);
|
||||
const auto v = toml::parse("test_parse.toml");
|
||||
|
||||
CHECK_EQ(u, v);
|
||||
|
||||
CHECK_EQ(toml::find<int>(v, "database", "ports", 0), 8000);
|
||||
CHECK_EQ(toml::find<int>(v, "database", "ports", 1), 8001);
|
||||
CHECK_EQ(toml::find<int>(v, "database", "ports", 2), 8002);
|
||||
}
|
Reference in New Issue
Block a user