diff --git a/.clang-format b/.clang-format index 77d3b077..83ae0ab8 100644 --- a/.clang-format +++ b/.clang-format @@ -24,11 +24,12 @@ AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes AttributeMacros: - - TOML_ABSTRACT_BASE + - TOML_ABSTRACT_INTERFACE - TOML_CALLCONV - TOML_CLOSED_ENUM - TOML_CLOSED_FLAGS_ENUM - TOML_EMPTY_BASES + - TOML_EXPORTED_CLASS - TOML_FLAGS_ENUM - TOML_LIKELY_CASE - TOML_OPEN_ENUM @@ -132,7 +133,6 @@ PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 1000000 PenaltyIndentedWhitespace: 0 PointerAlignment: Left -ReferenceAlignment: Left ReflowComments: true SortIncludes: false SortJavaStaticImport: Before @@ -161,6 +161,8 @@ SpaceBeforeSquareBrackets: false BitFieldColonSpacing: Both Standard: Latest StatementMacros: + - __pragma + - _Pragma - TOML_ALWAYS_INLINE - TOML_API - TOML_ATTR @@ -177,6 +179,13 @@ StatementMacros: - TOML_NEVER_INLINE - TOML_NODISCARD - TOML_NODISCARD_CTOR + - TOML_PRAGMA_CLANG + - TOML_PRAGMA_CLANG_GE_9 + - TOML_PRAGMA_CLANG_GE_10 + - TOML_PRAGMA_CLANG_GE_11 + - TOML_PRAGMA_GCC + - TOML_PRAGMA_MSVC + - TOML_PRAGMA_ICC - TOML_PURE_GETTER - TOML_PURE_INLINE_GETTER - TOML_RETURNS_BY_THROWING @@ -190,13 +199,16 @@ WhitespaceSensitiveMacros: - BOOST_PP_STRINGIZE - TOML_ATTR - TOML_CONCAT + - TOML_HAS_INCLUDE - TOML_LIKELY - - TOML_MAKE_RAW_STRING - TOML_MAKE_STRING - - TOML_MAKE_STRING_VIEW - TOML_PRAGMA_CLANG + - TOML_PRAGMA_CLANG_GE_9 + - TOML_PRAGMA_CLANG_GE_10 + - TOML_PRAGMA_CLANG_GE_11 - TOML_PRAGMA_GCC - TOML_PRAGMA_MSVC + - TOML_PRAGMA_ICC - TOML_UNLIKELY ... diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e26788b3..25842c05 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -29,6 +29,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + clang_version: '14' + gcc_version: '11' + jobs: linux: strategy: @@ -48,22 +52,56 @@ jobs: runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: - - name: Install dependencies + - name: Install base dependencies run: | sudo apt -y update - if [ ${{ matrix.compiler }} = clang++ ]; then compiler=clang; else compiler=${{ matrix.compiler }}; fi - sudo apt -y install --no-install-recommends $compiler ${{ matrix.linker }} pkgconf git ca-certificates locales-all python3 python3-pip python3-setuptools python3-wheel ninja-build - sudo pip3 install --upgrade meson + sudo apt -y install --no-install-recommends ${{ matrix.linker }} git python3 python3-pip ninja-build locales-all + sudo -H pip3 install --no-cache-dir --upgrade meson - uses: actions/checkout@v3 - name: Check toml.hpp run: | - sudo pip3 install --upgrade --requirement tools/requirements.txt cd tools + sudo -H pip3 install --upgrade --requirement ./requirements.txt python3 ci_single_header_check.py + - name: Update LLVM package repository + if: ${{ startsWith(matrix.compiler, 'clang') || startsWith(matrix.linker, 'lld') }} + run: | + sudo apt -y install --no-install-recommends software-properties-common wget + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + codename=$(lsb_release -sc) + sudo add-apt-repository --yes --no-update "deb http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-${{ env.clang_version }} main" + sudo apt -y update + + - name: Install clang + if: ${{ startsWith(matrix.compiler, 'clang') }} + run: | + sudo apt -y install --no-install-recommends clang-${{ env.clang_version }} + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${{ env.clang_version }} 1000 + + - name: Install g++ + if: ${{ startsWith(matrix.compiler, 'g++') }} + run: | + sudo apt -y install --no-install-recommends g++-${{ env.gcc_version }} + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${{ env.gcc_version }} 1000 + + - name: Install lld + if: ${{ startsWith(matrix.linker, 'lld') }} + run: | + sudo apt -y install --no-install-recommends lld-${{ env.clang_version }} + sudo update-alternatives --install /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-${{ env.clang_version }} 1000 + + - name: Configure locales + run: | + sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8' + - name: Configure Meson run: | CXX=${{ matrix.compiler }} CXX_LD=${{ matrix.linker }} meson setup build --buildtype=${{ matrix.type }} -Dcompile_library=${{ matrix.compile_library }} -Dpedantic=true -Dbuild_tests=true -Dbuild_examples=true -Dgenerate_cmake_config=false -Db_lto=false -Dubsan_examples=true -Dasan_examples=true @@ -97,7 +135,7 @@ jobs: python3 -m pip install -U pip==21.3.1 pip3 install meson ninja - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ilammy/msvc-dev-cmd@v1 @@ -114,13 +152,14 @@ jobs: tipi-build-linux: name: tipi.build project build and dependency resolution runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' container: tipibuild/tipi-ubuntu env: HOME: /root steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: mkdir -p ~/.tipi # checking if the tomlplusplus project builds and passes tests diff --git a/cpp.hint b/cpp.hint index bd358c14..7dcca90c 100644 --- a/cpp.hint +++ b/cpp.hint @@ -1,6 +1,6 @@ #define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true) #define TOML_ABI_NAMESPACE_END static_assert(true) -#define TOML_ABSTRACT_BASE +#define TOML_ABSTRACT_INTERFACE #define TOML_ALWAYS_INLINE inline #define TOML_ANON_NAMESPACE_END static_assert(true) #define TOML_ANON_NAMESPACE_START namespace diff --git a/docs/poxy.toml b/docs/poxy.toml index 2fcf89f9..68de648e 100644 --- a/docs/poxy.toml +++ b/docs/poxy.toml @@ -86,6 +86,7 @@ string_literals = [ '_toml' ] '(?:toml::)?node[_ ]views?' = 'classtoml_1_1node__view.html' '(?:toml::)?parse[_ ]errors?' = 'classtoml_1_1parse__error.html' '(?:toml::)?parse[_ ]results?' = 'classtoml_1_1parse__result.html' +'(?:toml::)?path[_ ]components?' = 'classtoml_1_1path__component.html' '(?:toml::)?source[_ ]positions?' = 'structtoml_1_1source__position.html' '(?:toml::)?source[_ ]regions?' = 'structtoml_1_1source__region.html' '(?:toml::)?time[_ ]offsets?' = 'structtoml_1_1time__offset.html' diff --git a/include/toml++/impl/array.inl b/include/toml++/impl/array.inl index a401930d..a8a4ac1e 100644 --- a/include/toml++/impl/array.inl +++ b/include/toml++/impl/array.inl @@ -139,6 +139,7 @@ TOML_NAMESPACE_START return elems_.insert(pos, std::move(elem)); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype) const noexcept { @@ -155,6 +156,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept { @@ -176,6 +178,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept { @@ -188,7 +191,7 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node& array::at(size_t index) { -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS return *elems_.at(index); diff --git a/include/toml++/impl/json_formatter.h b/include/toml++/impl/json_formatter.h index 4c7980bc..f070194c 100644 --- a/include/toml++/impl/json_formatter.h +++ b/include/toml++/impl/json_formatter.h @@ -87,7 +87,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) /// \brief Constructs a JSON formatter and binds it to a toml::parse_result. /// diff --git a/include/toml++/impl/key.h b/include/toml++/impl/key.h index da407980..d94d7e8d 100644 --- a/include/toml++/impl/key.h +++ b/include/toml++/impl/key.h @@ -290,10 +290,10 @@ TOML_NAMESPACE_START /// \name Iteration /// @{ - /// A const iterator for iterating over the characters in the key. + /// \brief A const iterator for iterating over the characters in the key. using const_iterator = const char*; - /// A const iterator for iterating over the characters in the key. + /// \brief A const iterator for iterating over the characters in the key. using iterator = const_iterator; /// \brief Returns an iterator to the first character in the key's backing string. diff --git a/include/toml++/impl/node.h b/include/toml++/impl/node.h index bf4d64bd..777418fc 100644 --- a/include/toml++/impl/node.h +++ b/include/toml++/impl/node.h @@ -15,7 +15,7 @@ TOML_NAMESPACE_START /// /// \detail A parsed TOML document forms a tree made up of tables, arrays and values. /// This type is the base of each of those, providing a lot of the polymorphic plumbing. - class TOML_ABSTRACT_BASE TOML_EXPORTED_CLASS node + class TOML_ABSTRACT_INTERFACE TOML_EXPORTED_CLASS node { private: /// \cond diff --git a/include/toml++/impl/node.inl b/include/toml++/impl/node.inl index 72ab33bf..e97356a7 100644 --- a/include/toml++/impl/node.inl +++ b/include/toml++/impl/node.inl @@ -115,6 +115,7 @@ TOML_NAMESPACE_END; TOML_IMPL_NAMESPACE_START { + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV node_deep_equality(const node* lhs, const node* rhs) noexcept { diff --git a/include/toml++/impl/parse_error.h b/include/toml++/impl/parse_error.h index 27f8ee95..0a6041e7 100644 --- a/include/toml++/impl/parse_error.h +++ b/include/toml++/impl/parse_error.h @@ -12,7 +12,7 @@ #include "print_to_stream.h" #include "header_start.h" -#if defined(DOXYGEN) || !TOML_EXCEPTIONS +#if TOML_DOXYGEN || !TOML_EXCEPTIONS #define TOML_PARSE_ERROR_BASE #else #define TOML_PARSE_ERROR_BASE : public std::runtime_error diff --git a/include/toml++/impl/parse_result.h b/include/toml++/impl/parse_result.h index de1e53ab..ceaa6e17 100644 --- a/include/toml++/impl/parse_result.h +++ b/include/toml++/impl/parse_result.h @@ -5,7 +5,7 @@ #pragma once #include "preprocessor.h" -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) #include "table.h" #include "parse_error.h" @@ -170,6 +170,8 @@ TOML_NAMESPACE_START /// @} /// \name Successful parses + /// \warning It is undefined behaviour to call these functions when the result respresents a failed parse. + /// Check #failed(), #succeeded or #operator bool() to determine the result's state. /// @{ /// \brief Returns the internal toml::table. @@ -220,6 +222,8 @@ TOML_NAMESPACE_START /// @} /// \name Failed parses + /// \warning It is undefined behaviour to call these functions when the result respresents a successful parse. + /// Check #failed(), #succeeded or #operator bool() to determine the result's state. /// @{ /// \brief Returns the internal toml::parse_error. diff --git a/include/toml++/impl/parser.inl b/include/toml++/impl/parser.inl index 5bb5e700..be4d4966 100644 --- a/include/toml++/impl/parser.inl +++ b/include/toml++/impl/parser.inl @@ -112,7 +112,7 @@ TOML_ANON_NAMESPACE_START public: TOML_NODISCARD_CTOR - explicit utf8_byte_stream(std::istream& stream) noexcept(!TOML_COMPILER_EXCEPTIONS) // + explicit utf8_byte_stream(std::istream& stream) noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) // : source_{ &stream } { if (!*this) // eof, bad @@ -147,14 +147,14 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { return eof() || source_->peek() == std::istream::traits_type::eof(); } TOML_NODISCARD TOML_ATTR(nonnull) - size_t operator()(void* dest, size_t num) noexcept(!TOML_COMPILER_EXCEPTIONS) + size_t operator()(void* dest, size_t num) noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { TOML_ASSERT(*this); @@ -185,16 +185,16 @@ TOML_ANON_NAMESPACE_START static_assert(std::is_trivial_v); static_assert(std::is_standard_layout_v); - struct TOML_ABSTRACT_BASE utf8_reader_interface + struct TOML_ABSTRACT_INTERFACE utf8_reader_interface { TOML_NODISCARD virtual const source_path_ptr& source_path() const noexcept = 0; TOML_NODISCARD - virtual const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) = 0; + virtual const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) = 0; TOML_NODISCARD - virtual bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) = 0; + virtual bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) = 0; #if !TOML_EXCEPTIONS @@ -257,7 +257,7 @@ TOML_ANON_NAMESPACE_START optional err_; #endif - bool read_next_block() noexcept(!TOML_COMPILER_EXCEPTIONS) + bool read_next_block() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { TOML_ASSERT(stream_); @@ -435,7 +435,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) final + const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final { utf8_reader_error_check({}); @@ -454,7 +454,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) final + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final { return stream_.peek_eof(); } @@ -521,7 +521,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) + const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { utf8_buffered_reader_error_check({}); @@ -575,7 +575,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { return reader_.peek_eof(); } @@ -2622,7 +2622,7 @@ TOML_IMPL_NAMESPACE_START char32_t chars[utf8_buffered_reader::max_history_length]; size_t char_count = {}, advance_count = {}; bool eof_while_scanning = false; - const auto scan = [&]() noexcept(!TOML_COMPILER_EXCEPTIONS) + const auto scan = [&]() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { if (is_eof()) return; diff --git a/include/toml++/impl/path.h b/include/toml++/impl/path.h index 32dac309..a0e3113e 100644 --- a/include/toml++/impl/path.h +++ b/include/toml++/impl/path.h @@ -38,8 +38,7 @@ TOML_NAMESPACE_START static bool TOML_CALLCONV equal(const path_component&, const path_component&) noexcept; template - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER static Type* get_as(storage_t& s) noexcept { return TOML_LAUNDER(reinterpret_cast(s.bytes)); @@ -50,7 +49,7 @@ TOML_NAMESPACE_START ::new (static_cast(storage_.bytes)) std::string{ key }; } - static void store_index(size_t index, storage_t& storage_) + static void store_index(size_t index, storage_t& storage_) noexcept { ::new (static_cast(storage_.bytes)) std::size_t{ index }; } @@ -62,28 +61,20 @@ TOML_NAMESPACE_START } TOML_NODISCARD - size_t& index() & noexcept + size_t& index_ref() noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::array_index); return *get_as(value_storage_); } TOML_NODISCARD - std::string& key() & noexcept + std::string& key_ref() noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::key); return *get_as(value_storage_); } - - /// \brief Returns the key string (const rvalue overload). - TOML_NODISCARD - std::string&& key() && noexcept - { - TOML_ASSERT_ASSUME(type_ == path_component_type::key); - return static_cast(*get_as(value_storage_)); - } - /// \endcond + public: /// \brief Default constructor (creates an empty key). TOML_NODISCARD_CTOR @@ -102,7 +93,9 @@ TOML_NAMESPACE_START #if TOML_ENABLE_WINDOWS_COMPAT - /// \brief Constructor for a path component that is a key specified witha wide-char string + /// \brief Constructor for a path component that is a key string + /// + /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION path_component(std::wstring_view key); @@ -121,11 +114,29 @@ TOML_NAMESPACE_START /// \brief Copy-assignment operator. TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(const path_component & rhs); + path_component& operator=(const path_component& rhs); /// \brief Move-assignment operator. TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(path_component && rhs) noexcept; + path_component& operator=(path_component&& rhs) noexcept; + + /// \brief Assigns an array index to this path component. + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(size_t new_index) noexcept; + + /// \brief Assigns a path key to this path component. + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(std::string_view new_key); + +#if TOML_ENABLE_WINDOWS_COMPAT + + /// \brief Assigns a path key to this path component. + /// + /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled. + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(std::wstring_view new_key); + +#endif /// \brief Destructor. ~path_component() noexcept @@ -133,61 +144,43 @@ TOML_NAMESPACE_START destroy(); } - /// \name Array index accessors and casts + /// \name Array index accessors + /// \warning It is undefined behaviour to call these functions when the path component does not represent an array index. + /// Check #type() to determine the component's value type. /// @{ /// \brief Returns the array index (const lvalue overload). - TOML_NODISCARD - const size_t& index() const& noexcept + TOML_PURE_GETTER + size_t index() const noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::array_index); return *get_as(value_storage_); } /// \brief Returns the array index (const lvalue). - TOML_NODISCARD - /* implicit */ operator const size_t&() const noexcept + TOML_PURE_INLINE_GETTER + explicit operator size_t() const noexcept { return index(); } /// @} - /// \name Key accessors and casts + /// \name Key accessors + /// \warning It is undefined behaviour to call these functions when the path component does not represent a key. + /// Check #type() to determine the component's value type. /// @{ - /// \brief Returns the key string (const lvalue overload). - TOML_NODISCARD - const std::string& key() const& noexcept + /// \brief Returns the key string. + TOML_PURE_GETTER + const std::string& key() const noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::key); return *get_as(value_storage_); } - /// \brief Returns the key string (const rvalue overload). - TOML_NODISCARD - const std::string&& key() const&& noexcept - { - TOML_ASSERT_ASSUME(type_ == path_component_type::key); - return static_cast(*get_as(value_storage_)); - } - /// \brief Returns the key string. - TOML_NODISCARD - explicit operator const std::string&() noexcept - { - return key(); - } - - /// \brief Returns the key string (rvalue overload). - TOML_NODISCARD - explicit operator const std::string&&() noexcept - { - return std::move(key()); - } - - /// \brief Returns the key string (const lvalue overload). - TOML_NODISCARD + TOML_PURE_INLINE_GETTER explicit operator const std::string&() const noexcept { return key(); @@ -202,6 +195,9 @@ TOML_NAMESPACE_START return type_; } + /// \name Equality + /// @{ + /// \brief Returns true if two path components represent the same key or array index. TOML_PURE_INLINE_GETTER friend bool operator==(const path_component& lhs, const path_component& rhs) noexcept @@ -216,22 +212,7 @@ TOML_NAMESPACE_START return !equal(lhs, rhs); } - /// \brief Assigns an array index to this path component. Index must castable to size_t - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(size_t new_index) noexcept; - - /// \brief Assigns a path key to this path component. Key must be a string type - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(std::string_view new_key); - -#if TOML_ENABLE_WINDOWS_COMPAT - - /// \brief Assigns a path key to this path component using window wide char strings. Key must be a wide char string type - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(std::wstring_view new_key); - -#endif - + /// @} }; /// \brief A TOML path. @@ -322,17 +303,19 @@ TOML_NAMESPACE_START return components_.empty(); } - /// \brief Fetch a path component by index for modification + /// \brief Fetch a path component by index. TOML_PURE_INLINE_GETTER path_component& operator[](size_t index) noexcept { + TOML_ASSERT(index < size()); return components_[index]; } - /// \brief Fetch a path component by index + /// \brief Fetch a path component by index (const overload). TOML_PURE_INLINE_GETTER const path_component& operator[](size_t index) const noexcept { + TOML_ASSERT(index < size()); return components_[index]; } @@ -592,16 +575,14 @@ TOML_NAMESPACE_START /// @{ /// \brief Returns whether two paths are the same. - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER friend bool operator==(const path& lhs, const path& rhs) noexcept { return equal(lhs, rhs); } /// \brief Returns whether two paths are not the same. - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER friend bool operator!=(const path& lhs, const path& rhs) noexcept { return !equal(lhs, rhs); @@ -685,24 +666,74 @@ TOML_NAMESPACE_START /// @} - /// \brief Erases the contents of the path - TOML_EXPORTED_MEMBER_FUNCTION - void clear() noexcept; + /// \name Iteration + /// @{ - /// \brief Iterator at the start of the vector of path components (see #toml::path_component) - TOML_NODISCARD - auto begin() const noexcept + /// An iterator for iterating over the components in the path. + /// \see #toml::path_component + using iterator = std::vector::iterator; + + /// A const iterator for iterating over the components in the path. + /// \see #toml::path_component + using const_iterator = std::vector::const_iterator; + + /// \brief Returns an iterator to the first component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + iterator begin() noexcept { return components_.begin(); } - /// \brief Iterator at the end of the vector of path components (see #toml::path_component) - TOML_NODISCARD - auto end() const noexcept + /// \brief Returns an iterator to one-past-the-last component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + iterator end() noexcept + { + return components_.end(); + } + + /// \brief Returns a const iterator to the first component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + const_iterator begin() const noexcept + { + return components_.begin(); + } + + /// \brief Returns a const iterator to one-past-the-last component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + const_iterator end() const noexcept + { + return components_.end(); + } + + /// \brief Returns a const iterator to the first component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + const_iterator cbegin() const noexcept + { + return components_.begin(); + } + + /// \brief Returns a const iterator to one-past-the-last component in the path. + /// \see #toml::path_component + TOML_PURE_INLINE_GETTER + const_iterator cend() const noexcept { return components_.end(); } + /// @} + + /// \name Subpaths and Truncation + /// @{ + + /// \brief Erases the contents of the path. + TOML_EXPORTED_MEMBER_FUNCTION + void clear() noexcept; + /// \brief Removes the number of terminal path components specified by n TOML_EXPORTED_MEMBER_FUNCTION path& truncate(size_t n); @@ -726,14 +757,15 @@ TOML_NAMESPACE_START /// range of path components from [start, end). TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION - path subpath(std::vector::const_iterator start, - std::vector::const_iterator end) const; + path subpath(const_iterator start, const_iterator end) const; /// \brief Returns a toml::path object that is a specified subpath of the current path, representing the /// range of path components with indexes from [start, start + length]. TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION path subpath(size_t start, size_t length) const; + + /// @} }; inline namespace literals diff --git a/include/toml++/impl/path.inl b/include/toml++/impl/path.inl index 00845fea..9ae4d3b0 100644 --- a/include/toml++/impl/path.inl +++ b/include/toml++/impl/path.inl @@ -54,12 +54,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE path_component::path_component(std::wstring_view key) // : path_component(impl::narrow(key)) - { } + {} -#endif +#endif TOML_EXTERNAL_LINKAGE - path_component::path_component(const path_component & pc) // + path_component::path_component(const path_component& pc) // : type_{ pc.type_ } { if (type_ == path_component_type::array_index) @@ -73,9 +73,9 @@ TOML_NAMESPACE_START : type_{ pc.type_ } { if (type_ == path_component_type::array_index) - store_index(pc.index(), value_storage_); + store_index(pc.index_ref(), value_storage_); else - store_key(std::move(pc).key(), value_storage_); + store_key(std::move(pc.key_ref()), value_storage_); } TOML_EXTERNAL_LINKAGE @@ -94,9 +94,9 @@ TOML_NAMESPACE_START else { if (type_ == path_component_type::array_index) - index() = rhs.index(); + index_ref() = rhs.index(); else - key() = rhs.key(); + key_ref() = rhs.key(); } return *this; } @@ -110,20 +110,21 @@ TOML_NAMESPACE_START type_ = rhs.type_; if (type_ == path_component_type::array_index) - store_index(std::move(rhs).index(), value_storage_); + store_index(rhs.index(), value_storage_); else - store_key(std::move(rhs).key(), value_storage_); + store_key(std::move(rhs.key_ref()), value_storage_); } else { if (type_ == path_component_type::array_index) - index() = std::move(rhs).index(); + index_ref() = rhs.index(); else - key() = std::move(rhs).key(); + key_ref() = std::move(rhs.key_ref()); } return *this; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV path_component::equal(const path_component& lhs, const path_component& rhs) noexcept { @@ -138,7 +139,7 @@ TOML_NAMESPACE_START } TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (size_t new_index) noexcept + path_component& path_component::operator=(size_t new_index) noexcept { // If currently a key, string will need to be destroyed regardless destroy(); @@ -150,26 +151,26 @@ TOML_NAMESPACE_START } TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (std::string_view new_key) + path_component& path_component::operator=(std::string_view new_key) { if (type_ == path_component_type::key) - key() = new_key; + key_ref() = new_key; else { type_ = path_component_type::key; store_key(new_key, value_storage_); } - + return *this; } #if TOML_ENABLE_WINDOWS_COMPAT TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (std::wstring_view new_key) + path_component& path_component::operator=(std::wstring_view new_key) { if (type_ == path_component_type::key) - key() = impl::narrow(new_key); + key_ref() = impl::narrow(new_key); else { type_ = path_component_type::key; @@ -180,7 +181,6 @@ TOML_NAMESPACE_START } #endif - } TOML_NAMESPACE_END; @@ -246,6 +246,7 @@ TOML_NAMESPACE_START } } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV path::equal(const path& lhs, const path& rhs) noexcept { diff --git a/include/toml++/impl/preprocessor.h b/include/toml++/impl/preprocessor.h index 819345a3..ec46c3e2 100644 --- a/include/toml++/impl/preprocessor.h +++ b/include/toml++/impl/preprocessor.h @@ -2,833 +2,1018 @@ //# Copyright (c) Mark Gillard //# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // SPDX-License-Identifier: MIT +#pragma once -// clang-format off +//#===================================================================================================================== +//# C++ VERSION +//#===================================================================================================================== -#pragma once #ifndef __cplusplus - #error toml++ is a C++ library. +#error toml++ is a C++ library. #endif - -//#==================================================================================================================== -//# COMPILER DETECTION -//#==================================================================================================================== - -#ifdef __INTELLISENSE__ - #define TOML_INTELLISENSE 1 +#ifdef _MSVC_LANG +#define TOML_CPP _MSVC_LANG +#else +#define TOML_CPP __cplusplus +#endif +#if TOML_CPP >= 202002L +#undef TOML_CPP +#define TOML_CPP 20 +#elif TOML_CPP >= 201703L +#undef TOML_CPP +#define TOML_CPP 17 #else - #define TOML_INTELLISENSE 0 +#if TOML_CPP < 201103L +#error toml++ requires C++17 or higher. For a pre-C++11 TOML library see https://github.com/ToruNiina/Boost.toml +#elif TOML_CPP < 201703L +#error toml++ requires C++17 or higher. For a C++11 TOML library see https://github.com/ToruNiina/toml11 #endif +#endif + +//#===================================================================================================================== +//# COMPILER/OS/ARCH DETECTION +//#===================================================================================================================== + #ifdef __clang__ - #define TOML_CLANG __clang_major__ +#define TOML_CLANG __clang_major__ #else - #define TOML_CLANG 0 +#define TOML_CLANG 0 #endif #ifdef __INTEL_COMPILER - #define TOML_ICC __INTEL_COMPILER - #ifdef __ICL - #define TOML_ICC_CL TOML_ICC - #else - #define TOML_ICC_CL 0 - #endif +#define TOML_ICC __INTEL_COMPILER +#ifdef __ICL +#define TOML_ICC_CL TOML_ICC +#else +#define TOML_ICC_CL 0 +#endif #else - #define TOML_ICC 0 - #define TOML_ICC_CL 0 +#define TOML_ICC 0 +#define TOML_ICC_CL 0 #endif #if defined(_MSC_VER) && !TOML_CLANG && !TOML_ICC - #define TOML_MSVC _MSC_VER +#define TOML_MSVC _MSC_VER #else - #define TOML_MSVC 0 +#define TOML_MSVC 0 #endif #if defined(__GNUC__) && !TOML_CLANG && !TOML_ICC - #define TOML_GCC __GNUC__ +#define TOML_GCC __GNUC__ +#else +#define TOML_GCC 0 +#endif +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) +#define TOML_WINDOWS 1 #else - #define TOML_GCC 0 +#define TOML_WINDOWS 0 #endif +#if defined(DOXYGEN) || defined(__DOXYGEN__) || defined(__POXY__) || defined(__poxy__) +#define TOML_DOXYGEN 1 +#else +#define TOML_DOXYGEN 0 +#endif +#ifdef __INTELLISENSE__ +#define TOML_INTELLISENSE 1 +#else +#define TOML_INTELLISENSE 0 +#endif +#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ + || defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) +#define TOML_ARM 1 +#else +#define TOML_ARM 0 +#endif + +//#===================================================================================================================== +//# ATTRIBUTES / FEATURE DETECTION / UTILITY MACROS +//#===================================================================================================================== +// TOML_HAS_INCLUDE #ifdef __has_include - #define TOML_HAS_INCLUDE(header) __has_include(header) +#define TOML_HAS_INCLUDE(header) __has_include(header) #else - #define TOML_HAS_INCLUDE(header) 0 +#define TOML_HAS_INCLUDE(header) 0 #endif -//#==================================================================================================================== -//# CLANG -//#==================================================================================================================== +#ifdef __has_builtin +#define TOML_HAS_BUILTIN(name) __has_builtin(name) +#else +#define TOML_HAS_BUILTIN(name) 0 +#endif + +// TOML_HAS_FEATURE +#ifdef __has_feature +#define TOML_HAS_FEATURE(name) __has_feature(name) +#else +#define TOML_HAS_FEATURE(name) 0 +#endif + +// TOML_HAS_ATTR +#ifdef __has_attribute +#define TOML_HAS_ATTR(attr) __has_attribute(attr) +#else +#define TOML_HAS_ATTR(attr) 0 +#endif + +// TOML_HAS_CPP_ATTR +#ifdef __has_cpp_attribute +#define TOML_HAS_CPP_ATTR(attr) __has_cpp_attribute(attr) +#else +#define TOML_HAS_CPP_ATTR(attr) 0 +#endif + +// TOML_COMPILER_HAS_EXCEPTIONS +#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__cpp_exceptions) +#define TOML_COMPILER_HAS_EXCEPTIONS 1 +#else +#define TOML_COMPILER_HAS_EXCEPTIONS 0 +#endif + +// TOML_COMPILER_HAS_RTTI +#if defined(_CPPRTTI) || defined(__GXX_RTTI) || TOML_HAS_FEATURE(cxx_rtti) +#define TOML_COMPILER_HAS_RTTI 1 +#else +#define TOML_COMPILER_HAS_RTTI 0 +#endif + +// TOML_ATTR (gnu attributes) +#if TOML_CLANG || TOML_GCC || defined(__GNUC__) +#define TOML_ATTR(...) __attribute__((__VA_ARGS__)) +#else +#define TOML_ATTR(...) +#endif + +// TOML_DECLSPEC (msvc attributes) +#ifdef _MSC_VER +#define TOML_DECLSPEC(...) __declspec(__VA_ARGS__) +#else +#define TOML_DECLSPEC(...) +#endif + +// TOML_CONCAT +#define TOML_CONCAT_1(x, y) x##y +#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) + +// TOML_MAKE_STRING +#define TOML_MAKE_STRING_1(s) #s +#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s) +// TOML_PRAGMA_XXXX (compiler-specific pragmas) #if TOML_CLANG +#define TOML_PRAGMA_CLANG(decl) _Pragma(TOML_MAKE_STRING(clang decl)) +#else +#define TOML_PRAGMA_CLANG(decl) +#endif +#if TOML_CLANG >= 9 +#define TOML_PRAGMA_CLANG_GE_9(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_9(decl) +#endif +#if TOML_CLANG >= 10 +#define TOML_PRAGMA_CLANG_GE_10(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_10(decl) +#endif +#if TOML_CLANG >= 11 +#define TOML_PRAGMA_CLANG_GE_11(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_11(decl) +#endif +#if TOML_GCC +#define TOML_PRAGMA_GCC(decl) _Pragma(TOML_MAKE_STRING(GCC decl)) +#else +#define TOML_PRAGMA_GCC(decl) +#endif +#if TOML_MSVC +#define TOML_PRAGMA_MSVC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_MSVC(...) +#endif +#if TOML_ICC +#define TOML_PRAGMA_ICC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_ICC(...) +#endif - #define TOML_PUSH_WARNINGS \ - _Pragma("clang diagnostic push") \ - static_assert(true) +// TOML_ALWAYS_INLINE +#ifdef _MSC_VER +#define TOML_ALWAYS_INLINE __forceinline +#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__always_inline__) +#define TOML_ALWAYS_INLINE \ + TOML_ATTR(__always_inline__) \ + inline +#else +#define TOML_ALWAYS_INLINE inline +#endif - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wswitch\"") \ - static_assert(true) +// TOML_NEVER_INLINE +#ifdef _MSC_VER +#define TOML_NEVER_INLINE TOML_DECLSPEC(noinline) +#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__noinline__) +#define TOML_NEVER_INLINE TOML_ATTR(__noinline__) +#else +#define TOML_NEVER_INLINE +#endif - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \ - static_assert(true) +// MSVC attributes +#define TOML_ABSTRACT_INTERFACE TOML_DECLSPEC(novtable) +#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases) - #if TOML_CLANG >= 10 - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 \ - _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") \ - static_assert(true) - #else - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 static_assert(true) - #endif +// TOML_TRIVIAL_ABI +#if TOML_CLANG || TOML_HAS_ATTR(__trivial_abi__) +#define TOML_TRIVIAL_ABI TOML_ATTR(__trivial_abi__) +#else +#define TOML_TRIVIAL_ABI +#endif - #if TOML_CLANG >= 11 - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_11 \ - _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \ - static_assert(true) - #else - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_11 static_assert(true) - #endif +// TOML_NODISCARD +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201603 +#define TOML_NODISCARD [[nodiscard]] +#elif TOML_CLANG || TOML_GCC || TOML_HAS_ATTR(__warn_unused_result__) +#define TOML_NODISCARD TOML_ATTR(__warn_unused_result__) +#else +#define TOML_NODISCARD +#endif - #define TOML_DISABLE_SPAM_WARNINGS \ - TOML_DISABLE_SPAM_WARNINGS_CLANG_10; \ - TOML_DISABLE_SPAM_WARNINGS_CLANG_11; \ - _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wweak-template-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("clang diagnostic ignored \"-Wpadded\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("clang diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("clang diagnostic ignored \"-Weverything\"") \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS - - #define TOML_ASSUME(expr) __builtin_assume(expr) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #if defined(_MSC_VER) // msvc compat mode - #ifdef __has_declspec_attribute - #if __has_declspec_attribute(novtable) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #endif - #if __has_declspec_attribute(empty_bases) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #if __has_declspec_attribute(noinline) - #define TOML_NEVER_INLINE __declspec(noinline) - #endif - #endif - #endif - #ifdef __has_attribute - #if !defined(TOML_ALWAYS_INLINE) && __has_attribute(always_inline) - #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline - #endif - #if !defined(TOML_NEVER_INLINE) && __has_attribute(noinline) - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #endif - #if !defined(TOML_TRIVIAL_ABI) && __has_attribute(trivial_abi) - #define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__)) - #endif - #if !defined(TOML_FLAGS_ENUM) && __has_attribute(flag_enum) - #define TOML_FLAGS_ENUM __attribute__((__flag_enum__)) - #endif - #if __has_attribute(enum_extensibility) - #ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) - #endif - #ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) - #endif - #endif - #endif - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) +// TOML_NODISCARD_CTOR +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201907 +#define TOML_NODISCARD_CTOR [[nodiscard]] +#else +#define TOML_NODISCARD_CTOR +#endif - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 +// pure + const +// clang-format off +#ifdef NDEBUG + #define TOML_PURE TOML_DECLSPEC(noalias) TOML_ATTR(__pure__) + #define TOML_CONST TOML_DECLSPEC(noalias) TOML_ATTR(__const__) + #define TOML_PURE_GETTER TOML_NODISCARD TOML_PURE + #define TOML_CONST_GETTER TOML_NODISCARD TOML_CONST + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_PURE + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_CONST +#else + #define TOML_PURE + #define TOML_CONST + #define TOML_PURE_GETTER TOML_NODISCARD + #define TOML_CONST_GETTER TOML_NODISCARD + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#endif +// clang-format on -#endif // clang +// TOML_ASSUME +#ifdef _MSC_VER +#define TOML_ASSUME(...) __assume(__VA_ARGS__) +#elif TOML_ICC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_assume) +#define TOML_ASSUME(...) __builtin_assume(__VA_ARGS__) +#else +#define TOML_ASSUME(...) static_assert(true) +#endif -//#==================================================================================================================== -//# MSVC -//#==================================================================================================================== +// TOML_UNREACHABLE +#ifdef _MSC_VER +#define TOML_UNREACHABLE __assume(0) +#elif TOML_ICC || TOML_CLANG || TOML_GCC || TOML_HAS_BUILTIN(__builtin_unreachable) +#define TOML_UNREACHABLE __builtin_unreachable() +#else +#define TOML_UNREACHABLE static_assert(true) +#endif -#if TOML_MSVC || TOML_ICC_CL - - #define TOML_CPP_VERSION _MSVC_LANG - #if TOML_MSVC // !intel-cl - - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) - - #if TOML_HAS_INCLUDE() - #pragma warning(push, 0) - #include - #pragma warning(pop) - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ - __pragma(warning(disable: ALL_CODE_ANALYSIS_WARNINGS)) \ - static_assert(true) - #else - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS - static_assert(true) - #endif +// TOML_LIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(likely) >= 201803 +#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] +#define TOML_LIKELY_CASE [[likely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1)) +#else +#define TOML_LIKELY(...) (__VA_ARGS__) +#endif +#ifndef TOML_LIKELY_CASE +#define TOML_LIKELY_CASE +#endif - #define TOML_DISABLE_SWITCH_WARNINGS \ - __pragma(warning(disable: 4061)) /* enumerator 'identifier' is not explicitly handled by a case label */ \ - __pragma(warning(disable: 4062)) /* enumerator 'identifier' is not handled */ \ - __pragma(warning(disable: 4063)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 4127)) /* conditional expr is constant */ \ - __pragma(warning(disable: 4324)) /* structure was padded due to alignment specifier */ \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4464)) /* relative include path contains '..' */ \ - __pragma(warning(disable: 4505)) /* unreferenced local function removed */ \ - __pragma(warning(disable: 4514)) /* unreferenced inline function has been removed */ \ - __pragma(warning(disable: 4582)) /* constructor is not implicitly called */ \ - __pragma(warning(disable: 4623)) /* default constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4625)) /* copy constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4626)) /* assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 4710)) /* function not inlined */ \ - __pragma(warning(disable: 4711)) /* function selected for automatic expansion */ \ - __pragma(warning(disable: 4820)) /* N bytes padding added */ \ - __pragma(warning(disable: 4946)) /* reinterpret_cast used between related classes */ \ - __pragma(warning(disable: 5026)) /* move constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 5027)) /* move assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ - __pragma(warning(disable: 5045)) /* Compiler will insert Spectre mitigation */ \ - __pragma(warning(disable: 26451)) \ - __pragma(warning(disable: 26490)) \ - __pragma(warning(disable: 26495)) \ - __pragma(warning(disable: 26812)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - __pragma(warning(disable: 4365)) /* argument signed/unsigned mismatch */ \ - __pragma(warning(disable: 4738)) /* storing 32-bit float result in memory */ \ - __pragma(warning(disable: 5219)) /* implicit conversion from integral to float */ \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4668)) \ - __pragma(warning(disable: 5105)) \ - TOML_DISABLE_CODE_ANALYSIS_WARNINGS;\ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS +// TOML_UNLIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(unlikely) >= 201803 +#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] +#define TOML_UNLIKELY_CASE [[unlikely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0)) +#else +#define TOML_UNLIKELY(...) (__VA_ARGS__) +#endif +#ifndef TOML_UNLIKELY_CASE +#define TOML_UNLIKELY_CASE +#endif - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #define TOML_NEVER_INLINE __declspec(noinline) - #define TOML_ASSUME(expr) __assume(expr) - #define TOML_UNREACHABLE __assume(0) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #ifdef _CPPUNWIND - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif +// TOML_FLAGS_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(flag_enum) +#define TOML_FLAGS_ENUM __attribute__((flag_enum)) +#else +#define TOML_FLAGS_ENUM +#endif -#endif // msvc +// TOML_OPEN_ENUM + TOML_CLOSED_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(enum_extensibility) +#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) +#define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) +#else +#define TOML_OPEN_ENUM +#define TOML_CLOSED_ENUM +#endif + +// TOML_OPEN_FLAGS_ENUM + TOML_CLOSED_FLAGS_ENUM +#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +#define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM + +// TOML_MAKE_FLAGS +#define TOML_MAKE_FLAGS_2(T, op, linkage) \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator op(T lhs, T rhs) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(static_cast(lhs) op static_cast(rhs)); \ + } \ + \ + linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept \ + { \ + return lhs = (lhs op rhs); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS_1(T, linkage) \ + static_assert(std::is_enum_v); \ + \ + TOML_MAKE_FLAGS_2(T, &, linkage); \ + TOML_MAKE_FLAGS_2(T, |, linkage); \ + TOML_MAKE_FLAGS_2(T, ^, linkage); \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator~(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(~static_cast(val)); \ + } \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr bool operator!(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return !static_cast(val); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS(T) TOML_MAKE_FLAGS_1(T, ) -//#==================================================================================================================== -//# ICC -//#==================================================================================================================== +#define TOML_UNUSED(...) static_cast(__VA_ARGS__) -#if TOML_ICC - - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) +#define TOML_DELETE_DEFAULTS(T) \ + T(const T&) = delete; \ + T(T&&) = delete; \ + T& operator=(const T&) = delete; \ + T& operator=(T&&) = delete + +#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator==(RHS rhs, LHS lhs) noexcept \ + { \ + return lhs == rhs; \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(LHS lhs, RHS rhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(RHS rhs, LHS lhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + static_assert(true) - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 82)) /* storage class is not first */ \ - __pragma(warning(disable: 111)) /* statement unreachable (false-positive) */ \ - __pragma(warning(disable: 869)) /* unreferenced parameter */ \ - __pragma(warning(disable: 1011)) /* missing return (false-positive) */ \ - __pragma(warning(disable: 2261)) /* assume expr side-effects discarded */ \ - static_assert(true) +#define TOML_EVAL_BOOL_1(T, F) T +#define TOML_EVAL_BOOL_0(T, F) F - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) +#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) +#define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ +#endif - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - static_assert(true) +//====================================================================================================================== +// COMPILER-SPECIFIC WARNING MANAGEMENT +//====================================================================================================================== - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS +#if TOML_CLANG -#endif // icc +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + static_assert(true) -//#==================================================================================================================== -//# GCC -//#==================================================================================================================== +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \ + static_assert(true) -#if TOML_GCC +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \ + static_assert(true) - #define TOML_PUSH_WARNINGS \ - _Pragma("GCC diagnostic push") \ - static_assert(true) - - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wswitch\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-enum\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-default\"") \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ - static_assert(true) - - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wpadded\"") \ - _Pragma("GCC diagnostic ignored \"-Wcast-align\"") \ - _Pragma("GCC diagnostic ignored \"-Wcomment\"") \ - _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \ - _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"") \ - _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ - _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ - _Pragma("GCC diagnostic ignored \"-Wnoexcept\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("GCC diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("GCC diagnostic ignored \"-Wall\"") \ - _Pragma("GCC diagnostic ignored \"-Wextra\"") \ - _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ - static_assert(true) - - - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS - - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline - #endif - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \ + TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \ + TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \ + static_assert(true, "") + +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) + +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 +#elif TOML_MSVC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#if TOML_HAS_INCLUDE() +#pragma warning(push, 0) +#include +#pragma warning(pop) +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ + __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) \ + static_assert(true) +#else +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) #endif -//#==================================================================================================================== -//# CPP VERSION -//#==================================================================================================================== +#define TOML_DISABLE_SWITCH_WARNINGS \ + __pragma(warning(disable : 4061)) \ + __pragma(warning(disable : 4062)) \ + __pragma(warning(disable : 4063)) \ + __pragma(warning(disable : 26819)) /* cg: unannotated fallthrough */ \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 4127)) /* conditional expr is constant */ \ + __pragma(warning(disable : 4324)) /* structure was padded due to alignment specifier */ \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4464)) /* relative include path contains '..' */ \ + __pragma(warning(disable : 4505)) /* unreferenced local function removed */ \ + __pragma(warning(disable : 4514)) /* unreferenced inline function has been removed */ \ + __pragma(warning(disable : 4582)) /* constructor is not implicitly called */ \ + __pragma(warning(disable : 4623)) /* default constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4625)) /* copy constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4626)) /* assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 4710)) /* function not inlined */ \ + __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \ + __pragma(warning(disable : 4820)) /* N bytes padding added */ \ + __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \ + __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ + __pragma(warning(disable : 5045)) /* Compiler will insert Spectre mitigation */ \ + __pragma(warning(disable : 26451)) \ + __pragma(warning(disable : 26490)) \ + __pragma(warning(disable : 26495)) \ + __pragma(warning(disable : 26812)) \ + __pragma(warning(disable : 26819)) \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + __pragma(warning(disable : 4365)) /* argument signed/unsigned mismatch */ \ + __pragma(warning(disable : 4738)) /* storing 32-bit float result in memory */ \ + __pragma(warning(disable : 5219)) /* implicit conversion from integral to float */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4668)) \ + __pragma(warning(disable : 5105)) \ + TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS + +#elif TOML_ICC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 82)) /* storage class is not first */ \ + __pragma(warning(disable : 111)) /* statement unreachable (false-positive) */ \ + __pragma(warning(disable : 869)) /* unreferenced parameter */ \ + __pragma(warning(disable : 1011)) /* missing return (false-positive) */ \ + __pragma(warning(disable : 2261)) /* assume expr side-effects discarded */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + TOML_DISABLE_SPAM_WARNINGS + +#define TOML_ENABLE_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#elif TOML_GCC + +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + static_assert(true) + +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + static_assert(true) -#ifndef TOML_CPP_VERSION - #define TOML_CPP_VERSION __cplusplus +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) + +#endif + +#ifndef TOML_PUSH_WARNINGS +#define TOML_PUSH_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SWITCH_WARNINGS +#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SPAM_WARNINGS +#define TOML_DISABLE_SPAM_WARNINGS static_assert(true) #endif -#if TOML_CPP_VERSION < 201103L - #error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml -#elif TOML_CPP_VERSION < 201703L - #error toml++ requires C++17 or higher. For a TOML library supporting C++11 see https://github.com/ToruNiina/toml11 +#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS +#define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) +#endif +#ifndef TOML_POP_WARNINGS +#define TOML_POP_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_WARNINGS +#define TOML_DISABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_ENABLE_WARNINGS +#define TOML_ENABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 #endif //#==================================================================================================================== //# USER CONFIGURATION //#==================================================================================================================== +/// \addtogroup configuration Library Configuration +/// \brief Preprocessor macros for configuring library functionality. +/// \detail Define these before including toml++ to alter the way it functions. +/// \remarks Some of these options have ABI implications; inline namespaces are used to prevent +/// you from trying to link incompatible combinations together. +/// @{ #ifdef TOML_CONFIG_HEADER - #include TOML_CONFIG_HEADER +#include TOML_CONFIG_HEADER #endif +//# {{ +#if TOML_DOXYGEN +#define TOML_CONFIG_HEADER +#endif +/// \def TOML_CONFIG_HEADER +/// \brief An additional header to include before any other toml++ header files. +/// \detail Not defined by default. +//# }} // is the library being built as a shared lib/dll using meson and friends? #ifndef TOML_SHARED_LIB - #define TOML_SHARED_LIB 0 +#define TOML_SHARED_LIB 0 #endif - + // header-only mode #if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0 - #define TOML_HEADER_ONLY TOML_ALL_INLINE +#define TOML_HEADER_ONLY TOML_ALL_INLINE #endif #if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 1 +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 1 #endif -#if defined(DOXYGEN) || TOML_SHARED_LIB - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 0 +#if TOML_DOXYGEN || TOML_SHARED_LIB +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 0 #endif +/// \def TOML_HEADER_ONLY +/// \brief Sets whether the library is entirely inline. +/// \detail Defaults to `1`. +/// \remark Disabling this means that you must define #TOML_IMPLEMENTATION in +/// exactly one translation unit in your project: +/// \cpp +/// // global_header_that_includes_toml++.h +/// #define TOML_HEADER_ONLY 0 +/// #include +/// +/// // some_code_file.cpp +/// #define TOML_IMPLEMENTATION +/// #include "global_header_that_includes_toml++.h" +/// \ecpp // internal implementation switch #if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY - #undef TOML_IMPLEMENTATION - #define TOML_IMPLEMENTATION 1 +#undef TOML_IMPLEMENTATION +#define TOML_IMPLEMENTATION 1 #else - #define TOML_IMPLEMENTATION 0 +#define TOML_IMPLEMENTATION 0 #endif +/// \def TOML_IMPLEMENTATION +/// \brief Enables the library's implementation when #TOML_HEADER_ONLY is disabled. +/// \detail Not defined by default. Meaningless when #TOML_HEADER_ONLY is enabled. // dll/shared lib function exports (legacy - TOML_API was the old name for this setting) -#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) \ - && !defined(TOML_EXPORTED_STATIC_FUNCTION) \ - && !defined(TOML_EXPORTED_FREE_FUNCTION) \ - && !defined(TOML_EXPORTED_CLASS) \ - && defined(TOML_API) - #define TOML_EXPORTED_MEMBER_FUNCTION TOML_API - #define TOML_EXPORTED_STATIC_FUNCTION TOML_API - #define TOML_EXPORTED_FREE_FUNCTION TOML_API +#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) \ + && !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API) +#define TOML_EXPORTED_MEMBER_FUNCTION TOML_API +#define TOML_EXPORTED_STATIC_FUNCTION TOML_API +#define TOML_EXPORTED_FREE_FUNCTION TOML_API #endif // dll/shared lib exports #if TOML_SHARED_LIB - #undef TOML_API - #undef TOML_EXPORTED_CLASS - #undef TOML_EXPORTED_MEMBER_FUNCTION - #undef TOML_EXPORTED_STATIC_FUNCTION - #undef TOML_EXPORTED_FREE_FUNCTION - #if defined(_WIN32) || defined(__CYGWIN__) - #if TOML_IMPLEMENTATION - #define TOML_EXPORTED_CLASS __declspec(dllexport) - #define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport) - #else - #define TOML_EXPORTED_CLASS __declspec(dllimport) - #define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport) - #endif - #ifndef TOML_CALLCONV - #define TOML_CALLCONV __cdecl - #endif - #elif defined(__GNUC__) && __GNUC__ >= 4 - #define TOML_EXPORTED_CLASS __attribute__((visibility("default"))) - #define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default"))) - #define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default"))) - #define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default"))) - #endif +#undef TOML_API +#undef TOML_EXPORTED_CLASS +#undef TOML_EXPORTED_MEMBER_FUNCTION +#undef TOML_EXPORTED_STATIC_FUNCTION +#undef TOML_EXPORTED_FREE_FUNCTION +#if TOML_WINDOWS +#if TOML_IMPLEMENTATION +#define TOML_EXPORTED_CLASS __declspec(dllexport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport) +#else +#define TOML_EXPORTED_CLASS __declspec(dllimport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport) +#endif +#ifndef TOML_CALLCONV +#define TOML_CALLCONV __cdecl +#endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define TOML_EXPORTED_CLASS __attribute__((visibility("default"))) +#define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default"))) +#endif #endif #ifndef TOML_EXPORTED_CLASS - #define TOML_EXPORTED_CLASS +#define TOML_EXPORTED_CLASS #endif #ifndef TOML_EXPORTED_MEMBER_FUNCTION - #define TOML_EXPORTED_MEMBER_FUNCTION +#define TOML_EXPORTED_MEMBER_FUNCTION #endif #ifndef TOML_EXPORTED_STATIC_FUNCTION - #define TOML_EXPORTED_STATIC_FUNCTION +#define TOML_EXPORTED_STATIC_FUNCTION #endif #ifndef TOML_EXPORTED_FREE_FUNCTION - #define TOML_EXPORTED_FREE_FUNCTION +#define TOML_EXPORTED_FREE_FUNCTION #endif +/// \def TOML_EXPORTED_CLASS +/// \brief An 'export' annotation to add to classes. +/// \detail Not defined by default. +/// \remark You might override this with `__declspec(dllexport)` if you were building the library +/// into the public API of a DLL on Windows. +/// +/// \def TOML_EXPORTED_MEMBER_FUNCTION +/// \brief An 'export' annotation to add to non-static class member functions. +/// \detail Not defined by default. +/// \remark You might override this with `__declspec(dllexport)` if you were building the library +/// into the public API of a DLL on Windows. +/// +/// \def TOML_EXPORTED_FREE_FUNCTION +/// \brief An 'export' annotation to add to free functions. +/// \detail Not defined by default. +/// \remark You might override this with `__declspec(dllexport)` if you were building the library +/// into the public API of a DLL on Windows. +/// +/// \def TOML_EXPORTED_STATIC_FUNCTION +/// \brief An 'export' annotation to add to `static` class member functions. +/// \detail Not defined by default. +/// \remark You might override this with `__declspec(dllexport)` if you were building the library +/// into the public API of a DLL on Windows. // experimental language features -#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES pre-3.0 - #define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES +#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES + // pre-3.0 +#define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES #endif #if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE - #undef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 1 +#undef TOML_ENABLE_UNRELEASED_FEATURES +#define TOML_ENABLE_UNRELEASED_FEATURES 1 #endif #ifndef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 0 +#define TOML_ENABLE_UNRELEASED_FEATURES 0 #endif +/// \def TOML_ENABLE_UNRELEASED_FEATURES +/// \brief Enables support for unreleased TOML language features not yet part of a +/// [numbered version](https://github.com/toml-lang/toml/releases). +/// \detail Defaults to `0`. +/// \see [TOML Language Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support) // parser #if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0 - #define TOML_ENABLE_PARSER TOML_PARSER +#define TOML_ENABLE_PARSER TOML_PARSER #endif #if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE - #undef TOML_ENABLE_PARSER - #define TOML_ENABLE_PARSER 1 +#undef TOML_ENABLE_PARSER +#define TOML_ENABLE_PARSER 1 #endif +/// \def TOML_ENABLE_PARSER +/// \brief Sets whether the parser-related parts of the library are included. +/// \detail Defaults to `1`. +/// \remarks If you don't parse any TOML from files or strings, setting `TOML_ENABLE_PARSER` +/// to `0` can improve compilation speed and reduce binary size. // formatters -#if !defined(TOML_ENABLE_FORMATTERS) \ - || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_FORMATTERS - #define TOML_ENABLE_FORMATTERS 1 +#if !defined(TOML_ENABLE_FORMATTERS) || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE +#undef TOML_ENABLE_FORMATTERS +#define TOML_ENABLE_FORMATTERS 1 #endif +/// \def TOML_ENABLE_FORMATTERS +/// \brief Sets whether the various formatter classes are enabled. +/// \detail Defaults to `1`. +/// \remarks If you don't need to re-serialize TOML data, setting `TOML_ENABLE_FORMATTERS` +/// to `0` can improve compilation speed and reduce binary size. +/// \see +/// - toml::toml_formatter +/// - toml::json_formatter +/// - toml::yaml_formatter // SIMD -#if !defined(TOML_ENABLE_SIMD) \ - || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_SIMD - #define TOML_ENABLE_SIMD 1 +#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || TOML_INTELLISENSE +#undef TOML_ENABLE_SIMD +#define TOML_ENABLE_SIMD 1 #endif // windows compat #if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0 - #define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT #endif -#if !defined(TOML_ENABLE_WINDOWS_COMPAT) \ - || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 1 +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ + || TOML_INTELLISENSE +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 1 #endif /// \cond -#ifndef _WIN32 - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 0 +#if !TOML_WINDOWS +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 0 #endif /// \endcond #ifndef TOML_INCLUDE_WINDOWS_H - #define TOML_INCLUDE_WINDOWS_H 0 +#define TOML_INCLUDE_WINDOWS_H 0 #endif +/// \def TOML_ENABLE_WINDOWS_COMPAT +/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library +/// when building for Windows. +/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building for anything other +/// than Windows. +/// \remark This does not change the underlying string type used to represent TOML keys and string +/// values; that will still be std::string. This setting simply enables some narrow <=> wide string +/// conversions when necessary at various interface boundaries. +///

