diff --git a/appveyor.yml b/appveyor.yml index ea6dc3c..300f62f 100644 --- a/appveyor.yml +++ b/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 diff --git a/include/toml11/compat.hpp b/include/toml11/compat.hpp index c954bf2..15a00af 100644 --- a/include/toml11/compat.hpp +++ b/include/toml11/compat.hpp @@ -386,6 +386,35 @@ using return_type_of_t = typename std::result_of::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 +using void_t = void; + +#endif // TOML11_HAS_STD_VOID_T + +} // cxx +} // toml + // ---------------------------------------------------------------------------- // (subset of) source_location diff --git a/include/toml11/types.hpp b/include/toml11/types.hpp index 75f55b2..6d59b99 100644 --- a/include/toml11/types.hpp +++ b/include/toml11/types.hpp @@ -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 static std::true_type check(typename T::comment_type*); - template static std::false_type check(...); -}; +template +struct has_comment_type: std::false_type{}; template -using has_comment_type = decltype(has_comment_type_impl::check(nullptr)); +struct has_comment_type>: std::true_type{}; -struct has_integer_type_impl -{ - template static std::true_type check(typename T::integer_type*); - template static std::false_type check(...); -}; +template +struct has_integer_type: std::false_type{}; template -using has_integer_type = decltype(has_integer_type_impl::check(nullptr)); +struct has_integer_type>: std::true_type{}; -struct has_floating_type_impl -{ - template static std::true_type check(typename T::floating_type*); - template static std::false_type check(...); -}; +template +struct has_floating_type: std::false_type{}; template -using has_floating_type = decltype(has_floating_type_impl::check(nullptr)); +struct has_floating_type>: std::true_type{}; -struct has_string_type_impl -{ - template static std::true_type check(typename T::string_type*); - template static std::false_type check(...); -}; +template +struct has_string_type: std::false_type{}; template -using has_string_type = decltype(has_string_type_impl::check(nullptr)); +struct has_string_type>: std::true_type{}; -struct has_array_type_impl -{ - template static std::true_type check(typename T::template array_type*); - template static std::false_type check(...); -}; +template +struct has_array_type: std::false_type{}; template -using has_array_type = decltype(has_array_type_impl::check(nullptr)); +struct has_array_type>>: std::true_type{}; -struct has_table_type_impl -{ - template static std::true_type check(typename T::template table_type*); - template static std::false_type check(...); -}; +template +struct has_table_type: std::false_type{}; template -using has_table_type = decltype(has_table_type_impl::check(nullptr)); +struct has_table_type>>: std::true_type{}; -struct has_parse_int_impl -{ - template static std::true_type check(decltype(std::declval().parse_int( - std::declval(), - std::declval(), - std::declval() - ))*); - template static std::false_type check(...); -}; +template +struct has_parse_int: std::false_type{}; template -using has_parse_int = decltype(has_parse_int_impl::check(nullptr)); +struct has_parse_int().parse_int( + std::declval(), + std::declval<::toml::source_location const&>(), + std::declval() + ))>>: std::true_type{}; -struct has_parse_float_impl -{ - template static std::true_type check(decltype(std::declval().parse_float( - std::declval(), - std::declval(), - std::declval() - ))*); - template static std::false_type check(...); -}; +template +struct has_parse_float: std::false_type{}; template -using has_parse_float = decltype(has_parse_float_impl::check(nullptr)); +struct has_parse_float().parse_float( + std::declval(), + std::declval<::toml::source_location const&>(), + std::declval() + ))>>: std::true_type{}; template using is_type_config = cxx::conjunction< diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 37dfea8..5e323bf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 diff --git a/tests/test_parse.cpp b/tests/test_parse.cpp new file mode 100644 index 0000000..65495d0 --- /dev/null +++ b/tests/test_parse.cpp @@ -0,0 +1,50 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +#include + +#include + +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(v, "database", "ports", 0), 8000); + CHECK_EQ(toml::find(v, "database", "ports", 1), 8001); + CHECK_EQ(toml::find(v, "database", "ports", 2), 8002); +}