From 02fd8a577bd36823b36823120ecf14c2573b5303 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 17 Dec 2021 22:29:57 +0900 Subject: [PATCH] feat: workaround __cplusplus problem on MSVC --- tests/test_comments.cpp | 2 +- tests/test_find.cpp | 4 +-- tests/test_find_or.cpp | 2 +- tests/test_find_or_recursive.cpp | 2 +- tests/test_get.cpp | 4 +-- tests/test_get_or.cpp | 2 +- tests/test_string.cpp | 2 +- tests/test_value.cpp | 4 +-- toml.hpp | 8 ------ toml/string.hpp | 5 +++- toml/traits.hpp | 17 +++++++------ toml/utility.hpp | 9 ++++--- toml/version.hpp | 42 ++++++++++++++++++++++++++++++++ 13 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 toml/version.hpp diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 635783a..8cc6573 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) BOOST_TEST(v.is_string()); BOOST_TEST(v.as_string() == "str"); } -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L { using namespace std::literals::string_view_literals; const value_type v("str"sv, {"comment1", "comment2"}); diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 238390c..aa44b7b 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -13,7 +13,7 @@ #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif #include @@ -477,7 +477,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_type BOOST_TEST("foo" == moved); } -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L { value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; BOOST_TEST("foo" == toml::find(v, "key")); diff --git a/tests/test_find_or.cpp b/tests/test_find_or.cpp index 72e5450..b0f786d 100644 --- a/tests/test_find_or.cpp +++ b/tests/test_find_or.cpp @@ -12,7 +12,7 @@ #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif diff --git a/tests/test_find_or_recursive.cpp b/tests/test_find_or_recursive.cpp index e4ff7ed..364112a 100644 --- a/tests/test_find_or_recursive.cpp +++ b/tests/test_find_or_recursive.cpp @@ -12,7 +12,7 @@ #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif diff --git a/tests/test_get.cpp b/tests/test_get.cpp index 9a795f2..a0dd315 100644 --- a/tests/test_get.cpp +++ b/tests/test_get.cpp @@ -12,7 +12,7 @@ #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif @@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types BOOST_TEST("foobar" == x); } -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L { value_type v("foo", toml::string_t::basic); BOOST_TEST("foo" == toml::get(v)); diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp index a709ae7..081b966 100644 --- a/tests/test_get_or.cpp +++ b/tests/test_get_or.cpp @@ -12,7 +12,7 @@ #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif diff --git a/tests/test_string.cpp b/tests/test_string.cpp index e03d412..444fc63 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(test_string_add_assign) str += str2; BOOST_TEST(str.str == "foobar"); } -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L // std::string_view { toml::string str("foo"); diff --git a/tests/test_value.cpp b/tests/test_value.cpp index 927decf..099d502 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -9,7 +9,7 @@ #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #include #endif @@ -423,7 +423,7 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_TEST(v2.as_boolean() == true); BOOST_TEST(v3.as_boolean() == true); -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L std::string_view sv = "foo"; toml::value v7(sv); diff --git a/toml.hpp b/toml.hpp index f34cfcc..16c0be1 100644 --- a/toml.hpp +++ b/toml.hpp @@ -25,14 +25,6 @@ #ifndef TOML_FOR_MODERN_CPP #define TOML_FOR_MODERN_CPP -#ifndef __cplusplus -# error "__cplusplus is not defined" -#endif - -#if __cplusplus < 201103L && _MSC_VER < 1900 -# error "toml11 requires C++11 or later." -#endif - #define TOML11_VERSION_MAJOR 3 #define TOML11_VERSION_MINOR 7 #define TOML11_VERSION_PATCH 0 diff --git a/toml/string.hpp b/toml/string.hpp index 5136d8c..def3e57 100644 --- a/toml/string.hpp +++ b/toml/string.hpp @@ -2,12 +2,15 @@ // Distributed under the MIT License. #ifndef TOML11_STRING_HPP #define TOML11_STRING_HPP + +#include "version.hpp" + #include #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #if __has_include() #define TOML11_USING_STRING_VIEW 1 #include diff --git a/toml/traits.hpp b/toml/traits.hpp index 5495c93..255d9e8 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -5,6 +5,7 @@ #include "from.hpp" #include "into.hpp" +#include "version.hpp" #include #include @@ -13,7 +14,7 @@ #include #include -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #if __has_include() #include #endif // has_include() @@ -146,7 +147,7 @@ struct has_specialized_into : decltype(has_specialized_into_impl::check(nullp // --------------------------------------------------------------------------- // C++17 and/or/not -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L using std::conjunction; using std::disjunction; @@ -208,7 +209,7 @@ template struct is_container : conjunction< negation>, // not a map negation>, // not a std::string -#if __cplusplus >= 201703L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L #if __has_include() negation>, // not a std::string_view #endif // has_include() @@ -233,7 +234,7 @@ struct is_basic_value<::toml::basic_value>: std::true_type{}; // --------------------------------------------------------------------------- // C++14 index_sequence -#if __cplusplus >= 201402L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L using std::index_sequence; using std::make_index_sequence; @@ -263,12 +264,12 @@ struct index_sequence_maker<0> template using make_index_sequence = typename index_sequence_maker::type; -#endif // __cplusplus >= 2014 +#endif // cplusplus >= 2014 // --------------------------------------------------------------------------- // C++14 enable_if_t -#if __cplusplus >= 201402L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L using std::enable_if_t; @@ -277,12 +278,12 @@ using std::enable_if_t; template using enable_if_t = typename std::enable_if::type; -#endif // __cplusplus >= 2014 +#endif // cplusplus >= 2014 // --------------------------------------------------------------------------- // return_type_of_t -#if __cplusplus >= 201703L && defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable>=201703 +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L && defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable>=201703 template using return_type_of_t = std::invoke_result_t; diff --git a/toml/utility.hpp b/toml/utility.hpp index 4a6b430..53a18b9 100644 --- a/toml/utility.hpp +++ b/toml/utility.hpp @@ -7,8 +7,9 @@ #include #include "traits.hpp" +#include "version.hpp" -#if __cplusplus >= 201402L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L # define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]] #elif defined(__GNUC__) # define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg))) @@ -21,7 +22,7 @@ namespace toml { -#if __cplusplus >= 201402L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L using std::make_unique; @@ -33,7 +34,7 @@ inline std::unique_ptr make_unique(Ts&& ... args) return std::unique_ptr(new T(std::forward(args)...)); } -#endif // __cplusplus >= 2014 +#endif // TOML11_CPLUSPLUS_STANDARD_VERSION >= 2014 namespace detail { @@ -91,7 +92,7 @@ T from_string(const std::string& str, T opt) namespace detail { -#if __cplusplus >= 201402L +#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L template decltype(auto) last_one(T&& tail) noexcept { diff --git a/toml/version.hpp b/toml/version.hpp new file mode 100644 index 0000000..1678010 --- /dev/null +++ b/toml/version.hpp @@ -0,0 +1,42 @@ +#ifndef TOML11_VERSION_HPP +#define TOML11_VERSION_HPP + +// This file checks C++ version. + +#ifndef __cplusplus +# error "__cplusplus is not defined" +#endif + +// Since MSVC does not define `__cplusplus` correctly unless you pass +// `/Zc:__cplusplus` when compiling, the workaround macros are added. +// Those enables you to define version manually or to use MSVC specific +// version macro automatically. +// +// The value of `__cplusplus` macro is defined in the C++ standard spec, but +// MSVC ignores the value, maybe because of backward compatibility. Instead, +// MSVC defines _MSVC_LANG that has the same value as __cplusplus defined in +// the C++ standard. First we check the manual version definition, and then +// we check if _MSVC_LANG is defined. If neither, use normal `__cplusplus`. +// +// FYI: https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-170 +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170 +// +#if defined(TOML11_ENFORCE_CXX11) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201103L +#elif defined(TOML11_ENFORCE_CXX14) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201402L +#elif defined(TOML11_ENFORCE_CXX17) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 201703L +#elif defined(TOML11_ENFORCE_CXX20) +# define TOML11_CPLUSPLUS_STANDARD_VERSION 202002L +#elif defined(_MSVC_LANG) +# define TOML11_CPLUSPLUS_STANDARD_VERSION _MSVC_LANG +#else +# define TOML11_CPLUSPLUS_STANDARD_VERSION __cplusplus +#endif + +#if TOML11_CPLUSPLUS_STANDARD_VERSION < 201103L +# error "toml11 requires C++11 or later." +#endif + +#endif// TOML11_VERSION_HPP