+/// If you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide strings, +/// you can safely set this to `0`. // custom optional #ifdef TOML_OPTIONAL_TYPE - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 #else - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 -#endif - -// exceptions (compiler support) -#ifndef TOML_COMPILER_EXCEPTIONS - #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif -#endif - -// exceptions (library use) -#if TOML_COMPILER_EXCEPTIONS - #if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) - #undef TOML_EXCEPTIONS - #define TOML_EXCEPTIONS 1 - #endif -#else - #if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS - #error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler. - #endif - #undef TOML_EXCEPTIONS - #define TOML_EXCEPTIONS 0 -#endif - -// calling convention for static/free/friend functions -#ifndef TOML_CALLCONV - #define TOML_CALLCONV -#endif - -#ifndef TOML_UNDEF_MACROS - #define TOML_UNDEF_MACROS 1 -#endif - -#ifndef TOML_MAX_NESTED_VALUES - #define TOML_MAX_NESTED_VALUES 256 - // this refers to the depth of nested values, e.g. inline tables and arrays. - // 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... -#endif - -#ifdef TOML_CHAR_8_STRINGS - #if TOML_CHAR_8_STRINGS - #error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. - #endif +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 #endif - -#ifdef TOML_LARGE_FILES - #if !TOML_LARGE_FILES - #error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. - #endif -#endif - -//#==================================================================================================================== -//# ATTRIBUTES, UTILITY MACROS ETC -//#==================================================================================================================== - -#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) - // not supported by any version of GCC or Clang as of 26/11/2020 - // not supported by any version of ICC on Linux as of 11/01/2021 - #define TOML_FLOAT_CHARCONV 0 -#endif -#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) - // causes link errors on emscripten - // causes Mac OS SDK version errors on some versions of Apple Clang - #define TOML_INT_CHARCONV 0 -#endif -#ifndef TOML_INT_CHARCONV - #define TOML_INT_CHARCONV 1 -#endif -#ifndef TOML_FLOAT_CHARCONV - #define TOML_FLOAT_CHARCONV 1 -#endif -#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() - #undef TOML_INT_CHARCONV - #undef TOML_FLOAT_CHARCONV - #define TOML_INT_CHARCONV 0 - #define TOML_FLOAT_CHARCONV 0 -#endif - -#ifndef TOML_PUSH_WARNINGS - #define TOML_PUSH_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SWITCH_WARNINGS - #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SPAM_WARNINGS - #define TOML_DISABLE_SPAM_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS - #define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) -#endif -#ifndef TOML_POP_WARNINGS - #define TOML_POP_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_WARNINGS - #define TOML_DISABLE_WARNINGS static_assert(true) -#endif -#ifndef TOML_ENABLE_WARNINGS - #define TOML_ENABLE_WARNINGS static_assert(true) -#endif - -#ifndef TOML_ATTR - #define TOML_ATTR(...) -#endif - -#ifndef TOML_ABSTRACT_BASE - #define TOML_ABSTRACT_BASE +//# {{ +#if TOML_DOXYGEN +#define TOML_OPTIONAL_TYPE #endif +/// \def TOML_OPTIONAL_TYPE +/// \brief Overrides the `optional` type used by the library. +/// \detail Not defined by default (use std::optional). +/// \warning The library uses optionals internally in a few places; if you choose to replace the optional type +/// it must be with something that is still API-compatible with std::optional +/// (e.g. [tl::optional](https://github.com/TartanLlama/optional)). +//# }} -#ifndef TOML_EMPTY_BASES - #define TOML_EMPTY_BASES +// exceptions (library use) +#if TOML_COMPILER_HAS_EXCEPTIONS +#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) +#undef TOML_EXCEPTIONS +#define TOML_EXCEPTIONS 1 #endif - -#ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE inline +#else +#if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS +#error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler. #endif -#ifndef TOML_NEVER_INLINE - #define TOML_NEVER_INLINE +#undef TOML_EXCEPTIONS +#define TOML_EXCEPTIONS 0 #endif +/// \def TOML_EXCEPTIONS +/// \brief Sets whether the library uses exceptions to report parsing failures. +/// \detail Defaults to `1` or `0` according to your compiler's exception mode. -#ifndef TOML_ASSUME - #define TOML_ASSUME(expr) static_assert(true) +// calling convention for static/free/friend functions +#ifndef TOML_CALLCONV +#define TOML_CALLCONV #endif +/// \def TOML_CALLCONV +/// \brief Calling convention to apply to exported free/static functions. +/// \detail Not defined by default (let the compiler decide). -#ifndef TOML_UNREACHABLE - #define TOML_UNREACHABLE TOML_ASSUME(false) +//# {{ +#if TOML_DOXYGEN +#define TOML_SMALL_FLOAT_TYPE #endif +/// \def TOML_SMALL_FLOAT_TYPE +/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. +/// \detail Not defined by default. +/// \remark If you're building for a platform that has `_Float16` and/or `__fp16`, you don't +/// need to use this configuration option to make toml++ aware of them. The library comes with that built-in. +//# }} -#ifndef TOML_FLAGS_ENUM - #define TOML_FLAGS_ENUM +#ifndef TOML_UNDEF_MACROS +#define TOML_UNDEF_MACROS 1 #endif -#ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM +#ifndef TOML_MAX_NESTED_VALUES +#define TOML_MAX_NESTED_VALUES 256 +// this refers to the depth of nested values, e.g. inline tables and arrays. +// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... #endif -#ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM +#ifdef TOML_CHAR_8_STRINGS +#if TOML_CHAR_8_STRINGS +#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. #endif - -#ifndef TOML_OPEN_FLAGS_ENUM - #define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM #endif -#ifndef TOML_CLOSED_FLAGS_ENUM - #define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM +#ifdef TOML_LARGE_FILES +#if !TOML_LARGE_FILES +#error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. #endif - -#ifdef __has_cpp_attribute - #define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__) -#else - #define TOML_HAS_ATTR(...) 0 #endif -#if TOML_HAS_ATTR(likely) >= 201803 - #ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] - #endif - #ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE [[likely]] - #endif -#endif -#ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) -#endif -#ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE +#ifndef TOML_LIFETIME_HOOKS +#define TOML_LIFETIME_HOOKS 0 #endif -#if TOML_HAS_ATTR(unlikely) >= 201803 - #ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] - #endif - #ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE [[unlikely]] - #endif -#endif -#ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) +#ifdef NDEBUG +#undef TOML_ASSERT +#define TOML_ASSERT(expr) static_assert(true) #endif -#ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE +#ifndef TOML_ASSERT +#ifndef assert +TOML_DISABLE_WARNINGS; +#include +TOML_ENABLE_WARNINGS; #endif - -#if TOML_HAS_ATTR(nodiscard) - #define TOML_NODISCARD [[nodiscard]] -#else - #define TOML_NODISCARD +#define TOML_ASSERT(expr) assert(expr) #endif - -#if TOML_HAS_ATTR(nodiscard) >= 201907 - #define TOML_NODISCARD_CTOR [[nodiscard]] +#ifdef NDEBUG +#define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) #else - #define TOML_NODISCARD_CTOR +#define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) #endif +/// \def TOML_ASSERT(expr) +/// \brief Sets the assert function used by the library. +/// \detail Defaults to the standard C `assert()`. -#ifndef TOML_TRIVIAL_ABI - #define TOML_TRIVIAL_ABI +//# {{ +#if TOML_DOXYGEN +#define TOML_SMALL_INT_TYPE #endif +/// \def TOML_SMALL_INT_TYPE +/// \brief If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. +/// \detail Not defined by default. +//# }} -#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ - __VA_ARGS__ TOML_NODISCARD friend bool operator == (RHS rhs, LHS lhs) noexcept { return lhs == rhs; } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (LHS lhs, RHS rhs) noexcept { return !(lhs == rhs); } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); } \ - static_assert(true) +/// @} +//#==================================================================================================================== +//# CHARCONV SUPPORT +//#==================================================================================================================== -#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 +#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) +// not supported by any version of GCC or Clang as of 26/11/2020 +// not supported by any version of ICC on Linux as of 11/01/2021 +#define TOML_FLOAT_CHARCONV 0 #endif - -#define TOML_CONCAT_1(x, y) x##y -#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) - -#define TOML_EVAL_BOOL_1(T, F) T -#define TOML_EVAL_BOOL_0(T, F) F - -#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ - || defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) - #define TOML_ARM 1 -#else - #define TOML_ARM 0 -#endif - -#define TOML_MAKE_FLAGS_(name, op) \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator op(name lhs, name rhs) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(static_cast(lhs) op static_cast(rhs)); \ - } \ - constexpr name& operator TOML_CONCAT(op, =)(name & lhs, name rhs) noexcept \ - { \ - return lhs = (lhs op rhs); \ - } \ - static_assert(true, "") - -#define TOML_MAKE_FLAGS(name) \ - TOML_MAKE_FLAGS_(name, &); \ - TOML_MAKE_FLAGS_(name, |); \ - TOML_MAKE_FLAGS_(name, ^); \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator~(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(~static_cast(val)); \ - } \ - TOML_CONST_INLINE_GETTER \ - constexpr bool operator!(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return !static_cast(val); \ - } \ - static_assert(true, "") - - -#ifndef TOML_LIFETIME_HOOKS - #define TOML_LIFETIME_HOOKS 0 +#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) +// causes link errors on emscripten +// causes Mac OS SDK version errors on some versions of Apple Clang +#define TOML_INT_CHARCONV 0 #endif - -#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) - #define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ +#ifndef TOML_INT_CHARCONV +#define TOML_INT_CHARCONV 1 #endif - -#ifdef NDEBUG - #define TOML_PURE_GETTER TOML_NODISCARD TOML_ATTR(pure) - #define TOML_CONST_GETTER TOML_NODISCARD TOML_ATTR(const) - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(pure) - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(const) -#else - #define TOML_PURE_GETTER TOML_NODISCARD - #define TOML_CONST_GETTER TOML_NODISCARD - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#ifndef TOML_FLOAT_CHARCONV +#define TOML_FLOAT_CHARCONV 1 +#endif +#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() +#undef TOML_INT_CHARCONV +#undef TOML_FLOAT_CHARCONV +#define TOML_INT_CHARCONV 0 +#define TOML_FLOAT_CHARCONV 0 #endif -#define TOML_UNUSED(...) static_cast(__VA_ARGS__) - -#define TOML_DELETE_DEFAULTS(T) \ - T(const T&) = delete; \ - T(T&&) = delete; \ - T& operator=(const T&) = delete; \ - T& operator=(T&&) = delete - -//====================================================================================================================== -// SFINAE -//====================================================================================================================== +//#===================================================================================================================== +//# SFINAE +//#===================================================================================================================== /// \cond #if defined(__cpp_concepts) && __cpp_concepts >= 201907 - #define TOML_REQUIRES(...) requires(__VA_ARGS__) +#define TOML_REQUIRES(...) requires(__VA_ARGS__) #else - #define TOML_REQUIRES(...) +#define TOML_REQUIRES(...) #endif -#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 -#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__ TOML_ENABLE_IF(condition)> TOML_REQUIRES(condition) -#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) +#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 +#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \ + template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \ + TOML_REQUIRES(condition) +#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) /// \endcond //# {{ #ifndef TOML_CONSTRAINED_TEMPLATE - #define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__> +#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__> #endif #ifndef TOML_HIDDEN_CONSTRAINT - #define TOML_HIDDEN_CONSTRAINT(condition, ...) +#define TOML_HIDDEN_CONSTRAINT(condition, ...) #endif //# }} -//#==================================================================================================================== +//#===================================================================================================================== //# EXTENDED INT AND FLOAT TYPES -//#==================================================================================================================== +//#===================================================================================================================== +// clang-format off #ifdef __FLT16_MANT_DIG__ #if __FLT_RADIX__ == 2 \ @@ -859,9 +1044,11 @@ #define TOML_UINT128 __uint128_t #endif +// clang-format on //#==================================================================================================================== //# VERSIONS AND NAMESPACES //#==================================================================================================================== +// clang-format off #include "version.h" @@ -888,7 +1075,7 @@ TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) #ifndef TOML_ABI_NAMESPACES - #ifdef DOXYGEN + #if TOML_DOXYGEN #define TOML_ABI_NAMESPACES 0 #else #define TOML_ABI_NAMESPACES 1 @@ -927,32 +1114,15 @@ #define TOML_INTERNAL_LINKAGE static #endif +// clang-format on //#==================================================================================================================== //# ASSERT //#==================================================================================================================== -#ifdef NDEBUG - #undef TOML_ASSERT - #define TOML_ASSERT(expr) static_assert(true) -#endif -#ifndef TOML_ASSERT - #ifndef assert - TOML_DISABLE_WARNINGS; - #include - TOML_ENABLE_WARNINGS; - #endif - #define TOML_ASSERT(expr) assert(expr) -#endif -#ifdef NDEBUG - #define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) -#else - #define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) -#endif - //#==================================================================================================================== //# STATIC ASSERT MESSAGE FORMATTING //#==================================================================================================================== - +// clang-format off /// \cond #if TOML_SIMPLE_STATIC_ASSERT_MESSAGES @@ -1005,155 +1175,4 @@ TOML_SA_NODE_TYPE_LIST /// \endcond - -//#==================================================================================================================== -//# DOXYGEN SPAM -//#==================================================================================================================== - -//# {{ -#ifdef DOXYGEN - -/// \addtogroup configuration Library Configuration -/// \brief Preprocessor macros for configuring library functionality. -/// \detail Define these before including toml++ to alter the way it functions. -/// \remarks Some of these options have ABI implications; inline namespaces are used to prevent -/// you from trying to link incompatible combinations together. -/// @{ - - -/// \def TOML_HEADER_ONLY -/// \brief Sets whether the library is entirely inline. -/// \detail Defaults to `1`. -/// \remark Disabling this means that you must define #TOML_IMPLEMENTATION in -/// exactly one translation unit in your project: -/// \cpp -/// // global_header_that_includes_toml++.h -/// #define TOML_HEADER_ONLY 0 -/// #include -/// -/// // some_code_file.cpp -/// #define TOML_IMPLEMENTATION -/// #include "global_header_that_includes_toml++.h" -/// \ecpp - - -/// \def TOML_CALLCONV -/// \brief Calling convention to apply to exported free/static functions. -/// \detail Not defined by default (let the compiler decide). - - -/// \def TOML_EXPORTED_CLASS -/// \brief An 'export' annotation to add to classes. -/// \detail Not defined by default. -/// \remark You might override this with `__declspec(dllexport)` if you were building the library -/// into the public API of a DLL on Windows. - - -/// \def TOML_EXPORTED_MEMBER_FUNCTION -/// \brief An 'export' annotation to add to non-static class member functions. -/// \detail Not defined by default. -/// \remark You might override this with `__declspec(dllexport)` if you were building the library -/// into the public API of a DLL on Windows. - - -/// \def TOML_EXPORTED_FREE_FUNCTION -/// \brief An 'export' annotation to add to free functions. -/// \detail Not defined by default. -/// \remark You might override this with `__declspec(dllexport)` if you were building the library -/// into the public API of a DLL on Windows. - - -/// \def TOML_EXPORTED_STATIC_FUNCTION -/// \brief An 'export' annotation to add to `static` class member functions. -/// \detail Not defined by default. -/// \remark You might override this with `__declspec(dllexport)` if you were building the library -/// into the public API of a DLL on Windows. - - -/// \def TOML_ASSERT(expr) -/// \brief Sets the assert function used by the library. -/// \detail Defaults to the standard C `assert()`. - - -#define TOML_CONFIG_HEADER -/// \def TOML_CONFIG_HEADER -/// \brief An additional header to include before any other toml++ header files. -/// \detail Not defined by default. - - -/// \def TOML_EXCEPTIONS -/// \brief Sets whether the library uses exceptions to report parsing failures. -/// \detail Defaults to `1` or `0` according to your compiler's exception mode. - - -/// \def TOML_IMPLEMENTATION -/// \brief Enables the library's implementation when #TOML_HEADER_ONLY is disabled. -/// \detail Not defined by default. Meaningless when #TOML_HEADER_ONLY is enabled. - - -#define TOML_OPTIONAL_TYPE -/// \def TOML_OPTIONAL_TYPE -/// \brief Overrides the `optional` type used by the library. -/// \detail Not defined by default (use std::optional). -/// \warning The library uses optionals internally in a few places; if you choose to replace the optional type -/// it must be with something that is still API-compatible with std::optional -/// (e.g. [tl::optional](https://github.com/TartanLlama/optional)). - - -/// \def TOML_ENABLE_PARSER -/// \brief Sets whether the parser-related parts of the library are included. -/// \detail Defaults to `1`. -/// \remarks If you don't parse any TOML from files or strings, setting `TOML_ENABLE_PARSER` -/// to `0` can improve compilation speed and reduce binary size. - - -/// \def TOML_ENABLE_FORMATTERS -/// \brief Sets whether the various formatter classes are enabled. -/// \detail Defaults to `1`. -/// \remarks If you don't need to re-serialize TOML data, setting `TOML_ENABLE_FORMATTERS` -/// to `0` can improve compilation speed and reduce binary size. -/// \see -/// - toml::toml_formatter -/// - toml::json_formatter -/// - toml::yaml_formatter - - -#define TOML_SMALL_FLOAT_TYPE -/// \def TOML_SMALL_FLOAT_TYPE -/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. -/// \detail Not defined by default. -/// \remark If you're building for a platform that has `_Float16` and/or `__fp16`, you don't -/// need to use this configuration option to make toml++ aware of them. The library comes with that built-in. - - -#define TOML_SMALL_INT_TYPE -/// \def TOML_SMALL_INT_TYPE -/// \brief If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. -/// \detail Not defined by default. - - -/// \def TOML_ENABLE_UNRELEASED_FEATURES -/// \brief Enables support for unreleased TOML language features not yet part of a -/// [numbered version](https://github.com/toml-lang/toml/releases). -/// \detail Defaults to `0`. -/// \see [TOML Language Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support) - - -/// \def TOML_ENABLE_WINDOWS_COMPAT -/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library -/// when building for Windows. -/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building for anything other -/// than Windows. -/// \remark This does not change the underlying string type used to represent TOML keys and string -/// values; that will still be std::string. This setting simply enables some narrow <=> wide string -/// conversions when necessary at various interface boundaries. -///

