diff --git a/README.md b/README.md
index 5bf48c10..7d8768c5 100644
--- a/README.md
+++ b/README.md
@@ -5,13 +5,13 @@
[![GitHub](https://img.shields.io/github/license/marzer/tomlplusplus)](https://github.com/marzer/tomlplusplus/blob/master/LICENSE)
`toml++` is a header-only toml parser and serializer for C++17, C++20 and whatever comes after.
- - Fully [TOML v0.5.0]-compliant
- - Modern C++17 (with some C++20 features where supported)
+ - [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md), plus support for some
+ unreleased TOML features (these are optional)
+ - C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings)
- Proper UTF-8 handling (incl. BOM)
- Works with or without exceptions
- Doesn't require RTTI
- First-class support for serializing to JSON
- - Supports a number of 'unreleased' TOML features (optional)
diff --git a/include/toml++/toml.h b/include/toml++/toml.h
index c40c04c9..ae64f801 100644
--- a/include/toml++/toml.h
+++ b/include/toml++/toml.h
@@ -53,7 +53,10 @@
#undef TOML_DOXYGEN
#undef TOML_RELOPS_REORDERING
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
+ #undef TOML_INLINE_NS_EX
#undef TOML_START
+ #undef TOML_START_2
+ #undef TOML_START_1
#undef TOML_END
#undef TOML_IMPL_START
#undef TOML_IMPL_END
@@ -61,33 +64,47 @@
/// \mainpage toml++
///
-/// This is the home of toml++, a header-only [TOML](https://github.com/toml-lang/toml) parser and serializer for C++17 and later.
+/// This is the home of toml++, a header-only [TOML](https://github.com/toml-lang/toml) parser and serializer for C++17
+/// and later.
///
/// \tableofcontents
///
///////////////////////////////////////////////////////////////////////
///
/// \section mainpage-features Features
-/// - C++17 (plus some C++20 features where supported, e.g. char8_t strings)
+/// - [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md), plus support for some
+/// unreleased TOML features (these are optional)
+/// - C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings)
/// - Proper UTF-8 handling (incl. BOM)
/// - Works with or without exceptions
/// - Doesn't require RTTI
/// - First-class support for serializing to JSON
-/// - Fully [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md)-compliant
-/// - Supports a number of 'unreleased' TOML features (optional; these can be disabled)
///
///////////////////////////////////////////////////////////////////////
///
/// \section mainpage-adding-lib Adding toml++ to your project
-/// Clone [the repository](https://github.com/marzer/tomlplusplus/) from GitHub. It's header-only so there's not much you have to do after that,
-/// other than some very minor (optional) configuration. See the [README](https://github.com/marzer/tomlplusplus/blob/master/README.md) for more info.
+/// It's header-only library so really all you have to do is clone
+/// [the repository](https://github.com/marzer/tomlplusplus/) from GitHub and set your include paths.
+/// There's some minor configuration you can do to customize some basic library functionality, but that's totally
+/// optional. See the [README](https://github.com/marzer/tomlplusplus/blob/master/README.md) for more info.
+///
+///
+/// On Linkers and the One-Definition-Rule
+/// Header-only libraries are great for minimal setup, but can cause ODR violations and complex linker errors
+/// in situations where multiple modules include them separately, each with different versions, configuration options,
+/// exception handling modes, et cetera.
+/// `toml++` attempts to combat this problem by nesting everything inside an additional inline namespace that
+/// changes according to the library's major version and the compiler's exception-handling mode.
+///
///
///////////////////////////////////////////////////////////////////////
///
/// \section mainpage-api-documentation API Documentation
-/// You're looking at it! Browse the docs using the links at the top of the page. You can search from anywhere by pressing the TAB key.
+/// You're looking at it! Browse the docs using the links at the top of the page.
+/// You can search from anywhere by pressing the TAB key.
///
-/// toml++ is still pretty hot off the presses so there's going to be some omissions, typos and general sparseness throughout the docs.
+/// toml++ is still pretty hot off the presses so there's going to be some omissions,
+/// typos and general sparseness throughout the docs.
/// If you spot something or have a suggestion, please [let me know](https://github.com/marzer/tomlplusplus/issues)!
///
///////////////////////////////////////////////////////////////////////
@@ -99,7 +116,8 @@
/// \subsection mainpage-example-parsing-files Parsing TOML files
/// toml++ works whether you have exceptions enabled or not. For the most part the usage is the same,
/// the main difference being how parsing errors are reported to the caller. When exceptions are enabled
-/// a toml::parse_error is thrown directly from the site of the error:
+/// a successful call to a parsing function simply returns a toml::table, whereas a failed call sees a toml::parse_error
+/// thrown directly from the site of the error:
/// \cpp
/// #include
/// #include //required for parse_file()
@@ -129,7 +147,7 @@
///
/// \ecpp
///
-/// When exceptions are disabled parsing methods return a toml::parse_result and it is up to the caller
+/// When exceptions are disabled parsing functions return a toml::parse_result instead and it is up to the caller
/// to check if parsing has been successful by examining the return value:
/// \cpp
/// #include
@@ -341,9 +359,13 @@
///
/// \section mainpage-license License
///
-/// toml++ is licensed under the terms of the MIT license - see [LICENSE](https://github.com/marzer/tomlplusplus/blob/master/LICENSE).
+/// toml++ is licensed under the terms of the MIT license - see
+/// [LICENSE](https://github.com/marzer/tomlplusplus/blob/master/LICENSE).
///
-/// UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's 'Flexible and Economical UTF - 8 Decoder', which is also subject
-/// to the terms of the MIT license - see [LICENSE-utf8-decoder](https://github.com/marzer/tomlplusplus/blob/master/LICENSE-utf8-decoder).
+/// UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's
+/// 'Flexible and Economical UTF - 8 Decoder', which is also subject to the terms of the MIT license - see
+/// [LICENSE-utf8-decoder](https://github.com/marzer/tomlplusplus/blob/master/LICENSE-utf8-decoder).
///
+/// \remark Note that if you're using the single-header version of the library you don't need to distribute these files;
+/// their contents is included in the preamble at the top of the file.
///
diff --git a/include/toml++/toml_common.h b/include/toml++/toml_common.h
index 52c164fc..777ef7f5 100644
--- a/include/toml++/toml_common.h
+++ b/include/toml++/toml_common.h
@@ -229,17 +229,6 @@
__VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); }
#endif
-#if !TOML_DOXYGEN
- #if TOML_EXCEPTIONS
- #define TOML_START namespace toml { inline namespace wex
- #else
- #define TOML_START namespace toml { inline namespace woex
- #endif
- #define TOML_END }
-#endif
-#define TOML_IMPL_START TOML_START { namespace impl
-#define TOML_IMPL_END } TOML_END
-
#include "toml_version.h"
#define TOML_MAKE_VERSION(maj, min, rev) \
@@ -262,6 +251,22 @@
#define TOML_LANG_EXACTLY(maj, min, rev) \
(TOML_LANG_EFFECTIVE_VERSION == TOML_MAKE_VERSION(maj, min, rev))
+#if !TOML_DOXYGEN
+
+ #if TOML_EXCEPTIONS
+ #define TOML_INLINE_NS_EX
+ #else
+ #define TOML_INLINE_NS_EX _noex
+ #endif
+
+ #define TOML_START_2(VER, ARG1, ARG2) namespace toml { inline namespace v##VER##ARG1##ARG2
+ #define TOML_START_1(VER, ARG1, ARG2) TOML_START_2(VER, ARG1, ARG2)
+ #define TOML_START TOML_START_1(TOML_LIB_MAJOR,TOML_INLINE_NS_EX,)
+ #define TOML_END }
+
+#endif
+#define TOML_IMPL_START TOML_START { namespace impl
+#define TOML_IMPL_END } TOML_END
////////// INCLUDES
diff --git a/include/toml++/toml_node_view.h b/include/toml++/toml_node_view.h
index ad81dba8..e5f7ce1b 100644
--- a/include/toml++/toml_node_view.h
+++ b/include/toml++/toml_node_view.h
@@ -35,17 +35,18 @@ TOML_START
///
/// tbl["products"][0]["keywords"].as_array()->push_back("heavy");
/// std::cout << tbl["products"][0]["keywords"] << std::endl;
- /// std::cout << "has third product: "sv << !!tbl["products"][2] << std::endl;
- /// std::cout << tbl["products"][2] << std::endl; // no-op
- ///
- /// \ecpp
+ /// std::cout << "has product[2]: "sv << !!tbl["products"][2] << std::endl;
+ /// std::cout << "product[2]: "sv << tbl["products"][2] << std::endl;
+ /// \ecpp
///
/// \out
/// "my hardware store"
/// "Hammer"
/// [ "hammer", "construction", "build" ]
+ /// "build"
/// [ "hammer", "construction", "build", "heavy" ]
- /// has third product: false
+ /// has product[2]: false
+ /// product[2]:
/// \eout
template
class node_view final
diff --git a/include/toml++/toml_value.h b/include/toml++/toml_value.h
index 743d5b06..c786764d 100644
--- a/include/toml++/toml_value.h
+++ b/include/toml++/toml_value.h
@@ -42,6 +42,17 @@ TOML_START
/// \brief The value's underlying data type.
using value_type = T;
+ /// \brief A type alias for 'value arguments'.
+ /// \details This differs according to the value's type argument:
+ /// - ints, floats, booleans: `value_type`
+ /// - strings: `string_view`
+ /// - everything else: `const value_type&`
+ using value_arg = std::conditional_t<
+ std::is_same_v,
+ string_view,
+ std::conditional_t, T, const T&>
+ >;
+
/// \brief Constructs a toml value.
///
/// \tparam U Constructor argument types.
@@ -167,19 +178,8 @@ TOML_START
return lhs;
}
- /// \brief A type alias for 'value arguments'.
- /// \details This differs according to the value's type argument:
- /// - ints, floats, booleans: `value_type`
- /// - strings: `string_view`
- /// - everything else: `const value_type&`
- using value_arg_t = std::conditional_t<
- std::is_same_v,
- string_view,
- std::conditional_t, T, const T&>
- >;
-
/// \brief Value-assignment operator.
- value& operator= (value_arg_t rhs) noexcept
+ value& operator= (value_arg rhs) noexcept
{
if constexpr (std::is_same_v)
val_.assign(rhs);
@@ -196,26 +196,26 @@ TOML_START
}
/// \brief Value equality operator.
- [[nodiscard]] friend bool operator == (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ == rhs; }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg_t, )
+ [[nodiscard]] friend bool operator == (const value& lhs, value_arg rhs) noexcept { return lhs.val_ == rhs; }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg, )
/// \brief Value less-than operator.
- [[nodiscard]] friend bool operator < (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ < rhs; }
+ [[nodiscard]] friend bool operator < (const value& lhs, value_arg rhs) noexcept { return lhs.val_ < rhs; }
/// \brief Value less-than operator.
- [[nodiscard]] friend bool operator < (value_arg_t lhs, const value& rhs) noexcept { return lhs < rhs.val_; }
+ [[nodiscard]] friend bool operator < (value_arg lhs, const value& rhs) noexcept { return lhs < rhs.val_; }
/// \brief Value less-than-or-equal-to operator.
- [[nodiscard]] friend bool operator <= (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ <= rhs; }
+ [[nodiscard]] friend bool operator <= (const value& lhs, value_arg rhs) noexcept { return lhs.val_ <= rhs; }
/// \brief Value less-than-or-equal-to operator.
- [[nodiscard]] friend bool operator <= (value_arg_t lhs, const value& rhs) noexcept { return lhs <= rhs.val_; }
+ [[nodiscard]] friend bool operator <= (value_arg lhs, const value& rhs) noexcept { return lhs <= rhs.val_; }
/// \brief Value greater-than operator.
- [[nodiscard]] friend bool operator > (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ > rhs; }
+ [[nodiscard]] friend bool operator > (const value& lhs, value_arg rhs) noexcept { return lhs.val_ > rhs; }
/// \brief Value greater-than operator.
- [[nodiscard]] friend bool operator > (value_arg_t lhs, const value& rhs) noexcept { return lhs > rhs.val_; }
+ [[nodiscard]] friend bool operator > (value_arg lhs, const value& rhs) noexcept { return lhs > rhs.val_; }
/// \brief Value greater-than-or-equal-to operator.
- [[nodiscard]] friend bool operator >= (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ >= rhs; }
+ [[nodiscard]] friend bool operator >= (const value& lhs, value_arg rhs) noexcept { return lhs.val_ >= rhs; }
/// \brief Value greater-than-or-equal-to operator.
- [[nodiscard]] friend bool operator >= (value_arg_t lhs, const value& rhs) noexcept { return lhs >= rhs.val_; }
+ [[nodiscard]] friend bool operator >= (value_arg lhs, const value& rhs) noexcept { return lhs >= rhs.val_; }
/// \brief Equality operator.
///
diff --git a/toml.hpp b/toml.hpp
index cbf6abe9..1c2151e6 100644
--- a/toml.hpp
+++ b/toml.hpp
@@ -293,17 +293,6 @@
__VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); }
#endif
-#if !TOML_DOXYGEN
- #if TOML_EXCEPTIONS
- #define TOML_START namespace toml { inline namespace wex
- #else
- #define TOML_START namespace toml { inline namespace woex
- #endif
- #define TOML_END }
-#endif
-#define TOML_IMPL_START TOML_START { namespace impl
-#define TOML_IMPL_END } TOML_END
-
#define TOML_LIB_MAJOR 0
#define TOML_LIB_MINOR 2
#define TOML_LIB_PATCH 0
@@ -332,6 +321,23 @@
#define TOML_LANG_EXACTLY(maj, min, rev) \
(TOML_LANG_EFFECTIVE_VERSION == TOML_MAKE_VERSION(maj, min, rev))
+#if !TOML_DOXYGEN
+
+ #if TOML_EXCEPTIONS
+ #define TOML_INLINE_NS_EX
+ #else
+ #define TOML_INLINE_NS_EX _noex
+ #endif
+
+ #define TOML_START_2(VER, ARG1, ARG2) namespace toml { inline namespace v##VER##ARG1##ARG2
+ #define TOML_START_1(VER, ARG1, ARG2) TOML_START_2(VER, ARG1, ARG2)
+ #define TOML_START TOML_START_1(TOML_LIB_MAJOR,TOML_INLINE_NS_EX,)
+ #define TOML_END }
+
+#endif
+#define TOML_IMPL_START TOML_START { namespace impl
+#define TOML_IMPL_END } TOML_END
+
TOML_PUSH_WARNINGS
TOML_DISABLE_ALL_WARNINGS
@@ -1680,6 +1686,11 @@ TOML_START
public:
using value_type = T;
+ using value_arg = std::conditional_t<
+ std::is_same_v,
+ string_view,
+ std::conditional_t, T, const T&>
+ >;
template
TOML_NODISCARD_CTOR
@@ -1757,13 +1768,7 @@ TOML_START
return lhs;
}
- using value_arg_t = std::conditional_t<
- std::is_same_v,
- string_view,
- std::conditional_t, T, const T&>
- >;
-
- value& operator= (value_arg_t rhs) noexcept
+ value& operator= (value_arg rhs) noexcept
{
if constexpr (std::is_same_v)
val_.assign(rhs);
@@ -1779,16 +1784,16 @@ TOML_START
return *this;
}
- [[nodiscard]] friend bool operator == (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ == rhs; }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg_t, )
- [[nodiscard]] friend bool operator < (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ < rhs; }
- [[nodiscard]] friend bool operator < (value_arg_t lhs, const value& rhs) noexcept { return lhs < rhs.val_; }
- [[nodiscard]] friend bool operator <= (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ <= rhs; }
- [[nodiscard]] friend bool operator <= (value_arg_t lhs, const value& rhs) noexcept { return lhs <= rhs.val_; }
- [[nodiscard]] friend bool operator > (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ > rhs; }
- [[nodiscard]] friend bool operator > (value_arg_t lhs, const value& rhs) noexcept { return lhs > rhs.val_; }
- [[nodiscard]] friend bool operator >= (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ >= rhs; }
- [[nodiscard]] friend bool operator >= (value_arg_t lhs, const value& rhs) noexcept { return lhs >= rhs.val_; }
+ [[nodiscard]] friend bool operator == (const value& lhs, value_arg rhs) noexcept { return lhs.val_ == rhs; }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg, )
+ [[nodiscard]] friend bool operator < (const value& lhs, value_arg rhs) noexcept { return lhs.val_ < rhs; }
+ [[nodiscard]] friend bool operator < (value_arg lhs, const value& rhs) noexcept { return lhs < rhs.val_; }
+ [[nodiscard]] friend bool operator <= (const value& lhs, value_arg rhs) noexcept { return lhs.val_ <= rhs; }
+ [[nodiscard]] friend bool operator <= (value_arg lhs, const value& rhs) noexcept { return lhs <= rhs.val_; }
+ [[nodiscard]] friend bool operator > (const value& lhs, value_arg rhs) noexcept { return lhs.val_ > rhs; }
+ [[nodiscard]] friend bool operator > (value_arg lhs, const value& rhs) noexcept { return lhs > rhs.val_; }
+ [[nodiscard]] friend bool operator >= (const value& lhs, value_arg rhs) noexcept { return lhs.val_ >= rhs; }
+ [[nodiscard]] friend bool operator >= (value_arg lhs, const value& rhs) noexcept { return lhs >= rhs.val_; }
template
[[nodiscard]] friend bool operator == (const value& lhs, const value& rhs) noexcept
@@ -8562,7 +8567,10 @@ TOML_END
#undef TOML_DOXYGEN
#undef TOML_RELOPS_REORDERING
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
+ #undef TOML_INLINE_NS_EX
#undef TOML_START
+ #undef TOML_START_2
+ #undef TOML_START_1
#undef TOML_END
#undef TOML_IMPL_START
#undef TOML_IMPL_END