From ee9b30c7749fccac272f9e737930643fec46fcce Mon Sep 17 00:00:00 2001 From: Mark Gillard Date: Wed, 18 Mar 2020 15:28:00 +0200 Subject: [PATCH] fixed compilation on older implementations without std::launder also: - fixed `json_formatter` type deduction on older compilers - added build configuration option for compiling examples --- include/toml++/toml.h | 1 + include/toml++/toml_common.h | 9 ++ include/toml++/toml_default_formatter.h | 4 + include/toml++/toml_json_formatter.h | 10 +- include/toml++/toml_parser.h | 16 +-- include/toml++/toml_version.h | 4 +- meson.build | 139 ++++++++++++------------ meson_options.txt | 1 + tests/meson.build | 13 ++- toml.hpp | 46 +++++--- 10 files changed, 146 insertions(+), 97 deletions(-) diff --git a/include/toml++/toml.h b/include/toml++/toml.h index d1faebe..0232068 100644 --- a/include/toml++/toml.h +++ b/include/toml++/toml.h @@ -82,6 +82,7 @@ #undef TOML_IMPLEMENTATION #undef TOML_INLINE_FUNC_IMPL #undef TOML_COMPILER_EXCEPTIONS + #undef TOML_LAUNDER #endif /// \mainpage toml++ diff --git a/include/toml++/toml_common.h b/include/toml++/toml_common.h index a66cffb..80ccc40 100644 --- a/include/toml++/toml_common.h +++ b/include/toml++/toml_common.h @@ -318,6 +318,9 @@ TOML_PUSH_WARNINGS TOML_DISABLE_ALL_WARNINGS +#if __has_include() + #include +#endif #include #include //memcpy, memset #include @@ -350,6 +353,12 @@ TOML_POP_WARNINGS #define TOML_STRING_PREFIX(S) S #endif +#ifdef __cpp_lib_launder + #define TOML_LAUNDER(x) std::launder(x) +#else + #define TOML_LAUNDER(x) x +#endif + ////////// FORWARD DECLARATIONS & TYPEDEFS // clang-format on diff --git a/include/toml++/toml_default_formatter.h b/include/toml++/toml_default_formatter.h index de7e40c..54172c3 100644 --- a/include/toml++/toml_default_formatter.h +++ b/include/toml++/toml_default_formatter.h @@ -459,6 +459,10 @@ TOML_START friend std::basic_ostream& operator << (std::basic_ostream&, default_formatter&&) TOML_MAY_THROW; }; + default_formatter(const table&) -> default_formatter; + default_formatter(const array&) -> default_formatter; + template default_formatter(const value&) -> default_formatter; + template inline void default_formatter::print_inline(const toml::table& tbl) TOML_MAY_THROW { diff --git a/include/toml++/toml_json_formatter.h b/include/toml++/toml_json_formatter.h index 905a973..1a8a5e5 100644 --- a/include/toml++/toml_json_formatter.h +++ b/include/toml++/toml_json_formatter.h @@ -103,10 +103,8 @@ TOML_START /// \param source The source TOML object. /// \param flags Format option flags. TOML_NODISCARD_CTOR - explicit json_formatter( - const toml::node& source, - format_flags flags = format_flags::quote_dates_and_times) noexcept - : base{ source, flags } + explicit json_formatter(const toml::node& source, format_flags flags = {}) noexcept + : base{ source, flags | format_flags::quote_dates_and_times } {} template @@ -115,6 +113,10 @@ TOML_START friend std::basic_ostream& operator << (std::basic_ostream&, json_formatter&&) TOML_MAY_THROW; }; + json_formatter(const table&) -> json_formatter; + json_formatter(const array&) -> json_formatter; + template json_formatter(const value&) -> json_formatter; + template inline void json_formatter::print(const toml::table& tbl) TOML_MAY_THROW { diff --git a/include/toml++/toml_parser.h b/include/toml++/toml_parser.h index 1b0c30d..e61292a 100644 --- a/include/toml++/toml_parser.h +++ b/include/toml++/toml_parser.h @@ -52,9 +52,9 @@ TOML_START void destroy() noexcept { if (is_err) - std::launder(reinterpret_cast(&storage))->~parse_error(); + TOML_LAUNDER(reinterpret_cast(&storage))->~parse_error(); else - std::launder(reinterpret_cast(&storage))->~table(); + TOML_LAUNDER(reinterpret_cast(&storage))->~table(); } public: @@ -70,38 +70,38 @@ TOML_START [[nodiscard]] table& get() & noexcept { TOML_ASSERT(!is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } /// \brief Returns the internal toml::table (rvalue overload). [[nodiscard]] table&& get() && noexcept { TOML_ASSERT(!is_err); - return std::move(*std::launder(reinterpret_cast(&storage))); + return std::move(*TOML_LAUNDER(reinterpret_cast(&storage))); } /// \brief Returns the internal toml::table (const lvalue overload). [[nodiscard]] const table& get() const& noexcept { TOML_ASSERT(!is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } /// \brief Returns the internal toml::parse_error. [[nodiscard]] parse_error& error() & noexcept { TOML_ASSERT(is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } /// \brief Returns the internal toml::parse_error (rvalue overload). [[nodiscard]] parse_error&& error() && noexcept { TOML_ASSERT(is_err); - return std::move(*std::launder(reinterpret_cast(&storage))); + return std::move(*TOML_LAUNDER(reinterpret_cast(&storage))); } /// \brief Returns the internal toml::parse_error (const lvalue overload). [[nodiscard]] const parse_error& error() const& noexcept { TOML_ASSERT(is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } /// \brief Returns the internal toml::table. diff --git a/include/toml++/toml_version.h b/include/toml++/toml_version.h index 3075e46..eda9d43 100644 --- a/include/toml++/toml_version.h +++ b/include/toml++/toml_version.h @@ -5,8 +5,8 @@ #pragma once #define TOML_LIB_MAJOR 0 -#define TOML_LIB_MINOR 4 -#define TOML_LIB_PATCH 4 +#define TOML_LIB_MINOR 5 +#define TOML_LIB_PATCH 0 #define TOML_LANG_MAJOR 0 #define TOML_LANG_MINOR 5 diff --git a/meson.build b/meson.build index ee7cb78..4e50392 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'tomlplusplus', 'cpp', - version : '0.4.4', + version : '0.5.0', license : 'MIT', default_options : [ 'cpp_std=c++17', @@ -11,67 +11,6 @@ project( ] ) -compiler = meson.get_compiler('cpp') -message(['compiler ID: ', compiler.get_id()]) - -if compiler.get_id() == 'gcc' - add_project_arguments([ - '-g0', - '-fmax-errors=5', - '-Wno-init-list-lifetime' - ], - language : 'cpp' - ) -endif - -if compiler.get_id() == 'clang' - add_project_arguments([ - '-g0', - '-ferror-limit=5', - '-fchar8_t', - # '-Weverything', - '-Wno-c++98-compat', - '-Wno-c++98-compat-pedantic', - '-Wno-float-equal', - '-Wno-switch-enum', - '-Wno-documentation-unknown-command', - '-Wno-padded', - '-Wno-weak-vtables', - '-Wno-double-promotion' - #, '-ftime-trace' - ], - language : 'cpp' - ) -endif - -if compiler.get_id() == 'intel-cl' - add_project_arguments([ - '/Qoption,cpp,--unicode_source_kind,UTF-8', - '/std=c++latest', - '/wd82', # storage class is not first - '/wd280', # selector expression is constant (why the fuck is that a warning?) - '/wd411', # class provides no constructor (duh, it's an aggregate) - '/wd1011', # missing return statement (false negative) - '/wd1628', # function marked [[noreturn]] returns (false positive) - '/wd3280' # declaration hides member (triggered in Catch2) - ], - language : 'cpp' - ) -endif - -compiler_supports_char8_strings = compiler.compiles(''' - #include - #include - using namespace std::string_view_literals; - std::u8string func() - { - return std::u8string{ u8"this is a test."sv }; - } - ''', - name : 'char8 string check', - args : [ '-std=c++2a' ] -) - tomlplusplus_dep = declare_dependency( include_directories : include_directories('include'), version : meson.project_version(), @@ -84,11 +23,77 @@ else build_tests = get_option('BUILD_TESTS').enabled() endif -if build_tests - inc = include_directories('include', 'extern') - subdir('tests') +build_examples = false +if get_option('BUILD_EXAMPLES').auto() + build_examples = (not meson.is_subproject()) else - message('Not building tests') + build_examples = get_option('BUILD_EXAMPLES').enabled() +endif + +if build_tests or build_examples + + compiler = meson.get_compiler('cpp') + message(['compiler ID: ', compiler.get_id()]) + message(['compiler version: ', compiler.version()]) + + if compiler.get_id() == 'gcc' + add_project_arguments([ + '-g0', + '-fmax-errors=5', + '-Wno-init-list-lifetime' + ], + language : 'cpp' + ) + endif + + if compiler.get_id() == 'clang' + add_project_arguments([ + '-g0', + '-ferror-limit=5', + '-fchar8_t', + # '-Weverything', + '-Wno-c++98-compat', + '-Wno-c++98-compat-pedantic', + '-Wno-float-equal', + '-Wno-switch-enum', + '-Wno-documentation-unknown-command', + '-Wno-padded', + '-Wno-weak-vtables', + '-Wno-double-promotion' + #, '-ftime-trace' + ], + language : 'cpp' + ) + endif + + if compiler.get_id() == 'intel-cl' + add_project_arguments([ + '/Qoption,cpp,--unicode_source_kind,UTF-8', + '/std=c++latest', + '/wd82', # storage class is not first + '/wd280', # selector expression is constant (why the fuck is that a warning?) + '/wd411', # class provides no constructor (duh, it's an aggregate) + '/wd1011', # missing return statement (false negative) + '/wd1628', # function marked [[noreturn]] returns (false positive) + '/wd3280' # declaration hides member (triggered in Catch2) + ], + language : 'cpp' + ) + endif + + inc = include_directories('include', 'extern') + + if build_tests + subdir('tests') + else + message('Not building tests') + endif + + if build_examples + subdir('examples') + else + message('Not building examples') + endif + endif -# subdir('examples') diff --git a/meson_options.txt b/meson_options.txt index c3f08fc..1a266e5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,2 @@ option('BUILD_TESTS', type : 'feature', value : 'auto', description : 'Whether to build tests (defaults to auto: only if not a subproject)') +option('BUILD_EXAMPLES', type : 'feature', value : 'auto', description : 'Whether to build examples (defaults to auto: only if not a subproject)') diff --git a/tests/meson.build b/tests/meson.build index cae25a9..30f953c 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -21,7 +21,18 @@ toml_char8_strings = '-DTOML_CHAR_8_STRINGS=1' manually_set_cpp_std = 'cpp_std=none' cpp20 = '-std=c++2a' use_tloptional = '-DTARTANLLAMA_OPTIONAL' - +compiler_supports_char8_strings = compiler.compiles(''' + #include + #include + using namespace std::string_view_literals; + std::u8string func() + { + return std::u8string{ u8"this is a test."sv }; + } + ''', + name : 'char8 string check', + args : [ '-std=c++2a' ] +) ############################################################################ ### char diff --git a/toml.hpp b/toml.hpp index 319d55d..5857d86 100644 --- a/toml.hpp +++ b/toml.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------------------------------------------------- // -// toml++ v0.4.4 +// toml++ v0.5.0 // https://github.com/marzer/tomlplusplus // SPDX-License-Identifier: MIT // @@ -298,8 +298,8 @@ #endif #define TOML_LIB_MAJOR 0 -#define TOML_LIB_MINOR 4 -#define TOML_LIB_PATCH 4 +#define TOML_LIB_MINOR 5 +#define TOML_LIB_PATCH 0 #define TOML_LANG_MAJOR 0 #define TOML_LANG_MINOR 5 @@ -363,6 +363,9 @@ TOML_PUSH_WARNINGS TOML_DISABLE_ALL_WARNINGS +#if __has_include() + #include +#endif #include #include //memcpy, memset #include @@ -395,6 +398,12 @@ TOML_POP_WARNINGS #define TOML_STRING_PREFIX(S) S #endif +#ifdef __cpp_lib_launder + #define TOML_LAUNDER(x) std::launder(x) +#else + #define TOML_LAUNDER(x) x +#endif + namespace toml { } TOML_START @@ -4721,9 +4730,9 @@ TOML_START void destroy() noexcept { if (is_err) - std::launder(reinterpret_cast(&storage))->~parse_error(); + TOML_LAUNDER(reinterpret_cast(&storage))->~parse_error(); else - std::launder(reinterpret_cast(&storage))->~table(); + TOML_LAUNDER(reinterpret_cast(&storage))->~table(); } public: @@ -4734,33 +4743,33 @@ TOML_START [[nodiscard]] table& get() & noexcept { TOML_ASSERT(!is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } [[nodiscard]] table&& get() && noexcept { TOML_ASSERT(!is_err); - return std::move(*std::launder(reinterpret_cast(&storage))); + return std::move(*TOML_LAUNDER(reinterpret_cast(&storage))); } [[nodiscard]] const table& get() const& noexcept { TOML_ASSERT(!is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } [[nodiscard]] parse_error& error() & noexcept { TOML_ASSERT(is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } [[nodiscard]] parse_error&& error() && noexcept { TOML_ASSERT(is_err); - return std::move(*std::launder(reinterpret_cast(&storage))); + return std::move(*TOML_LAUNDER(reinterpret_cast(&storage))); } [[nodiscard]] const parse_error& error() const& noexcept { TOML_ASSERT(is_err); - return *std::launder(reinterpret_cast(&storage)); + return *TOML_LAUNDER(reinterpret_cast(&storage)); } [[nodiscard]] operator table& () noexcept { return get(); } @@ -5495,6 +5504,10 @@ TOML_START friend std::basic_ostream& operator << (std::basic_ostream&, default_formatter&&) TOML_MAY_THROW; }; + default_formatter(const table&) -> default_formatter; + default_formatter(const array&) -> default_formatter; + template default_formatter(const value&) -> default_formatter; + template inline void default_formatter::print_inline(const toml::table& tbl) TOML_MAY_THROW { @@ -5626,10 +5639,8 @@ TOML_START public: TOML_NODISCARD_CTOR - explicit json_formatter( - const toml::node& source, - format_flags flags = format_flags::quote_dates_and_times) noexcept - : base{ source, flags } + explicit json_formatter(const toml::node& source, format_flags flags = {}) noexcept + : base{ source, flags | format_flags::quote_dates_and_times } {} template @@ -5638,6 +5649,10 @@ TOML_START friend std::basic_ostream& operator << (std::basic_ostream&, json_formatter&&) TOML_MAY_THROW; }; + json_formatter(const table&) -> json_formatter; + json_formatter(const array&) -> json_formatter; + template json_formatter(const value&) -> json_formatter; + template inline void json_formatter::print(const toml::table& tbl) TOML_MAY_THROW { @@ -9188,6 +9203,7 @@ TOML_END #undef TOML_IMPLEMENTATION #undef TOML_INLINE_FUNC_IMPL #undef TOML_COMPILER_EXCEPTIONS + #undef TOML_LAUNDER #endif #ifdef __GNUC__