-/// If you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide strings, -/// you can safely set this to `0`. - - -/// @} -#endif // DOXYGEN -//# }} - // clang-format on diff --git a/include/toml++/impl/std_string.h b/include/toml++/impl/std_string.h index 8f4c6f04..a45e344a 100644 --- a/include/toml++/impl/std_string.h +++ b/include/toml++/impl/std_string.h @@ -10,7 +10,7 @@ TOML_DISABLE_WARNINGS; #include TOML_ENABLE_WARNINGS; -#if defined(DOXYGEN) \ +#if TOML_DOXYGEN \ || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \ && __cpp_lib_char8_t >= 201907) #define TOML_HAS_CHAR8 1 diff --git a/include/toml++/impl/table.h b/include/toml++/impl/table.h index 3811cff8..75f16cf8 100644 --- a/include/toml++/impl/table.h +++ b/include/toml++/impl/table.h @@ -1474,13 +1474,13 @@ TOML_NAMESPACE_START ipos->second = std::move(static_cast(args)...); else { -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS try { #endif ipos->second.reset( new impl::wrap_node{ static_cast(args)... }); -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS } catch (...) { diff --git a/include/toml++/impl/table.inl b/include/toml++/impl/table.inl index 7ac7ffc4..d7c9aa17 100644 --- a/include/toml++/impl/table.inl +++ b/include/toml++/impl/table.inl @@ -106,6 +106,7 @@ TOML_NAMESPACE_START return *this; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype) const noexcept { @@ -125,6 +126,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept { @@ -147,6 +149,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept { @@ -156,6 +159,7 @@ TOML_NAMESPACE_START return result; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE node* table::get(std::string_view key) noexcept { @@ -169,7 +173,7 @@ TOML_NAMESPACE_START { auto n = get(key); -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS if (!n) { @@ -188,18 +192,21 @@ TOML_NAMESPACE_START return *n; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::map_iterator table::get_lower_bound(std::string_view key) noexcept { return map_.lower_bound(key); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::iterator table::find(std::string_view key) noexcept { return iterator{ map_.find(key) }; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::const_iterator table::find(std::string_view key) const noexcept { @@ -277,6 +284,7 @@ TOML_NAMESPACE_START return map_.emplace_hint(const_map_iterator{ hint }, std::move(k), std::move(v)); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV table::equal(const table& lhs, const table& rhs) noexcept { diff --git a/include/toml++/impl/toml_formatter.h b/include/toml++/impl/toml_formatter.h index ad097c6e..5c81a5ef 100644 --- a/include/toml++/impl/toml_formatter.h +++ b/include/toml++/impl/toml_formatter.h @@ -99,7 +99,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) /// \brief Constructs a TOML formatter and binds it to a toml::parse_result. /// diff --git a/include/toml++/impl/unicode.inl b/include/toml++/impl/unicode.inl index 2fda84ed..8edc3c15 100644 --- a/include/toml++/impl/unicode.inl +++ b/include/toml++/impl/unicode.inl @@ -17,6 +17,7 @@ TOML_IMPL_NAMESPACE_START { + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool is_ascii(const char* str, size_t len) noexcept { diff --git a/include/toml++/impl/yaml_formatter.h b/include/toml++/impl/yaml_formatter.h index affb3f74..d9536de2 100644 --- a/include/toml++/impl/yaml_formatter.h +++ b/include/toml++/impl/yaml_formatter.h @@ -86,7 +86,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) /// \brief Constructs a YAML formatter and binds it to a toml::parse_result. /// diff --git a/include/toml++/toml.h b/include/toml++/toml.h index b7e7d816..30ca7e73 100644 --- a/include/toml++/toml.h +++ b/include/toml++/toml.h @@ -85,7 +85,7 @@ TOML_POP_WARNINGS; #undef TOML_ABI_NAMESPACE_END #undef TOML_ABI_NAMESPACE_START #undef TOML_ABI_NAMESPACES -#undef TOML_ABSTRACT_BASE +#undef TOML_ABSTRACT_INTERFACE #undef TOML_ALWAYS_INLINE #undef TOML_ANON_NAMESPACE #undef TOML_ANON_NAMESPACE_END @@ -99,11 +99,14 @@ TOML_POP_WARNINGS; #undef TOML_CLANG #undef TOML_CLOSED_ENUM #undef TOML_CLOSED_FLAGS_ENUM -#undef TOML_COMPILER_EXCEPTIONS +#undef TOML_COMPILER_HAS_EXCEPTIONS +#undef TOML_COMPILER_HAS_RTTI +#undef TOML_CONST #undef TOML_CONST_GETTER #undef TOML_CONST_INLINE_GETTER #undef TOML_CONSTRAINED_TEMPLATE -#undef TOML_CPP_VERSION +#undef TOML_CPP +#undef TOML_DECLSPEC #undef TOML_DELETE_DEFAULTS #undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS @@ -113,6 +116,7 @@ TOML_POP_WARNINGS; #undef TOML_DISABLE_SUGGEST_ATTR_WARNINGS #undef TOML_DISABLE_SWITCH_WARNINGS #undef TOML_DISABLE_WARNINGS +#undef TOML_DOXYGEN #undef TOML_EMPTY_BASES #undef TOML_ENABLE_IF #undef TOML_ENABLE_WARNINGS @@ -126,8 +130,11 @@ TOML_POP_WARNINGS; #undef TOML_FP16 #undef TOML_GCC #undef TOML_HAS_ATTR +#undef TOML_HAS_BUILTIN #undef TOML_HAS_CHAR8 +#undef TOML_HAS_CPP_ATTR #undef TOML_HAS_CUSTOM_OPTIONAL_TYPE +#undef TOML_HAS_FEATURE #undef TOML_HAS_INCLUDE #undef TOML_HAS_SSE2 #undef TOML_HAS_SSE4_1 @@ -152,6 +159,10 @@ TOML_POP_WARNINGS; #undef TOML_LIKELY_CASE #undef TOML_MAKE_FLAGS #undef TOML_MAKE_FLAGS_ +#undef TOML_MAKE_FLAGS_1 +#undef TOML_MAKE_FLAGS_2 +#undef TOML_MAKE_STRING +#undef TOML_MAKE_STRING_1 #undef TOML_MAKE_VERSION #undef TOML_MSVC #undef TOML_NAMESPACE @@ -162,6 +173,14 @@ TOML_POP_WARNINGS; #undef TOML_OPEN_FLAGS_ENUM #undef TOML_PARSER_TYPENAME #undef TOML_POP_WARNINGS +#undef TOML_PRAGMA_CLANG +#undef TOML_PRAGMA_CLANG_GE_10 +#undef TOML_PRAGMA_CLANG_GE_11 +#undef TOML_PRAGMA_CLANG_GE_9 +#undef TOML_PRAGMA_GCC +#undef TOML_PRAGMA_ICC +#undef TOML_PRAGMA_MSVC +#undef TOML_PURE #undef TOML_PURE_GETTER #undef TOML_PURE_INLINE_GETTER #undef TOML_PUSH_WARNINGS @@ -187,6 +206,7 @@ TOML_POP_WARNINGS; #undef TOML_UNLIKELY_CASE #undef TOML_UNREACHABLE #undef TOML_UNUSED +#undef TOML_WINDOWS #endif #endif // TOMLPLUSPLUS_H diff --git a/src/toml++/toml.cpp b/src/toml++/toml.cpp index f880eaac..a2d1d1f8 100644 --- a/src/toml++/toml.cpp +++ b/src/toml++/toml.cpp @@ -1,5 +1,8 @@ #ifndef TOML_IMPLEMENTATION #define TOML_IMPLEMENTATION #endif +#ifndef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 0 +#endif #include diff --git a/tests/conformance_burntsushi_invalid.cpp b/tests/conformance_burntsushi_invalid.cpp index 860b607c..e25086de 100644 --- a/tests/conformance_burntsushi_invalid.cpp +++ b/tests/conformance_burntsushi_invalid.cpp @@ -9,6 +9,14 @@ namespace { + static constexpr auto array_double_comma_1 = R"(array = [1,,2])"sv; + static constexpr auto array_double_comma_2 = R"(array = [1,2,,])"sv; + static constexpr auto array_extending_table = R"(a = [{ b = 1 }] + +# Cannot extend tables within static arrays +# https://github.com/toml-lang/toml/issues/908 +[a.c] +foo = 1)"sv; static constexpr auto array_missing_separator = R"(wrong = [ 1 2 3 ])"sv; static constexpr auto array_no_close_2 = R"(x = [42 #)"sv; static constexpr auto array_no_close_table_2 = R"(x = [{ key = 42 #)"sv; @@ -276,16 +284,21 @@ key""" = 1)"sv; static constexpr auto key_no_eol = R"(a = 1 b = 2)"sv; static constexpr auto key_open_bracket = R"([abc = 1)"sv; static constexpr auto key_partial_quoted = R"(partial"quoted" = 5)"sv; + static constexpr auto key_quoted_unclosed_1 = R"("key = x)"sv; + static constexpr auto key_quoted_unclosed_2 = R"("key)"sv; static constexpr auto key_single_open_bracket = R"([)"sv; static constexpr auto key_space = R"(a b = 1)"sv; static constexpr auto key_start_bracket = R"([a] [xyz = 5 [b])"sv; + static constexpr auto key_start_dot = R"(.key = 1)"sv; static constexpr auto key_two_equals = R"(key= = 1)"sv; static constexpr auto key_two_equals2 = R"(a==1)"sv; static constexpr auto key_two_equals3 = R"(a=b=1)"sv; static constexpr auto key_without_value_1 = R"(key)"sv; static constexpr auto key_without_value_2 = R"(key = )"sv; + static constexpr auto key_without_value_3 = R"("key")"sv; + static constexpr auto key_without_value_4 = R"("key" = )"sv; #if !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK @@ -303,7 +316,11 @@ key""" = 1)"sv; second line")"sv; static constexpr auto string_bad_slash_escape = R"(invalid-escape = "This string has a bad \/ escape character.")"sv; - static constexpr auto string_bad_uni_esc = R"(str = "val\ue")"sv; + static constexpr auto string_bad_uni_esc_1 = R"(str = "val\ue")"sv; + static constexpr auto string_bad_uni_esc_2 = R"(str = "val\Ux")"sv; + static constexpr auto string_bad_uni_esc_3 = R"(str = "val\U0000000")"sv; + static constexpr auto string_bad_uni_esc_4 = R"(str = "val\U0000")"sv; + static constexpr auto string_bad_uni_esc_5 = R"(str = "val\Ugggggggg")"sv; static constexpr auto string_basic_multiline_out_of_range_unicode_escape_1 = R"(a = """\UFFFFFFFF""")"sv; static constexpr auto string_basic_multiline_out_of_range_unicode_escape_2 = R"(a = """\U00D80000""")"sv; static constexpr auto string_basic_multiline_quotes = R"(str5 = """Here are three quotation marks: """.""")"sv; @@ -428,6 +445,12 @@ answer = 42)"sv; TEST_CASE("conformance - burntsushi/invalid") { + parsing_should_fail(FILE_LINE_ARGS, array_double_comma_1); // array-double-comma-1 + + parsing_should_fail(FILE_LINE_ARGS, array_double_comma_2); // array-double-comma-2 + + parsing_should_fail(FILE_LINE_ARGS, array_extending_table); // array-extending-table + parsing_should_fail(FILE_LINE_ARGS, array_missing_separator); // array-missing-separator parsing_should_fail(FILE_LINE_ARGS, array_no_close_2); // array-no-close-2 @@ -758,12 +781,18 @@ TEST_CASE("conformance - burntsushi/invalid") parsing_should_fail(FILE_LINE_ARGS, key_partial_quoted); // key-partial-quoted + parsing_should_fail(FILE_LINE_ARGS, key_quoted_unclosed_1); // key-quoted-unclosed-1 + + parsing_should_fail(FILE_LINE_ARGS, key_quoted_unclosed_2); // key-quoted-unclosed-2 + parsing_should_fail(FILE_LINE_ARGS, key_single_open_bracket); // key-single-open-bracket parsing_should_fail(FILE_LINE_ARGS, key_space); // key-space parsing_should_fail(FILE_LINE_ARGS, key_start_bracket); // key-start-bracket + parsing_should_fail(FILE_LINE_ARGS, key_start_dot); // key-start-dot + parsing_should_fail(FILE_LINE_ARGS, key_two_equals); // key-two-equals parsing_should_fail(FILE_LINE_ARGS, key_two_equals2); // key-two-equals2 @@ -774,6 +803,10 @@ TEST_CASE("conformance - burntsushi/invalid") parsing_should_fail(FILE_LINE_ARGS, key_without_value_2); // key-without-value-2 + parsing_should_fail(FILE_LINE_ARGS, key_without_value_3); // key-without-value-3 + + parsing_should_fail(FILE_LINE_ARGS, key_without_value_4); // key-without-value-4 + #if !TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK parsing_should_fail(FILE_LINE_ARGS, key_special_character); // key-special-character @@ -794,7 +827,15 @@ TEST_CASE("conformance - burntsushi/invalid") parsing_should_fail(FILE_LINE_ARGS, string_bad_slash_escape); // string-bad-slash-escape - parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc); // string-bad-uni-esc + parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_1); // string-bad-uni-esc-1 + + parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_2); // string-bad-uni-esc-2 + + parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_3); // string-bad-uni-esc-3 + + parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_4); // string-bad-uni-esc-4 + + parsing_should_fail(FILE_LINE_ARGS, string_bad_uni_esc_5); // string-bad-uni-esc-5 parsing_should_fail( FILE_LINE_ARGS, diff --git a/tests/conformance_burntsushi_valid.cpp b/tests/conformance_burntsushi_valid.cpp index 8ed91b67..31ee8b40 100644 --- a/tests/conformance_burntsushi_valid.cpp +++ b/tests/conformance_burntsushi_valid.cpp @@ -30,7 +30,14 @@ comments = [ static constexpr auto array_mixed_string_table = R"(contributors = [ "Foo Bar ", { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } -])"sv; +] + +# Start with a table as the first element. This tests a case that some libraries +# might have where they will check if the first entry is a table/map/hash/assoc +# array and then encode it as a table array. This was a reasonable thing to do +# before TOML 1.0 since arrays could only contain one type, but now it's no +# longer. +mixed = [{k="a"}, "b", 1])"sv; static constexpr auto array_nested_double = R"(nest = [ [ ["a"], @@ -361,8 +368,13 @@ plain = 3 [table.withdot] plain = 5 "key.with.dots" = 6)"sv; - static constexpr auto key_space = R"("a b" = 1)"sv; - static constexpr auto key_special_chars = R"("~!@$^&*()_+-`1234567890[]|/?><.,;:'" = 1)"sv; + static constexpr auto key_space = R"(# Keep whitespace inside quotes keys at all positions. +"a b" = 1 +" c d " = 2 + +[ " tbl " ] +"\ttab\ttab\t" = "tab")"sv; + static constexpr auto key_special_chars = R"("=~!@$^&*()_+-`1234567890[]|/?><.,;:'=" = 1)"sv; static constexpr auto key_special_word = R"(false = false true = 1 inf = 100000000 @@ -822,6 +834,14 @@ TEST_CASE("conformance - burntsushi/valid") { R"(url)"sv, R"(https://example.com/bazqux)"sv }, }, } }, + { R"(mixed)"sv, + toml::array{ + toml::table{ + { R"(k)"sv, R"(a)"sv }, + }, + R"(b)"sv, + 1, + } }, }; REQUIRE(tbl == expected); }); @@ -1949,6 +1969,11 @@ another line)"sv }, [](toml::table&& tbl) // key-space { const auto expected = toml::table{ + { R"( c d )"sv, 2 }, + { R"( tbl )"sv, + toml::table{ + { R"( tab tab )"sv, R"(tab)"sv }, + } }, { R"(a b)"sv, 1 }, }; REQUIRE(tbl == expected); @@ -1959,7 +1984,7 @@ another line)"sv }, [](toml::table&& tbl) // key-special-chars { const auto expected = toml::table{ - { R"(~!@$^&*()_+-`1234567890[]|/?><.,;:')"sv, 1 }, + { R"(=~!@$^&*()_+-`1234567890[]|/?><.,;:'=)"sv, 1 }, }; REQUIRE(tbl == expected); }); diff --git a/tests/path.cpp b/tests/path.cpp index 3cbfd156..f57d2ed3 100644 --- a/tests/path.cpp +++ b/tests/path.cpp @@ -581,5 +581,4 @@ TEST_CASE("path - accessing") CHECK(tbl["d"][""]); CHECK(tbl["d"][""] == tbl[toml::path("d.")]); } - } diff --git a/tests/tests.h b/tests/tests.h index cb85c931..b4f6a66e 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -26,11 +26,11 @@ #if defined(TOML_INT128) ^ defined(TOML_UINT128) #error TOML_INT128 and TOML_UINT128 must both be defined, or neither be defined #endif -#if TOML_COMPILER_EXCEPTIONS ^ SHOULD_HAVE_EXCEPTIONS -#error TOML_COMPILER_EXCEPTIONS was not deduced correctly +#if TOML_COMPILER_HAS_EXCEPTIONS ^ SHOULD_HAVE_EXCEPTIONS +#error TOML_COMPILER_HAS_EXCEPTIONS was not deduced correctly #endif -#if TOML_COMPILER_EXCEPTIONS ^ TOML_EXCEPTIONS -#error TOML_EXCEPTIONS does not match TOML_COMPILER_EXCEPTIONS (default behaviour should be to match) +#if TOML_COMPILER_HAS_EXCEPTIONS ^ TOML_EXCEPTIONS +#error TOML_EXCEPTIONS does not match TOML_COMPILER_HAS_EXCEPTIONS (default behaviour should be to match) #endif #if defined(_WIN32) ^ TOML_ENABLE_WINDOWS_COMPAT #error TOML_ENABLE_WINDOWS_COMPAT does not match _WIN32 (default behaviour should be to match) diff --git a/toml.hpp b/toml.hpp index 91ba791e..6ce0b3d0 100644 --- a/toml.hpp +++ b/toml.hpp @@ -48,780 +48,852 @@ //******** impl/preprocessor.h *************************************************************************************** -// clang-format off - #ifndef __cplusplus - #error toml++ is a C++ library. +#error toml++ is a C++ library. #endif - -#ifdef __INTELLISENSE__ - #define TOML_INTELLISENSE 1 +#ifdef _MSVC_LANG +#define TOML_CPP _MSVC_LANG #else - #define TOML_INTELLISENSE 0 +#define TOML_CPP __cplusplus +#endif +#if TOML_CPP >= 202002L +#undef TOML_CPP +#define TOML_CPP 20 +#elif TOML_CPP >= 201703L +#undef TOML_CPP +#define TOML_CPP 17 +#else +#if TOML_CPP < 201103L +#error toml++ requires C++17 or higher. For a pre-C++11 TOML library see https://github.com/ToruNiina/Boost.toml +#elif TOML_CPP < 201703L +#error toml++ requires C++17 or higher. For a C++11 TOML library see https://github.com/ToruNiina/toml11 +#endif #endif + #ifdef __clang__ - #define TOML_CLANG __clang_major__ +#define TOML_CLANG __clang_major__ #else - #define TOML_CLANG 0 +#define TOML_CLANG 0 #endif #ifdef __INTEL_COMPILER - #define TOML_ICC __INTEL_COMPILER - #ifdef __ICL - #define TOML_ICC_CL TOML_ICC - #else - #define TOML_ICC_CL 0 - #endif +#define TOML_ICC __INTEL_COMPILER +#ifdef __ICL +#define TOML_ICC_CL TOML_ICC +#else +#define TOML_ICC_CL 0 +#endif #else - #define TOML_ICC 0 - #define TOML_ICC_CL 0 +#define TOML_ICC 0 +#define TOML_ICC_CL 0 #endif #if defined(_MSC_VER) && !TOML_CLANG && !TOML_ICC - #define TOML_MSVC _MSC_VER +#define TOML_MSVC _MSC_VER #else - #define TOML_MSVC 0 +#define TOML_MSVC 0 #endif #if defined(__GNUC__) && !TOML_CLANG && !TOML_ICC - #define TOML_GCC __GNUC__ +#define TOML_GCC __GNUC__ +#else +#define TOML_GCC 0 +#endif +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) +#define TOML_WINDOWS 1 +#else +#define TOML_WINDOWS 0 +#endif +#if defined(DOXYGEN) || defined(__DOXYGEN__) || defined(__POXY__) || defined(__poxy__) +#define TOML_DOXYGEN 1 #else - #define TOML_GCC 0 +#define TOML_DOXYGEN 0 +#endif +#ifdef __INTELLISENSE__ +#define TOML_INTELLISENSE 1 +#else +#define TOML_INTELLISENSE 0 +#endif +#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ + || defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) +#define TOML_ARM 1 +#else +#define TOML_ARM 0 #endif +// TOML_HAS_INCLUDE #ifdef __has_include - #define TOML_HAS_INCLUDE(header) __has_include(header) +#define TOML_HAS_INCLUDE(header) __has_include(header) #else - #define TOML_HAS_INCLUDE(header) 0 +#define TOML_HAS_INCLUDE(header) 0 #endif +#ifdef __has_builtin +#define TOML_HAS_BUILTIN(name) __has_builtin(name) +#else +#define TOML_HAS_BUILTIN(name) 0 +#endif + +// TOML_HAS_FEATURE +#ifdef __has_feature +#define TOML_HAS_FEATURE(name) __has_feature(name) +#else +#define TOML_HAS_FEATURE(name) 0 +#endif + +// TOML_HAS_ATTR +#ifdef __has_attribute +#define TOML_HAS_ATTR(attr) __has_attribute(attr) +#else +#define TOML_HAS_ATTR(attr) 0 +#endif + +// TOML_HAS_CPP_ATTR +#ifdef __has_cpp_attribute +#define TOML_HAS_CPP_ATTR(attr) __has_cpp_attribute(attr) +#else +#define TOML_HAS_CPP_ATTR(attr) 0 +#endif + +// TOML_COMPILER_HAS_EXCEPTIONS +#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) || defined(__cpp_exceptions) +#define TOML_COMPILER_HAS_EXCEPTIONS 1 +#else +#define TOML_COMPILER_HAS_EXCEPTIONS 0 +#endif + +// TOML_COMPILER_HAS_RTTI +#if defined(_CPPRTTI) || defined(__GXX_RTTI) || TOML_HAS_FEATURE(cxx_rtti) +#define TOML_COMPILER_HAS_RTTI 1 +#else +#define TOML_COMPILER_HAS_RTTI 0 +#endif + +// TOML_ATTR (gnu attributes) +#if TOML_CLANG || TOML_GCC || defined(__GNUC__) +#define TOML_ATTR(...) __attribute__((__VA_ARGS__)) +#else +#define TOML_ATTR(...) +#endif + +// TOML_DECLSPEC (msvc attributes) +#ifdef _MSC_VER +#define TOML_DECLSPEC(...) __declspec(__VA_ARGS__) +#else +#define TOML_DECLSPEC(...) +#endif + +// TOML_CONCAT +#define TOML_CONCAT_1(x, y) x##y +#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) + +// TOML_MAKE_STRING +#define TOML_MAKE_STRING_1(s) #s +#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s) + +// TOML_PRAGMA_XXXX (compiler-specific pragmas) #if TOML_CLANG +#define TOML_PRAGMA_CLANG(decl) _Pragma(TOML_MAKE_STRING(clang decl)) +#else +#define TOML_PRAGMA_CLANG(decl) +#endif +#if TOML_CLANG >= 9 +#define TOML_PRAGMA_CLANG_GE_9(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_9(decl) +#endif +#if TOML_CLANG >= 10 +#define TOML_PRAGMA_CLANG_GE_10(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_10(decl) +#endif +#if TOML_CLANG >= 11 +#define TOML_PRAGMA_CLANG_GE_11(decl) TOML_PRAGMA_CLANG(decl) +#else +#define TOML_PRAGMA_CLANG_GE_11(decl) +#endif +#if TOML_GCC +#define TOML_PRAGMA_GCC(decl) _Pragma(TOML_MAKE_STRING(GCC decl)) +#else +#define TOML_PRAGMA_GCC(decl) +#endif +#if TOML_MSVC +#define TOML_PRAGMA_MSVC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_MSVC(...) +#endif +#if TOML_ICC +#define TOML_PRAGMA_ICC(...) __pragma(__VA_ARGS__) +#else +#define TOML_PRAGMA_ICC(...) +#endif - #define TOML_PUSH_WARNINGS \ - _Pragma("clang diagnostic push") \ - static_assert(true) +// TOML_ALWAYS_INLINE +#ifdef _MSC_VER +#define TOML_ALWAYS_INLINE __forceinline +#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__always_inline__) +#define TOML_ALWAYS_INLINE \ + TOML_ATTR(__always_inline__) \ + inline +#else +#define TOML_ALWAYS_INLINE inline +#endif - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wswitch\"") \ - static_assert(true) +// TOML_NEVER_INLINE +#ifdef _MSC_VER +#define TOML_NEVER_INLINE TOML_DECLSPEC(noinline) +#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__noinline__) +#define TOML_NEVER_INLINE TOML_ATTR(__noinline__) +#else +#define TOML_NEVER_INLINE +#endif - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \ - static_assert(true) +// MSVC attributes +#define TOML_ABSTRACT_INTERFACE TOML_DECLSPEC(novtable) +#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases) - #if TOML_CLANG >= 10 - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 \ - _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") \ - static_assert(true) - #else - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_10 static_assert(true) - #endif +// TOML_TRIVIAL_ABI +#if TOML_CLANG || TOML_HAS_ATTR(__trivial_abi__) +#define TOML_TRIVIAL_ABI TOML_ATTR(__trivial_abi__) +#else +#define TOML_TRIVIAL_ABI +#endif - #if TOML_CLANG >= 11 - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_11 \ - _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \ - static_assert(true) - #else - #define TOML_DISABLE_SPAM_WARNINGS_CLANG_11 static_assert(true) - #endif +// TOML_NODISCARD +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201603 +#define TOML_NODISCARD [[nodiscard]] +#elif TOML_CLANG || TOML_GCC || TOML_HAS_ATTR(__warn_unused_result__) +#define TOML_NODISCARD TOML_ATTR(__warn_unused_result__) +#else +#define TOML_NODISCARD +#endif - #define TOML_DISABLE_SPAM_WARNINGS \ - TOML_DISABLE_SPAM_WARNINGS_CLANG_10; \ - TOML_DISABLE_SPAM_WARNINGS_CLANG_11; \ - _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wweak-template-vtables\"") \ - _Pragma("clang diagnostic ignored \"-Wdouble-promotion\"") \ - _Pragma("clang diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("clang diagnostic ignored \"-Wpadded\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("clang diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("clang diagnostic ignored \"-Weverything\"") \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS - - #define TOML_ASSUME(expr) __builtin_assume(expr) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #if defined(_MSC_VER) // msvc compat mode - #ifdef __has_declspec_attribute - #if __has_declspec_attribute(novtable) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #endif - #if __has_declspec_attribute(empty_bases) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #if __has_declspec_attribute(noinline) - #define TOML_NEVER_INLINE __declspec(noinline) - #endif - #endif - #endif - #ifdef __has_attribute - #if !defined(TOML_ALWAYS_INLINE) && __has_attribute(always_inline) - #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline - #endif - #if !defined(TOML_NEVER_INLINE) && __has_attribute(noinline) - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #endif - #if !defined(TOML_TRIVIAL_ABI) && __has_attribute(trivial_abi) - #define TOML_TRIVIAL_ABI __attribute__((__trivial_abi__)) - #endif - #if !defined(TOML_FLAGS_ENUM) && __has_attribute(flag_enum) - #define TOML_FLAGS_ENUM __attribute__((__flag_enum__)) - #endif - #if __has_attribute(enum_extensibility) - #ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) - #endif - #ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) - #endif - #endif - #endif - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) +// TOML_NODISCARD_CTOR +#if TOML_CPP >= 17 && TOML_HAS_CPP_ATTR(nodiscard) >= 201907 +#define TOML_NODISCARD_CTOR [[nodiscard]] +#else +#define TOML_NODISCARD_CTOR +#endif - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 +// pure + const +// clang-format off +#ifdef NDEBUG + #define TOML_PURE TOML_DECLSPEC(noalias) TOML_ATTR(__pure__) + #define TOML_CONST TOML_DECLSPEC(noalias) TOML_ATTR(__const__) + #define TOML_PURE_GETTER TOML_NODISCARD TOML_PURE + #define TOML_CONST_GETTER TOML_NODISCARD TOML_CONST + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_PURE + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_CONST +#else + #define TOML_PURE + #define TOML_CONST + #define TOML_PURE_GETTER TOML_NODISCARD + #define TOML_CONST_GETTER TOML_NODISCARD + #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE + #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#endif +// clang-format on -#endif // clang +// TOML_ASSUME +#ifdef _MSC_VER +#define TOML_ASSUME(...) __assume(__VA_ARGS__) +#elif TOML_ICC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_assume) +#define TOML_ASSUME(...) __builtin_assume(__VA_ARGS__) +#else +#define TOML_ASSUME(...) static_assert(true) +#endif -#if TOML_MSVC || TOML_ICC_CL +// TOML_UNREACHABLE +#ifdef _MSC_VER +#define TOML_UNREACHABLE __assume(0) +#elif TOML_ICC || TOML_CLANG || TOML_GCC || TOML_HAS_BUILTIN(__builtin_unreachable) +#define TOML_UNREACHABLE __builtin_unreachable() +#else +#define TOML_UNREACHABLE static_assert(true) +#endif - #define TOML_CPP_VERSION _MSVC_LANG - #if TOML_MSVC // !intel-cl +// TOML_LIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(likely) >= 201803 +#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] +#define TOML_LIKELY_CASE [[likely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1)) +#else +#define TOML_LIKELY(...) (__VA_ARGS__) +#endif +#ifndef TOML_LIKELY_CASE +#define TOML_LIKELY_CASE +#endif - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) +// TOML_UNLIKELY +#if TOML_CPP >= 20 && TOML_HAS_CPP_ATTR(unlikely) >= 201803 +#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] +#define TOML_UNLIKELY_CASE [[unlikely]] +#elif TOML_GCC || TOML_CLANG || TOML_HAS_BUILTIN(__builtin_expect) +#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0)) +#else +#define TOML_UNLIKELY(...) (__VA_ARGS__) +#endif +#ifndef TOML_UNLIKELY_CASE +#define TOML_UNLIKELY_CASE +#endif - #if TOML_HAS_INCLUDE() - #pragma warning(push, 0) - #include - #pragma warning(pop) - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ - __pragma(warning(disable: ALL_CODE_ANALYSIS_WARNINGS)) \ - static_assert(true) - #else - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS - static_assert(true) - #endif +// TOML_FLAGS_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(flag_enum) +#define TOML_FLAGS_ENUM __attribute__((flag_enum)) +#else +#define TOML_FLAGS_ENUM +#endif - #define TOML_DISABLE_SWITCH_WARNINGS \ - __pragma(warning(disable: 4061)) /* enumerator 'identifier' is not explicitly handled by a case label */ \ - __pragma(warning(disable: 4062)) /* enumerator 'identifier' is not handled */ \ - __pragma(warning(disable: 4063)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 4127)) /* conditional expr is constant */ \ - __pragma(warning(disable: 4324)) /* structure was padded due to alignment specifier */ \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4464)) /* relative include path contains '..' */ \ - __pragma(warning(disable: 4505)) /* unreferenced local function removed */ \ - __pragma(warning(disable: 4514)) /* unreferenced inline function has been removed */ \ - __pragma(warning(disable: 4582)) /* constructor is not implicitly called */ \ - __pragma(warning(disable: 4623)) /* default constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4625)) /* copy constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 4626)) /* assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 4710)) /* function not inlined */ \ - __pragma(warning(disable: 4711)) /* function selected for automatic expansion */ \ - __pragma(warning(disable: 4820)) /* N bytes padding added */ \ - __pragma(warning(disable: 4946)) /* reinterpret_cast used between related classes */ \ - __pragma(warning(disable: 5026)) /* move constructor was implicitly defined as deleted */ \ - __pragma(warning(disable: 5027)) /* move assignment operator was implicitly defined as deleted */ \ - __pragma(warning(disable: 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ - __pragma(warning(disable: 5045)) /* Compiler will insert Spectre mitigation */ \ - __pragma(warning(disable: 26451)) \ - __pragma(warning(disable: 26490)) \ - __pragma(warning(disable: 26495)) \ - __pragma(warning(disable: 26812)) \ - __pragma(warning(disable: 26819)) \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - __pragma(warning(disable: 4365)) /* argument signed/unsigned mismatch */ \ - __pragma(warning(disable: 4738)) /* storing 32-bit float result in memory */ \ - __pragma(warning(disable: 5219)) /* implicit conversion from integral to float */ \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - __pragma(warning(disable: 4348)) \ - __pragma(warning(disable: 4668)) \ - __pragma(warning(disable: 5105)) \ - TOML_DISABLE_CODE_ANALYSIS_WARNINGS;\ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS +// TOML_OPEN_ENUM + TOML_CLOSED_ENUM +#if TOML_CLANG || TOML_HAS_ATTR(enum_extensibility) +#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open))) +#define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed))) +#else +#define TOML_OPEN_ENUM +#define TOML_CLOSED_ENUM +#endif - #endif - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __forceinline - #endif - #define TOML_NEVER_INLINE __declspec(noinline) - #define TOML_ASSUME(expr) __assume(expr) - #define TOML_UNREACHABLE __assume(0) - #define TOML_ABSTRACT_BASE __declspec(novtable) - #define TOML_EMPTY_BASES __declspec(empty_bases) - #ifdef _CPPUNWIND - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif +// TOML_OPEN_FLAGS_ENUM + TOML_CLOSED_FLAGS_ENUM +#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +#define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM -#endif // msvc +// TOML_MAKE_FLAGS +#define TOML_MAKE_FLAGS_2(T, op, linkage) \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator op(T lhs, T rhs) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(static_cast(lhs) op static_cast(rhs)); \ + } \ + \ + linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept \ + { \ + return lhs = (lhs op rhs); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS_1(T, linkage) \ + static_assert(std::is_enum_v); \ + \ + TOML_MAKE_FLAGS_2(T, &, linkage); \ + TOML_MAKE_FLAGS_2(T, |, linkage); \ + TOML_MAKE_FLAGS_2(T, ^, linkage); \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr T operator~(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return static_cast(~static_cast(val)); \ + } \ + \ + TOML_CONST_INLINE_GETTER \ + linkage constexpr bool operator!(T val) noexcept \ + { \ + using under = std::underlying_type_t; \ + return !static_cast(val); \ + } \ + \ + static_assert(true) +#define TOML_MAKE_FLAGS(T) TOML_MAKE_FLAGS_1(T, ) -#if TOML_ICC +#define TOML_UNUSED(...) static_cast(__VA_ARGS__) - #define TOML_PUSH_WARNINGS \ - __pragma(warning(push)) \ - static_assert(true) +#define TOML_DELETE_DEFAULTS(T) \ + T(const T&) = delete; \ + T(T&&) = delete; \ + T& operator=(const T&) = delete; \ + T& operator=(T&&) = delete - #define TOML_DISABLE_SPAM_WARNINGS \ - __pragma(warning(disable: 82)) /* storage class is not first */ \ - __pragma(warning(disable: 111)) /* statement unreachable (false-positive) */ \ - __pragma(warning(disable: 869)) /* unreferenced parameter */ \ - __pragma(warning(disable: 1011)) /* missing return (false-positive) */ \ - __pragma(warning(disable: 2261)) /* assume expr side-effects discarded */ \ - static_assert(true) +#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator==(RHS rhs, LHS lhs) noexcept \ + { \ + return lhs == rhs; \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(LHS lhs, RHS rhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + __VA_ARGS__ TOML_NODISCARD \ + friend bool operator!=(RHS rhs, LHS lhs) noexcept \ + { \ + return !(lhs == rhs); \ + } \ + static_assert(true) - #define TOML_POP_WARNINGS \ - __pragma(warning(pop)) \ - static_assert(true) +#define TOML_EVAL_BOOL_1(T, F) T +#define TOML_EVAL_BOOL_0(T, F) F - #define TOML_DISABLE_WARNINGS \ - __pragma(warning(push, 0)) \ - static_assert(true) +#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) +#define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ +#endif - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS +// COMPILER-SPECIFIC WARNING MANAGEMENT -#endif // icc +#if TOML_CLANG -#if TOML_GCC +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + static_assert(true) - #define TOML_PUSH_WARNINGS \ - _Pragma("GCC diagnostic push") \ - static_assert(true) - - #define TOML_DISABLE_SWITCH_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wswitch\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-enum\"") \ - _Pragma("GCC diagnostic ignored \"-Wswitch-default\"") \ - static_assert(true) - - #define TOML_DISABLE_ARITHMETIC_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") \ - _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ - static_assert(true) - - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \ - _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \ - static_assert(true) - - #define TOML_DISABLE_SPAM_WARNINGS \ - _Pragma("GCC diagnostic ignored \"-Wpadded\"") \ - _Pragma("GCC diagnostic ignored \"-Wcast-align\"") \ - _Pragma("GCC diagnostic ignored \"-Wcomment\"") \ - _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \ - _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"") \ - _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \ - _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ - _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ - _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ - _Pragma("GCC diagnostic ignored \"-Wnoexcept\"") \ - static_assert(true) - - #define TOML_POP_WARNINGS \ - _Pragma("GCC diagnostic pop") \ - static_assert(true) - - #define TOML_DISABLE_WARNINGS \ - TOML_PUSH_WARNINGS; \ - _Pragma("GCC diagnostic ignored \"-Wall\"") \ - _Pragma("GCC diagnostic ignored \"-Wextra\"") \ - _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \ - TOML_DISABLE_SWITCH_WARNINGS; \ - TOML_DISABLE_ARITHMETIC_WARNINGS; \ - TOML_DISABLE_SPAM_WARNINGS; \ - TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ - static_assert(true) - - #define TOML_ENABLE_WARNINGS \ - TOML_POP_WARNINGS - - #define TOML_ATTR(...) __attribute__((__VA_ARGS__)) - #ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline - #endif - #define TOML_NEVER_INLINE __attribute__((__noinline__)) - #define TOML_UNREACHABLE __builtin_unreachable() - #define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) ) - #define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) ) +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \ + TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \ + TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic push) \ + TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \ + static_assert(true, "") + +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_CLANG(diagnostic pop) \ + static_assert(true) + +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1 + +#elif TOML_MSVC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#if TOML_HAS_INCLUDE() +#pragma warning(push, 0) +#include +#pragma warning(pop) +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \ + __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) \ + static_assert(true) +#else +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) +#endif + +#define TOML_DISABLE_SWITCH_WARNINGS \ + __pragma(warning(disable : 4061)) \ + __pragma(warning(disable : 4062)) \ + __pragma(warning(disable : 4063)) \ + __pragma(warning(disable : 26819)) /* cg: unannotated fallthrough */ \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 4127)) /* conditional expr is constant */ \ + __pragma(warning(disable : 4324)) /* structure was padded due to alignment specifier */ \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4464)) /* relative include path contains '..' */ \ + __pragma(warning(disable : 4505)) /* unreferenced local function removed */ \ + __pragma(warning(disable : 4514)) /* unreferenced inline function has been removed */ \ + __pragma(warning(disable : 4582)) /* constructor is not implicitly called */ \ + __pragma(warning(disable : 4623)) /* default constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4625)) /* copy constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 4626)) /* assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 4710)) /* function not inlined */ \ + __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \ + __pragma(warning(disable : 4820)) /* N bytes padding added */ \ + __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \ + __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \ + __pragma(warning(disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \ + __pragma(warning(disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \ + __pragma(warning(disable : 5045)) /* Compiler will insert Spectre mitigation */ \ + __pragma(warning(disable : 26451)) \ + __pragma(warning(disable : 26490)) \ + __pragma(warning(disable : 26495)) \ + __pragma(warning(disable : 26812)) \ + __pragma(warning(disable : 26819)) \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + __pragma(warning(disable : 4365)) /* argument signed/unsigned mismatch */ \ + __pragma(warning(disable : 4738)) /* storing 32-bit float result in memory */ \ + __pragma(warning(disable : 5219)) /* implicit conversion from integral to float */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + __pragma(warning(disable : 4348)) \ + __pragma(warning(disable : 4668)) \ + __pragma(warning(disable : 5105)) \ + TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS + +#elif TOML_ICC + +#define TOML_PUSH_WARNINGS \ + __pragma(warning(push)) \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + __pragma(warning(disable : 82)) /* storage class is not first */ \ + __pragma(warning(disable : 111)) /* statement unreachable (false-positive) */ \ + __pragma(warning(disable : 869)) /* unreferenced parameter */ \ + __pragma(warning(disable : 1011)) /* missing return (false-positive) */ \ + __pragma(warning(disable : 2261)) /* assume expr side-effects discarded */ \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + __pragma(warning(push, 0)) \ + TOML_DISABLE_SPAM_WARNINGS + +#define TOML_ENABLE_WARNINGS \ + __pragma(warning(pop)) \ + static_assert(true) + +#elif TOML_GCC + +#define TOML_PUSH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + static_assert(true) + +#define TOML_DISABLE_SWITCH_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \ + static_assert(true) + +#define TOML_DISABLE_ARITHMETIC_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + static_assert(true) + +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \ + static_assert(true) + +#define TOML_DISABLE_SPAM_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \ + static_assert(true) + +#define TOML_POP_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) + +#define TOML_DISABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic push) \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \ + TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \ + TOML_DISABLE_SWITCH_WARNINGS; \ + TOML_DISABLE_ARITHMETIC_WARNINGS; \ + TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \ + TOML_DISABLE_SPAM_WARNINGS; \ + static_assert(true) + +#define TOML_ENABLE_WARNINGS \ + TOML_PRAGMA_GCC(diagnostic pop) \ + static_assert(true) #endif -#ifndef TOML_CPP_VERSION - #define TOML_CPP_VERSION __cplusplus +#ifndef TOML_PUSH_WARNINGS +#define TOML_PUSH_WARNINGS static_assert(true) #endif -#if TOML_CPP_VERSION < 201103L - #error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml -#elif TOML_CPP_VERSION < 201703L - #error toml++ requires C++17 or higher. For a TOML library supporting C++11 see https://github.com/ToruNiina/toml11 +#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS +#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SWITCH_WARNINGS +#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS +#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_SPAM_WARNINGS +#define TOML_DISABLE_SPAM_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS +#define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) +#endif +#ifndef TOML_POP_WARNINGS +#define TOML_POP_WARNINGS static_assert(true) +#endif +#ifndef TOML_DISABLE_WARNINGS +#define TOML_DISABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_ENABLE_WARNINGS +#define TOML_ENABLE_WARNINGS static_assert(true) +#endif +#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES +#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 #endif #ifdef TOML_CONFIG_HEADER - #include TOML_CONFIG_HEADER +#include TOML_CONFIG_HEADER #endif // is the library being built as a shared lib/dll using meson and friends? #ifndef TOML_SHARED_LIB - #define TOML_SHARED_LIB 0 +#define TOML_SHARED_LIB 0 #endif // header-only mode #if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0 - #define TOML_HEADER_ONLY TOML_ALL_INLINE +#define TOML_HEADER_ONLY TOML_ALL_INLINE #endif #if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 1 +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 1 #endif -#if defined(DOXYGEN) || TOML_SHARED_LIB - #undef TOML_HEADER_ONLY - #define TOML_HEADER_ONLY 0 +#if TOML_DOXYGEN || TOML_SHARED_LIB +#undef TOML_HEADER_ONLY +#define TOML_HEADER_ONLY 0 #endif // internal implementation switch #if defined(TOML_IMPLEMENTATION) || TOML_HEADER_ONLY - #undef TOML_IMPLEMENTATION - #define TOML_IMPLEMENTATION 1 +#undef TOML_IMPLEMENTATION +#define TOML_IMPLEMENTATION 1 #else - #define TOML_IMPLEMENTATION 0 +#define TOML_IMPLEMENTATION 0 #endif // dll/shared lib function exports (legacy - TOML_API was the old name for this setting) -#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) \ - && !defined(TOML_EXPORTED_STATIC_FUNCTION) \ - && !defined(TOML_EXPORTED_FREE_FUNCTION) \ - && !defined(TOML_EXPORTED_CLASS) \ - && defined(TOML_API) - #define TOML_EXPORTED_MEMBER_FUNCTION TOML_API - #define TOML_EXPORTED_STATIC_FUNCTION TOML_API - #define TOML_EXPORTED_FREE_FUNCTION TOML_API +#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) \ + && !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API) +#define TOML_EXPORTED_MEMBER_FUNCTION TOML_API +#define TOML_EXPORTED_STATIC_FUNCTION TOML_API +#define TOML_EXPORTED_FREE_FUNCTION TOML_API #endif // dll/shared lib exports #if TOML_SHARED_LIB - #undef TOML_API - #undef TOML_EXPORTED_CLASS - #undef TOML_EXPORTED_MEMBER_FUNCTION - #undef TOML_EXPORTED_STATIC_FUNCTION - #undef TOML_EXPORTED_FREE_FUNCTION - #if defined(_WIN32) || defined(__CYGWIN__) - #if TOML_IMPLEMENTATION - #define TOML_EXPORTED_CLASS __declspec(dllexport) - #define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport) - #else - #define TOML_EXPORTED_CLASS __declspec(dllimport) - #define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport) - #endif - #ifndef TOML_CALLCONV - #define TOML_CALLCONV __cdecl - #endif - #elif defined(__GNUC__) && __GNUC__ >= 4 - #define TOML_EXPORTED_CLASS __attribute__((visibility("default"))) - #define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default"))) - #define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default"))) - #define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default"))) - #endif +#undef TOML_API +#undef TOML_EXPORTED_CLASS +#undef TOML_EXPORTED_MEMBER_FUNCTION +#undef TOML_EXPORTED_STATIC_FUNCTION +#undef TOML_EXPORTED_FREE_FUNCTION +#if TOML_WINDOWS +#if TOML_IMPLEMENTATION +#define TOML_EXPORTED_CLASS __declspec(dllexport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport) +#else +#define TOML_EXPORTED_CLASS __declspec(dllimport) +#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport) +#endif +#ifndef TOML_CALLCONV +#define TOML_CALLCONV __cdecl +#endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define TOML_EXPORTED_CLASS __attribute__((visibility("default"))) +#define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default"))) +#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default"))) +#endif #endif #ifndef TOML_EXPORTED_CLASS - #define TOML_EXPORTED_CLASS +#define TOML_EXPORTED_CLASS #endif #ifndef TOML_EXPORTED_MEMBER_FUNCTION - #define TOML_EXPORTED_MEMBER_FUNCTION +#define TOML_EXPORTED_MEMBER_FUNCTION #endif #ifndef TOML_EXPORTED_STATIC_FUNCTION - #define TOML_EXPORTED_STATIC_FUNCTION +#define TOML_EXPORTED_STATIC_FUNCTION #endif #ifndef TOML_EXPORTED_FREE_FUNCTION - #define TOML_EXPORTED_FREE_FUNCTION +#define TOML_EXPORTED_FREE_FUNCTION #endif // experimental language features -#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES pre-3.0 - #define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES +#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES + // pre-3.0 +#define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES #endif #if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE - #undef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 1 +#undef TOML_ENABLE_UNRELEASED_FEATURES +#define TOML_ENABLE_UNRELEASED_FEATURES 1 #endif #ifndef TOML_ENABLE_UNRELEASED_FEATURES - #define TOML_ENABLE_UNRELEASED_FEATURES 0 +#define TOML_ENABLE_UNRELEASED_FEATURES 0 #endif // parser #if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0 - #define TOML_ENABLE_PARSER TOML_PARSER +#define TOML_ENABLE_PARSER TOML_PARSER #endif #if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE - #undef TOML_ENABLE_PARSER - #define TOML_ENABLE_PARSER 1 +#undef TOML_ENABLE_PARSER +#define TOML_ENABLE_PARSER 1 #endif // formatters -#if !defined(TOML_ENABLE_FORMATTERS) \ - || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_FORMATTERS - #define TOML_ENABLE_FORMATTERS 1 +#if !defined(TOML_ENABLE_FORMATTERS) || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE +#undef TOML_ENABLE_FORMATTERS +#define TOML_ENABLE_FORMATTERS 1 #endif // SIMD -#if !defined(TOML_ENABLE_SIMD) \ - || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_SIMD - #define TOML_ENABLE_SIMD 1 +#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || TOML_INTELLISENSE +#undef TOML_ENABLE_SIMD +#define TOML_ENABLE_SIMD 1 #endif // windows compat #if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0 - #define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT #endif -#if !defined(TOML_ENABLE_WINDOWS_COMPAT) \ - || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ - || TOML_INTELLISENSE - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 1 +#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \ + || TOML_INTELLISENSE +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 1 #endif -#ifndef _WIN32 - #undef TOML_ENABLE_WINDOWS_COMPAT - #define TOML_ENABLE_WINDOWS_COMPAT 0 +#if !TOML_WINDOWS +#undef TOML_ENABLE_WINDOWS_COMPAT +#define TOML_ENABLE_WINDOWS_COMPAT 0 #endif #ifndef TOML_INCLUDE_WINDOWS_H - #define TOML_INCLUDE_WINDOWS_H 0 +#define TOML_INCLUDE_WINDOWS_H 0 #endif // custom optional #ifdef TOML_OPTIONAL_TYPE - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1 #else - #define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 -#endif - -// exceptions (compiler support) -#ifndef TOML_COMPILER_EXCEPTIONS - #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) - #define TOML_COMPILER_EXCEPTIONS 1 - #else - #define TOML_COMPILER_EXCEPTIONS 0 - #endif +#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0 #endif // exceptions (library use) -#if TOML_COMPILER_EXCEPTIONS - #if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) - #undef TOML_EXCEPTIONS - #define TOML_EXCEPTIONS 1 - #endif +#if TOML_COMPILER_HAS_EXCEPTIONS +#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS) +#undef TOML_EXCEPTIONS +#define TOML_EXCEPTIONS 1 +#endif #else - #if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS - #error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler. - #endif - #undef TOML_EXCEPTIONS - #define TOML_EXCEPTIONS 0 +#if defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS +#error TOML_EXCEPTIONS was explicitly enabled but exceptions are disabled/unsupported by the compiler. +#endif +#undef TOML_EXCEPTIONS +#define TOML_EXCEPTIONS 0 #endif // calling convention for static/free/friend functions #ifndef TOML_CALLCONV - #define TOML_CALLCONV +#define TOML_CALLCONV #endif #ifndef TOML_UNDEF_MACROS - #define TOML_UNDEF_MACROS 1 +#define TOML_UNDEF_MACROS 1 #endif #ifndef TOML_MAX_NESTED_VALUES - #define TOML_MAX_NESTED_VALUES 256 - // this refers to the depth of nested values, e.g. inline tables and arrays. - // 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... +#define TOML_MAX_NESTED_VALUES 256 +// this refers to the depth of nested values, e.g. inline tables and arrays. +// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job... #endif #ifdef TOML_CHAR_8_STRINGS - #if TOML_CHAR_8_STRINGS - #error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. - #endif -#endif - -#ifdef TOML_LARGE_FILES - #if !TOML_LARGE_FILES - #error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. - #endif -#endif - -#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) - // not supported by any version of GCC or Clang as of 26/11/2020 - // not supported by any version of ICC on Linux as of 11/01/2021 - #define TOML_FLOAT_CHARCONV 0 -#endif -#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) - // causes link errors on emscripten - // causes Mac OS SDK version errors on some versions of Apple Clang - #define TOML_INT_CHARCONV 0 +#if TOML_CHAR_8_STRINGS +#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly. #endif -#ifndef TOML_INT_CHARCONV - #define TOML_INT_CHARCONV 1 -#endif -#ifndef TOML_FLOAT_CHARCONV - #define TOML_FLOAT_CHARCONV 1 -#endif -#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() - #undef TOML_INT_CHARCONV - #undef TOML_FLOAT_CHARCONV - #define TOML_INT_CHARCONV 0 - #define TOML_FLOAT_CHARCONV 0 #endif -#ifndef TOML_PUSH_WARNINGS - #define TOML_PUSH_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_CODE_ANALYSIS_WARNINGS - #define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SWITCH_WARNINGS - #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS - #define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_SPAM_WARNINGS - #define TOML_DISABLE_SPAM_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_ARITHMETIC_WARNINGS - #define TOML_DISABLE_ARITHMETIC_WARNINGS static_assert(true) -#endif -#ifndef TOML_POP_WARNINGS - #define TOML_POP_WARNINGS static_assert(true) -#endif -#ifndef TOML_DISABLE_WARNINGS - #define TOML_DISABLE_WARNINGS static_assert(true) -#endif -#ifndef TOML_ENABLE_WARNINGS - #define TOML_ENABLE_WARNINGS static_assert(true) -#endif - -#ifndef TOML_ATTR - #define TOML_ATTR(...) -#endif - -#ifndef TOML_ABSTRACT_BASE - #define TOML_ABSTRACT_BASE -#endif - -#ifndef TOML_EMPTY_BASES - #define TOML_EMPTY_BASES -#endif - -#ifndef TOML_ALWAYS_INLINE - #define TOML_ALWAYS_INLINE inline -#endif -#ifndef TOML_NEVER_INLINE - #define TOML_NEVER_INLINE -#endif - -#ifndef TOML_ASSUME - #define TOML_ASSUME(expr) static_assert(true) -#endif - -#ifndef TOML_UNREACHABLE - #define TOML_UNREACHABLE TOML_ASSUME(false) -#endif - -#ifndef TOML_FLAGS_ENUM - #define TOML_FLAGS_ENUM -#endif - -#ifndef TOML_OPEN_ENUM - #define TOML_OPEN_ENUM -#endif - -#ifndef TOML_CLOSED_ENUM - #define TOML_CLOSED_ENUM -#endif - -#ifndef TOML_OPEN_FLAGS_ENUM - #define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM +#ifdef TOML_LARGE_FILES +#if !TOML_LARGE_FILES +#error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0. #endif - -#ifndef TOML_CLOSED_FLAGS_ENUM - #define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM #endif -#ifdef __has_cpp_attribute - #define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__) -#else - #define TOML_HAS_ATTR(...) 0 -#endif - -#if TOML_HAS_ATTR(likely) >= 201803 - #ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) [[likely]] - #endif - #ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE [[likely]] - #endif -#endif -#ifndef TOML_LIKELY - #define TOML_LIKELY(...) (__VA_ARGS__) -#endif -#ifndef TOML_LIKELY_CASE - #define TOML_LIKELY_CASE +#ifndef TOML_LIFETIME_HOOKS +#define TOML_LIFETIME_HOOKS 0 #endif -#if TOML_HAS_ATTR(unlikely) >= 201803 - #ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]] - #endif - #ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE [[unlikely]] - #endif -#endif -#ifndef TOML_UNLIKELY - #define TOML_UNLIKELY(...) (__VA_ARGS__) +#ifdef NDEBUG +#undef TOML_ASSERT +#define TOML_ASSERT(expr) static_assert(true) #endif -#ifndef TOML_UNLIKELY_CASE - #define TOML_UNLIKELY_CASE +#ifndef TOML_ASSERT +#ifndef assert +TOML_DISABLE_WARNINGS; +#include +TOML_ENABLE_WARNINGS; #endif - -#if TOML_HAS_ATTR(nodiscard) - #define TOML_NODISCARD [[nodiscard]] -#else - #define TOML_NODISCARD +#define TOML_ASSERT(expr) assert(expr) #endif - -#if TOML_HAS_ATTR(nodiscard) >= 201907 - #define TOML_NODISCARD_CTOR [[nodiscard]] +#ifdef NDEBUG +#define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) #else - #define TOML_NODISCARD_CTOR +#define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) #endif -#ifndef TOML_TRIVIAL_ABI - #define TOML_TRIVIAL_ABI +#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)) +// not supported by any version of GCC or Clang as of 26/11/2020 +// not supported by any version of ICC on Linux as of 11/01/2021 +#define TOML_FLOAT_CHARCONV 0 #endif - -#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \ - __VA_ARGS__ TOML_NODISCARD friend bool operator == (RHS rhs, LHS lhs) noexcept { return lhs == rhs; } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (LHS lhs, RHS rhs) noexcept { return !(lhs == rhs); } \ - __VA_ARGS__ TOML_NODISCARD friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); } \ - static_assert(true) - -#ifndef TOML_SIMPLE_STATIC_ASSERT_MESSAGES - #define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0 +#if !defined(TOML_INT_CHARCONV) && (defined(__EMSCRIPTEN__) || defined(__APPLE__)) +// causes link errors on emscripten +// causes Mac OS SDK version errors on some versions of Apple Clang +#define TOML_INT_CHARCONV 0 #endif - -#define TOML_CONCAT_1(x, y) x##y -#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y) - -#define TOML_EVAL_BOOL_1(T, F) T -#define TOML_EVAL_BOOL_0(T, F) F - -#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \ - || defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE) - #define TOML_ARM 1 -#else - #define TOML_ARM 0 -#endif - -#define TOML_MAKE_FLAGS_(name, op) \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator op(name lhs, name rhs) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(static_cast(lhs) op static_cast(rhs)); \ - } \ - constexpr name& operator TOML_CONCAT(op, =)(name & lhs, name rhs) noexcept \ - { \ - return lhs = (lhs op rhs); \ - } \ - static_assert(true, "") - -#define TOML_MAKE_FLAGS(name) \ - TOML_MAKE_FLAGS_(name, &); \ - TOML_MAKE_FLAGS_(name, |); \ - TOML_MAKE_FLAGS_(name, ^); \ - TOML_CONST_INLINE_GETTER \ - constexpr name operator~(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return static_cast(~static_cast(val)); \ - } \ - TOML_CONST_INLINE_GETTER \ - constexpr bool operator!(name val) noexcept \ - { \ - using under = std::underlying_type_t; \ - return !static_cast(val); \ - } \ - static_assert(true, "") - -#ifndef TOML_LIFETIME_HOOKS - #define TOML_LIFETIME_HOOKS 0 +#ifndef TOML_INT_CHARCONV +#define TOML_INT_CHARCONV 1 #endif - -#if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) - #define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ +#ifndef TOML_FLOAT_CHARCONV +#define TOML_FLOAT_CHARCONV 1 #endif - -#ifdef NDEBUG - #define TOML_PURE_GETTER TOML_NODISCARD TOML_ATTR(pure) - #define TOML_CONST_GETTER TOML_NODISCARD TOML_ATTR(const) - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(pure) - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE TOML_ATTR(const) -#else - #define TOML_PURE_GETTER TOML_NODISCARD - #define TOML_CONST_GETTER TOML_NODISCARD - #define TOML_PURE_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE - #define TOML_CONST_INLINE_GETTER TOML_NODISCARD TOML_ALWAYS_INLINE +#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE() +#undef TOML_INT_CHARCONV +#undef TOML_FLOAT_CHARCONV +#define TOML_INT_CHARCONV 0 +#define TOML_FLOAT_CHARCONV 0 #endif -#define TOML_UNUSED(...) static_cast(__VA_ARGS__) - -#define TOML_DELETE_DEFAULTS(T) \ - T(const T&) = delete; \ - T(T&&) = delete; \ - T& operator=(const T&) = delete; \ - T& operator=(T&&) = delete - -// SFINAE #if defined(__cpp_concepts) && __cpp_concepts >= 201907 - #define TOML_REQUIRES(...) requires(__VA_ARGS__) +#define TOML_REQUIRES(...) requires(__VA_ARGS__) #else - #define TOML_REQUIRES(...) +#define TOML_REQUIRES(...) #endif -#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 -#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__ TOML_ENABLE_IF(condition)> TOML_REQUIRES(condition) -#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) +#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0 +#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \ + template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \ + TOML_REQUIRES(condition) +#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__) + +// clang-format off #ifdef __FLT16_MANT_DIG__ #if __FLT_RADIX__ == 2 \ @@ -852,6 +924,10 @@ #define TOML_UINT128 __uint128_t #endif +// clang-format on + +// clang-format off + //******** impl/version.h ******************************************************************************************** #define TOML_LIB_MAJOR 3 @@ -887,7 +963,7 @@ TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH) #ifndef TOML_ABI_NAMESPACES - #ifdef DOXYGEN + #if TOML_DOXYGEN #define TOML_ABI_NAMESPACES 0 #else #define TOML_ABI_NAMESPACES 1 @@ -926,23 +1002,9 @@ #define TOML_INTERNAL_LINKAGE static #endif -#ifdef NDEBUG - #undef TOML_ASSERT - #define TOML_ASSERT(expr) static_assert(true) -#endif -#ifndef TOML_ASSERT - #ifndef assert - TOML_DISABLE_WARNINGS; - #include - TOML_ENABLE_WARNINGS; - #endif - #define TOML_ASSERT(expr) assert(expr) -#endif -#ifdef NDEBUG - #define TOML_ASSERT_ASSUME(expr) TOML_ASSUME(expr) -#else - #define TOML_ASSERT_ASSUME(expr) TOML_ASSERT(expr) -#endif +// clang-format on + +// clang-format off #if TOML_SIMPLE_STATIC_ASSERT_MESSAGES @@ -1037,7 +1099,7 @@ TOML_DISABLE_WARNINGS; #include TOML_ENABLE_WARNINGS; -#if defined(DOXYGEN) \ +#if TOML_DOXYGEN \ || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \ && __cpp_lib_char8_t >= 201907) #define TOML_HAS_CHAR8 1 @@ -2719,8 +2781,7 @@ TOML_NAMESPACE_START static bool TOML_CALLCONV equal(const path_component&, const path_component&) noexcept; template - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER static Type* get_as(storage_t& s) noexcept { return TOML_LAUNDER(reinterpret_cast(s.bytes)); @@ -2731,7 +2792,7 @@ TOML_NAMESPACE_START ::new (static_cast(storage_.bytes)) std::string{ key }; } - static void store_index(size_t index, storage_t& storage_) + static void store_index(size_t index, storage_t& storage_) noexcept { ::new (static_cast(storage_.bytes)) std::size_t{ index }; } @@ -2743,26 +2804,19 @@ TOML_NAMESPACE_START } TOML_NODISCARD - size_t& index() & noexcept + size_t& index_ref() noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::array_index); return *get_as(value_storage_); } TOML_NODISCARD - std::string& key() & noexcept + std::string& key_ref() noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::key); return *get_as(value_storage_); } - TOML_NODISCARD - std::string&& key() && noexcept - { - TOML_ASSERT_ASSUME(type_ == path_component_type::key); - return static_cast(*get_as(value_storage_)); - } - public: TOML_NODISCARD_CTOR @@ -2794,56 +2848,50 @@ TOML_NAMESPACE_START path_component(path_component&& pc) noexcept; TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(const path_component & rhs); + path_component& operator=(const path_component& rhs); TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(path_component && rhs) noexcept; + path_component& operator=(path_component&& rhs) noexcept; + + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(size_t new_index) noexcept; + + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(std::string_view new_key); + +#if TOML_ENABLE_WINDOWS_COMPAT + + TOML_EXPORTED_MEMBER_FUNCTION + path_component& operator=(std::wstring_view new_key); + +#endif ~path_component() noexcept { destroy(); } - TOML_NODISCARD - const size_t& index() const& noexcept + TOML_PURE_GETTER + size_t index() const noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::array_index); return *get_as(value_storage_); } - TOML_NODISCARD - /* implicit */ operator const size_t&() const noexcept + TOML_PURE_INLINE_GETTER + explicit operator size_t() const noexcept { return index(); } - TOML_NODISCARD - const std::string& key() const& noexcept + TOML_PURE_GETTER + const std::string& key() const noexcept { TOML_ASSERT_ASSUME(type_ == path_component_type::key); return *get_as(value_storage_); } - TOML_NODISCARD - const std::string&& key() const&& noexcept - { - TOML_ASSERT_ASSUME(type_ == path_component_type::key); - return static_cast(*get_as(value_storage_)); - } - - TOML_NODISCARD - explicit operator const std::string&() noexcept - { - return key(); - } - - TOML_NODISCARD - explicit operator const std::string&&() noexcept - { - return std::move(key()); - } - - TOML_NODISCARD + TOML_PURE_INLINE_GETTER explicit operator const std::string&() const noexcept { return key(); @@ -2866,19 +2914,6 @@ TOML_NAMESPACE_START { return !equal(lhs, rhs); } - - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(size_t new_index) noexcept; - - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(std::string_view new_key); - -#if TOML_ENABLE_WINDOWS_COMPAT - - TOML_EXPORTED_MEMBER_FUNCTION - path_component& operator=(std::wstring_view new_key); - -#endif }; class TOML_EXPORTED_CLASS path @@ -2940,12 +2975,14 @@ TOML_NAMESPACE_START TOML_PURE_INLINE_GETTER path_component& operator[](size_t index) noexcept { + TOML_ASSERT(index < size()); return components_[index]; } TOML_PURE_INLINE_GETTER const path_component& operator[](size_t index) const noexcept { + TOML_ASSERT(index < size()); return components_[index]; } @@ -3128,15 +3165,13 @@ TOML_NAMESPACE_START #endif - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER friend bool operator==(const path& lhs, const path& rhs) noexcept { return equal(lhs, rhs); } - TOML_NODISCARD - TOML_ALWAYS_INLINE + TOML_PURE_INLINE_GETTER friend bool operator!=(const path& lhs, const path& rhs) noexcept { return !equal(lhs, rhs); @@ -3202,21 +3237,49 @@ TOML_NAMESPACE_START #endif // TOML_ENABLE_WINDOWS_COMPAT - TOML_EXPORTED_MEMBER_FUNCTION - void clear() noexcept; + using iterator = std::vector::iterator; - TOML_NODISCARD - auto begin() const noexcept + using const_iterator = std::vector::const_iterator; + + TOML_PURE_INLINE_GETTER + iterator begin() noexcept { return components_.begin(); } - TOML_NODISCARD - auto end() const noexcept + TOML_PURE_INLINE_GETTER + iterator end() noexcept { return components_.end(); } + TOML_PURE_INLINE_GETTER + const_iterator begin() const noexcept + { + return components_.begin(); + } + + TOML_PURE_INLINE_GETTER + const_iterator end() const noexcept + { + return components_.end(); + } + + TOML_PURE_INLINE_GETTER + const_iterator cbegin() const noexcept + { + return components_.begin(); + } + + TOML_PURE_INLINE_GETTER + const_iterator cend() const noexcept + { + return components_.end(); + } + + TOML_EXPORTED_MEMBER_FUNCTION + void clear() noexcept; + TOML_EXPORTED_MEMBER_FUNCTION path& truncate(size_t n); @@ -3234,8 +3297,7 @@ TOML_NAMESPACE_START TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION - path subpath(std::vector::const_iterator start, - std::vector::const_iterator end) const; + path subpath(const_iterator start, const_iterator end) const; TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION @@ -3288,7 +3350,7 @@ TOML_PUSH_WARNINGS; TOML_NAMESPACE_START { - class TOML_ABSTRACT_BASE TOML_EXPORTED_CLASS node + class TOML_ABSTRACT_INTERFACE TOML_EXPORTED_CLASS node { private: @@ -7933,13 +7995,13 @@ TOML_NAMESPACE_START ipos->second = std::move(static_cast(args)...); else { -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS try { #endif ipos->second.reset( new impl::wrap_node{ static_cast(args)... }); -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS } catch (...) { @@ -8580,7 +8642,7 @@ TOML_PUSH_WARNINGS; #undef max #endif -#if defined(DOXYGEN) || !TOML_EXCEPTIONS +#if TOML_DOXYGEN || !TOML_EXCEPTIONS #define TOML_PARSE_ERROR_BASE #else #define TOML_PARSE_ERROR_BASE : public std::runtime_error @@ -8683,7 +8745,7 @@ TOML_POP_WARNINGS; //******** impl/parse_result.h *************************************************************************************** -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) TOML_PUSH_WARNINGS; #ifdef _MSC_VER @@ -9399,7 +9461,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) TOML_NODISCARD_CTOR explicit toml_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept @@ -9486,7 +9548,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) TOML_NODISCARD_CTOR explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept @@ -9577,7 +9639,7 @@ TOML_NAMESPACE_START : base{ &source, nullptr, constants, { flags, " "sv } } {} -#if defined(DOXYGEN) || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) +#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS) TOML_NODISCARD_CTOR explicit yaml_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept @@ -10290,6 +10352,7 @@ TOML_NAMESPACE_END; TOML_IMPL_NAMESPACE_START { + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV node_deep_equality(const node* lhs, const node* rhs) noexcept { @@ -10653,12 +10716,12 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE path_component::path_component(std::wstring_view key) // : path_component(impl::narrow(key)) - { } + {} #endif TOML_EXTERNAL_LINKAGE - path_component::path_component(const path_component & pc) // + path_component::path_component(const path_component& pc) // : type_{ pc.type_ } { if (type_ == path_component_type::array_index) @@ -10672,9 +10735,9 @@ TOML_NAMESPACE_START : type_{ pc.type_ } { if (type_ == path_component_type::array_index) - store_index(pc.index(), value_storage_); + store_index(pc.index_ref(), value_storage_); else - store_key(std::move(pc).key(), value_storage_); + store_key(std::move(pc.key_ref()), value_storage_); } TOML_EXTERNAL_LINKAGE @@ -10693,9 +10756,9 @@ TOML_NAMESPACE_START else { if (type_ == path_component_type::array_index) - index() = rhs.index(); + index_ref() = rhs.index(); else - key() = rhs.key(); + key_ref() = rhs.key(); } return *this; } @@ -10709,20 +10772,21 @@ TOML_NAMESPACE_START type_ = rhs.type_; if (type_ == path_component_type::array_index) - store_index(std::move(rhs).index(), value_storage_); + store_index(rhs.index(), value_storage_); else - store_key(std::move(rhs).key(), value_storage_); + store_key(std::move(rhs.key_ref()), value_storage_); } else { if (type_ == path_component_type::array_index) - index() = std::move(rhs).index(); + index_ref() = rhs.index(); else - key() = std::move(rhs).key(); + key_ref() = std::move(rhs.key_ref()); } return *this; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV path_component::equal(const path_component& lhs, const path_component& rhs) noexcept { @@ -10737,7 +10801,7 @@ TOML_NAMESPACE_START } TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (size_t new_index) noexcept + path_component& path_component::operator=(size_t new_index) noexcept { // If currently a key, string will need to be destroyed regardless destroy(); @@ -10749,10 +10813,10 @@ TOML_NAMESPACE_START } TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (std::string_view new_key) + path_component& path_component::operator=(std::string_view new_key) { if (type_ == path_component_type::key) - key() = new_key; + key_ref() = new_key; else { type_ = path_component_type::key; @@ -10765,10 +10829,10 @@ TOML_NAMESPACE_START #if TOML_ENABLE_WINDOWS_COMPAT TOML_EXTERNAL_LINKAGE - path_component& path_component::operator= (std::wstring_view new_key) + path_component& path_component::operator=(std::wstring_view new_key) { if (type_ == path_component_type::key) - key() = impl::narrow(new_key); + key_ref() = impl::narrow(new_key); else { type_ = path_component_type::key; @@ -10840,6 +10904,7 @@ TOML_NAMESPACE_START } } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV path::equal(const path& lhs, const path& rhs) noexcept { @@ -11237,6 +11302,7 @@ TOML_NAMESPACE_START return elems_.insert(pos, std::move(elem)); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype) const noexcept { @@ -11253,6 +11319,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept { @@ -11274,6 +11341,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool array::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept { @@ -11286,7 +11354,7 @@ TOML_NAMESPACE_START TOML_EXTERNAL_LINKAGE node& array::at(size_t index) { -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS return *elems_.at(index); @@ -11582,6 +11650,7 @@ TOML_NAMESPACE_START return *this; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype) const noexcept { @@ -11601,6 +11670,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept { @@ -11623,6 +11693,7 @@ TOML_NAMESPACE_START return true; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool table::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept { @@ -11632,6 +11703,7 @@ TOML_NAMESPACE_START return result; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE node* table::get(std::string_view key) noexcept { @@ -11645,7 +11717,7 @@ TOML_NAMESPACE_START { auto n = get(key); -#if TOML_COMPILER_EXCEPTIONS +#if TOML_COMPILER_HAS_EXCEPTIONS if (!n) { @@ -11664,18 +11736,21 @@ TOML_NAMESPACE_START return *n; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::map_iterator table::get_lower_bound(std::string_view key) noexcept { return map_.lower_bound(key); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::iterator table::find(std::string_view key) noexcept { return iterator{ map_.find(key) }; } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE table::const_iterator table::find(std::string_view key) const noexcept { @@ -11753,6 +11828,7 @@ TOML_NAMESPACE_START return map_.emplace_hint(const_map_iterator{ hint }, std::move(k), std::move(v)); } + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool TOML_CALLCONV table::equal(const table& lhs, const table& rhs) noexcept { @@ -11834,6 +11910,7 @@ TOML_PUSH_WARNINGS; TOML_IMPL_NAMESPACE_START { + TOML_PURE_GETTER TOML_EXTERNAL_LINKAGE bool is_ascii(const char* str, size_t len) noexcept { @@ -11978,7 +12055,7 @@ TOML_ANON_NAMESPACE_START public: TOML_NODISCARD_CTOR - explicit utf8_byte_stream(std::istream& stream) noexcept(!TOML_COMPILER_EXCEPTIONS) // + explicit utf8_byte_stream(std::istream& stream) noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) // : source_{ &stream } { if (!*this) // eof, bad @@ -12013,14 +12090,14 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { return eof() || source_->peek() == std::istream::traits_type::eof(); } TOML_NODISCARD TOML_ATTR(nonnull) - size_t operator()(void* dest, size_t num) noexcept(!TOML_COMPILER_EXCEPTIONS) + size_t operator()(void* dest, size_t num) noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { TOML_ASSERT(*this); @@ -12051,16 +12128,16 @@ TOML_ANON_NAMESPACE_START static_assert(std::is_trivial_v); static_assert(std::is_standard_layout_v); - struct TOML_ABSTRACT_BASE utf8_reader_interface + struct TOML_ABSTRACT_INTERFACE utf8_reader_interface { TOML_NODISCARD virtual const source_path_ptr& source_path() const noexcept = 0; TOML_NODISCARD - virtual const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) = 0; + virtual const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) = 0; TOML_NODISCARD - virtual bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) = 0; + virtual bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) = 0; #if !TOML_EXCEPTIONS @@ -12123,7 +12200,7 @@ TOML_ANON_NAMESPACE_START optional err_; #endif - bool read_next_block() noexcept(!TOML_COMPILER_EXCEPTIONS) + bool read_next_block() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { TOML_ASSERT(stream_); @@ -12301,7 +12378,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) final + const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final { utf8_reader_error_check({}); @@ -12320,7 +12397,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) final + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) final { return stream_.peek_eof(); } @@ -12387,7 +12464,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_EXCEPTIONS) + const utf8_codepoint* read_next() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { utf8_buffered_reader_error_check({}); @@ -12441,7 +12518,7 @@ TOML_ANON_NAMESPACE_START } TOML_NODISCARD - bool peek_eof() const noexcept(!TOML_COMPILER_EXCEPTIONS) + bool peek_eof() const noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { return reader_.peek_eof(); } @@ -14483,7 +14560,7 @@ TOML_IMPL_NAMESPACE_START char32_t chars[utf8_buffered_reader::max_history_length]; size_t char_count = {}, advance_count = {}; bool eof_while_scanning = false; - const auto scan = [&]() noexcept(!TOML_COMPILER_EXCEPTIONS) + const auto scan = [&]() noexcept(!TOML_COMPILER_HAS_EXCEPTIONS) { if (is_eof()) return; @@ -16944,7 +17021,7 @@ TOML_POP_WARNINGS; #undef TOML_ABI_NAMESPACE_END #undef TOML_ABI_NAMESPACE_START #undef TOML_ABI_NAMESPACES -#undef TOML_ABSTRACT_BASE +#undef TOML_ABSTRACT_INTERFACE #undef TOML_ALWAYS_INLINE #undef TOML_ANON_NAMESPACE #undef TOML_ANON_NAMESPACE_END @@ -16958,11 +17035,14 @@ TOML_POP_WARNINGS; #undef TOML_CLANG #undef TOML_CLOSED_ENUM #undef TOML_CLOSED_FLAGS_ENUM -#undef TOML_COMPILER_EXCEPTIONS +#undef TOML_COMPILER_HAS_EXCEPTIONS +#undef TOML_COMPILER_HAS_RTTI +#undef TOML_CONST #undef TOML_CONST_GETTER #undef TOML_CONST_INLINE_GETTER #undef TOML_CONSTRAINED_TEMPLATE -#undef TOML_CPP_VERSION +#undef TOML_CPP +#undef TOML_DECLSPEC #undef TOML_DELETE_DEFAULTS #undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS @@ -16972,6 +17052,7 @@ TOML_POP_WARNINGS; #undef TOML_DISABLE_SUGGEST_ATTR_WARNINGS #undef TOML_DISABLE_SWITCH_WARNINGS #undef TOML_DISABLE_WARNINGS +#undef TOML_DOXYGEN #undef TOML_EMPTY_BASES #undef TOML_ENABLE_IF #undef TOML_ENABLE_WARNINGS @@ -16985,8 +17066,11 @@ TOML_POP_WARNINGS; #undef TOML_FP16 #undef TOML_GCC #undef TOML_HAS_ATTR +#undef TOML_HAS_BUILTIN #undef TOML_HAS_CHAR8 +#undef TOML_HAS_CPP_ATTR #undef TOML_HAS_CUSTOM_OPTIONAL_TYPE +#undef TOML_HAS_FEATURE #undef TOML_HAS_INCLUDE #undef TOML_HAS_SSE2 #undef TOML_HAS_SSE4_1 @@ -17011,6 +17095,10 @@ TOML_POP_WARNINGS; #undef TOML_LIKELY_CASE #undef TOML_MAKE_FLAGS #undef TOML_MAKE_FLAGS_ +#undef TOML_MAKE_FLAGS_1 +#undef TOML_MAKE_FLAGS_2 +#undef TOML_MAKE_STRING +#undef TOML_MAKE_STRING_1 #undef TOML_MAKE_VERSION #undef TOML_MSVC #undef TOML_NAMESPACE @@ -17021,6 +17109,14 @@ TOML_POP_WARNINGS; #undef TOML_OPEN_FLAGS_ENUM #undef TOML_PARSER_TYPENAME #undef TOML_POP_WARNINGS +#undef TOML_PRAGMA_CLANG +#undef TOML_PRAGMA_CLANG_GE_10 +#undef TOML_PRAGMA_CLANG_GE_11 +#undef TOML_PRAGMA_CLANG_GE_9 +#undef TOML_PRAGMA_GCC +#undef TOML_PRAGMA_ICC +#undef TOML_PRAGMA_MSVC +#undef TOML_PURE #undef TOML_PURE_GETTER #undef TOML_PURE_INLINE_GETTER #undef TOML_PUSH_WARNINGS @@ -17046,6 +17142,7 @@ TOML_POP_WARNINGS; #undef TOML_UNLIKELY_CASE #undef TOML_UNREACHABLE #undef TOML_UNUSED +#undef TOML_WINDOWS #endif #endif // TOMLPLUSPLUS_H