added value assignment operators

also:
- added value::value_type
- removed format_flags::always_print_as_inline
- significantly improved documentation
This commit is contained in:
Mark Gillard 2020-02-18 23:29:59 +02:00
parent 1f8f3c7baa
commit 0b4eca301c
19 changed files with 564 additions and 392 deletions

View File

@ -32,20 +32,20 @@ int64_t depends_on_cpp_version = config["dependencies"]["cpp"].as_integer()->get
// modify the data
config.insert_or_assign("alternatives", toml::array{
"cpptoml",
"toml11",
"Boost.TOML"
"cpptoml",
"toml11",
"Boost.TOML"
});
// iterate & visit over the data
for (auto [k, v] : config)
{
v.visit([](auto& node) noexcept
{
std::cout << node << std:endl;
if constexpr (toml::is_string<decltype(node)>)
do_something_with_string_values(node)
});
v.visit([](auto& node) noexcept
{
std::cout << node << std:endl;
if constexpr (toml::is_string<decltype(node)>)
do_something_with_string_values(node);
});
}
// re-serialize as TOML

View File

@ -41,6 +41,8 @@ SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES = "cpp=@code{.cpp}" \
"ecpp=@endcode" \
"out=@code{.unparsed}" \
"eout=@endcode" \
"detail=@details"
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = NO

View File

@ -2,13 +2,14 @@
HTML_EXTRA_STYLESHEET = https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600 \
../css/m-dark+documentation.compiled.css \
tomlplusplus.css
HTML_EXTRA_FILES = tomlplusplus.js
HTML_EXTRA_FILES = tomlplusplus.js \
github-icon.png
##! M_THEME_COLOR = #22272e
##! M_LINKS_NAVBAR1 = \
##! namespaces
##! M_LINKS_NAVBAR2 = \
##! annotated \
##! "<a target="_blank" href="https://github.com/marzer/tomlplusplus/">Github</a>"
##! "<a target="_blank" href="https://github.com/marzer/tomlplusplus/" class="github">Github</a>"
##! M_SEARCH_DOWNLOAD_BINARY = NO
##! M_CLASS_TREE_EXPAND_LEVELS = 3
##! M_FILE_TREE_EXPAND_LEVELS = 3

BIN
docs/github-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,109 +1,3 @@
/*
table.m-table th
{
color: #ffe698;
}
article section > h2
{
padding-top: 0.5rem;
padding-bottom: 0.1rem;
background-color: #282e36;
padding-left: 1rem;
margin-left: -1rem;
margin-right: -1rem;
margin-top: 2rem;
border-color: #282e36;
border-style: solid;
border-width: 0.0625rem;
border-left-width: 0.25rem;
border-radius: 0.2rem;
}
article section:target
{
border-radius: 0.2rem;
}
article section:target > h2
{
border-color: #a5c9ea;
}
table.m-table thead th
{
border-bottom-width: 0.0rem;
}
table.m-table tbody td
{
border: 0px;
}
table.m-table thead tr:first-child th
{
border-top-width: 0.1rem;
}
code.m-code, aside code
{
margin-left: 0.1em;
padding-left: 0.2em;
padding-right: 0.1em;
}
dl.m-doc dd
{
margin-bottom: 0.8rem;
}
.m-doc-template a, dl.m-doc dd a, ul.m-doc li > span.m-doc a
{
color: #858585;
}
.m-doc-template a.tpp-external:hover,
dl.m-doc dd a.tpp-external:hover,
ul.m-doc li > span.m-doc a.tpp-external:hover
{
color: inherit;
}
pre, .m-doc-search-content
{
background-color: #1e1e1e;
}
pre.m-code, code
{
background-color: #1e1e1e88;
}
article section.m-doc-details > div > h3:first-child, article section > h2, body > footer > nav
{
background-color: #252526;
}
.tpp-external-navbar
{
background-color: #007acc11;
}
.m-label:not(.m-flat)
{
font-weight: bold;
}
div.m-doc-include
{
font-size: 0.9rem;
}
.m-doc-include span.cp
{
display: none;
}
.m-doc-include a.cpf
{
color: #9999AA;
}
*/
html, body
{
scroll-padding-top: 3.5rem;
@ -114,7 +8,8 @@ body
margin-top: 3rem;
}
header {
header
{
position: fixed;
left: 0;
right: 0;
@ -122,23 +17,28 @@ header {
z-index: 100;
}
article, article > header, article section {
article, article > header, article section
{
margin-bottom: 3em;
}
pre, code, .tpp-enable-if > a {
pre, code, .tpp-enable-if > a
{
font-family: 'Consolas', 'Source Sans Pro', monospace;
}
a.tpp-external {
a.tpp-external
{
font-weight: normal;
}
.tpp-enable-if {
.tpp-enable-if
{
margin-bottom: 2px;
}
.tpp-enable-if > * {
.tpp-enable-if > *
{
display: inline-block;
border-radius: 0.2rem;
background-clip: padding-box !important;
@ -146,7 +46,8 @@ a.tpp-external {
text-decoration: none;
}
.tpp-enable-if > a {
.tpp-enable-if > a
{
white-space: nowrap;
font-size: 0.8rem;
font-weight: bold;
@ -157,22 +58,46 @@ a.tpp-external {
margin-bottom: 2px;
}
.tpp-enable-if > a:hover {
background-color: #747474;
color: initial;
}
.tpp-enable-if > a:hover
{
background-color: #747474;
color: initial;
}
.tpp-enable-if > span {
.tpp-enable-if > span
{
display: none;
padding-left: 2em;
}
nav .m-thin {
nav .m-thin
{
margin-left: 0.5em;
}
nav .github
{
padding-left: 44px !important;
background-image: url("github-icon.png");
background-repeat: no-repeat;
background-size: 25px 25px;
background-position: -30px center;
background-origin: content-box;
}
pre.m-code + pre
{
margin-top: -1.0rem;
color: #bababa; /* is yououou */
background-color: #282e36aa;
font-size: 0.8rem;
}
/* "Parameters", "Returns" etc */
.m-doc-details div table.m-table.m-fullwidth.m-flat thead tr th,
.m-doc-details div table.m-table.m-fullwidth.m-flat tfoot tr th
.m-doc-details div table.m-table.m-fullwidth.m-flat tfoot tr th,
.m-doc-details div table.m-table.m-fullwidth.m-flat tfoot tr td strong em,
.m-doc-details div table.m-table.m-fullwidth.m-flat tbody tr td strong em
{
color: #a5c9ea;
}
@ -216,20 +141,23 @@ nav .m-thin {
/* string literals, "includes" */
.m-code .s,
.m-code .s + .n,
.m-code .sa,
.m-code .dl,
.m-code .cpf
{
color: rgb(214,157,133);
}
.m-code .kt,
.m-code .k
.m-code .k,
.m-code .nc
{
font-weight: normal;
}
/* user types and typedefs */
.m-code .ut
.m-code .ut,
.m-code .nc
{
color: rgb(78,201,176);
}
@ -238,4 +166,4 @@ nav .m-thin {
.m-code .ns
{
color: rgb(140,140,140);
}
}

View File

@ -18,7 +18,7 @@
#include "toml_default_formatter.h"
#include "toml_json_formatter.h"
//macro hygiene
// macro hygiene
#if TOML_UNDEF_MACROS
#undef TOML_EXCEPTIONS
#undef TOML_USE_STREAMS_FOR_FLOATS
@ -53,3 +53,50 @@
#undef TOML_UNDEF_MACROS
#undef TOML_DOXYGEN
#endif
/// \mainpage toml++
///
/// This is the home of the API documentation for toml++, a [TOML](https://github.com/toml-lang/toml) parser for C++17 and later.
/// If you're looking for information about how to add toml++ to your project etc, see the
/// see [README](https://github.com/marzer/tomlplusplus/blob/master/README.md) on GitHub.
/// Otherwise, browse the docs using the links at the top of the page. You can search from anywhere by pressing the TAB key.
///
/// <em>Obviously this page is pretty sparse and could do with some more content. If you have concrete suggestions for what
/// should go here, please [let me know](https://github.com/marzer/tomlplusplus/issues)!</em>
///
/// \cpp
/// #include <iostream>
/// #include <toml++/toml.h>
///
/// int main()
/// {
/// auto tbl = toml::table{{
/// { "lib", "toml++" },
/// { "cpp", toml::array{ 17, 20, "and beyond" } },
/// { "toml", toml::array{ "0.5.0", "and beyond" } },
/// { "repo", "https://github.com/marzer/tomlplusplus/" },
/// { "author", toml::table{{
/// { "name", "Mark Gillard" },
/// { "github", "https://github.com/marzer" },
/// { "twitter", "https://twitter.com/marzer8789" }
/// }}
/// },
/// }};
///
/// std::cout << tbl << std::endl;
/// return 0;
/// }
/// \ecpp
///
/// \out
/// cpp = [ 17, 20, "and beyond" ]
/// lib = "toml++"
/// repo = "https://github.com/marzer/tomlplusplus/"
/// toml = [ "0.5.0", "and beyond" ]
///
/// [author]
/// github = "https://github.com/marzer"
/// name = "Mark Gillard"
/// twitter = "https://twitter.com/marzer8789"
/// \eout
///

View File

@ -197,7 +197,7 @@ namespace toml
/// arr[i].visit([=](auto&& el) noexcept
/// {
/// if constexpr (toml::is_integer<decltype(el)>)
/// el++;
/// (*el)++;
/// else
/// el = "six"sv;
/// });
@ -213,12 +213,14 @@ namespace toml
/// arr.emplace_back<toml::array>(10, 11.0);
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2, 3, 4, "five"]
/// // [2, 3, 4, 5, "six"]
/// // [3, 4, 5, "six", 7, 8.0, "nine"]
/// // [3, 4, 5, "six", 7, 8.0, "nine", [10, 11.0]]
/// \ecpp
///
/// \out
/// [1, 2, 3, 4, "five"]
/// [2, 3, 4, 5, "six"]
/// [3, 4, 5, "six", 7, 8.0, "nine"]
/// [3, 4, 5, "six", 7, 8.0, "nine", [10, 11.0]]
/// \eout
class array final
: public node
{
@ -268,9 +270,11 @@ namespace toml
/// auto arr = toml::array{ 1, 2.0, "three"sv, toml::array{ 4, 5 } };
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2.0, "three", [4, 5]]
/// \ecpp
///
/// \out
/// [1, 2.0, "three", [4, 5]]
/// \eout
///
/// \tparam U One of the TOML node or value types (or a type promotable to one).
/// \tparam V One of the TOML node or value types (or a type promotable to one).
@ -319,16 +323,18 @@ namespace toml
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << std::endl;
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << std::endl;
///
/// // output:
/// // homogeneous: true
/// // all doubles: false
/// // all arrays: false
/// // all integers: true
/// \ecpp
///
/// \tparam T A TOML node type.
/// - Provide an explicit type for "is every node a T?"
/// - Leave it as `void` for "is every node the same type?"
/// \out
/// homogeneous: true
/// all doubles: false
/// all arrays: false
/// all integers: true
/// \eout
///
/// \tparam T A TOML node type. <br>
/// <strong><em>Explicitly specified:</em></strong> "is every node a T?" <br>
/// <strong><em>Left as `void`:</em></strong> "is every node the same type?"
///
/// \returns True if the array was homogeneous.
///
@ -407,10 +413,12 @@ namespace toml
/// arr.insert(arr.cend(), toml::array{ 4, 5 });
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, "two", 3, [4, 5]]
/// \ecpp
///
/// \out
/// [1, "two", 3, [4, 5]]
/// \eout
///
/// \tparam U One of the TOML node or value types (or a type promotable to one).
/// \param pos The insertion position.
/// \param val The value being inserted.
@ -432,16 +440,18 @@ namespace toml
/// arr.insert(arr.cbegin() + 1, 3, "honk");
/// std::cout << arr << std::endl;
///
/// // output:
/// // [
/// // "with an evil twinkle in its eye the goose said",
/// // "honk",
/// // "honk",
/// // "honk",
/// // "and immediately we knew peace was never an option."
/// // ]
/// \ecpp
///
/// \out
/// [
/// "with an evil twinkle in its eye the goose said",
/// "honk",
/// "honk",
/// "honk",
/// "and immediately we knew peace was never an option."
/// ]
/// \eout
///
/// \tparam U One of the TOML value types (or a type promotable to one).
/// \param pos The insertion position.
/// \param count The number of times the value should be inserted.
@ -533,10 +543,12 @@ namespace toml
/// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, "drill" 2]
/// \ecpp
///
/// \out
/// [1, "drill" 2]
/// \eout
///
/// \tparam U One of the TOML node or value types.
/// \tparam V Value constructor argument types.
/// \param pos The insertion position.
@ -544,7 +556,7 @@ namespace toml
///
/// \returns An iterator to the inserted value.
///
/// \remarks There is no difference between insert and emplace
/// \remarks There is no difference between insert() and emplace()
/// for trivial value types (floats, ints, bools).
template <typename U, typename... V>
iterator emplace(const_iterator pos, V&&... args) noexcept
@ -567,11 +579,13 @@ namespace toml
/// arr.erase(arr.cbegin() + 1);
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2, 3]
/// // [1, 3]
/// \ecpp
///
/// \out
/// [1, 2, 3]
/// [1, 3]
/// \eout
///
/// \param pos Iterator to the node being erased.
///
/// \returns Iterator to the first node immediately following the removed node.
@ -589,11 +603,13 @@ namespace toml
/// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, "bad", "karma", 3]
/// // [1, 3]
/// \ecpp
///
/// \out
/// [1, "bad", "karma", 3]
/// [1, 3]
/// \eout
///
/// \param first Iterator to the first node being erased.
/// \param last Iterator to the one-past-the-last node being erased.
///
@ -609,13 +625,15 @@ namespace toml
/// auto arr = toml::array{ 1, 2 };
/// arr.push_back(3);
/// arr.push_back(4.0);
/// arr.push_back(array{ 5, "six"sv });
/// arr.push_back(toml::array{ 5, "six"sv });
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2, 3, 4.0, [5, "six"]]
/// \ecpp
///
/// \out
/// [1, 2, 3, 4.0, [5, "six"]]
/// \eout
///
/// \tparam U One of the TOML value types (or a type promotable to one).
/// \param val The value being added.
///
@ -632,13 +650,15 @@ namespace toml
///
/// \detail \cpp
/// auto arr = toml::array{ 1, 2 };
/// arr.emplace_back<array>(3, "four"sv);
/// arr.emplace_back<toml::array>(3, "four"sv);
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2, [3, "four"]]
/// \ecpp
///
/// \out
/// [1, 2, [3, "four"]]
/// \eout
///
/// \tparam U One of the TOML value types.
/// \tparam V Value constructor argument types.
/// \param args Arguments to forward to the value's constructor.
@ -671,19 +691,21 @@ namespace toml
///
/// \detail \cpp
/// auto arr = toml::array{ 99, "bottles of beer on the wall" };
/// std::cout << R"(node [0] exists: )"sv << !!arr.get(0) << std::endl;
/// std::cout << R"(node [1] exists: )"sv << !!arr.get(1) << std::endl;
/// std::cout << R"(node [2] exists: )"sv << !!arr.get(2) << std::endl;
/// std::cout << "node [0] exists: "sv << !!arr.get(0) << std::endl;
/// std::cout << "node [1] exists: "sv << !!arr.get(1) << std::endl;
/// std::cout << "node [2] exists: "sv << !!arr.get(2) << std::endl;
/// if (auto val = arr.get(0))
/// std::cout << R"(node [0] was an )"sv << val->type() << std::endl;
/// std::cout << "node [0] was an "sv << val->type() << std::endl;
///
/// // output:
/// // node [0] exists: true
/// // node [1] exists: true
/// // node [2] exists: false
/// // node [0] was an integer
/// \ecpp
///
/// \out
/// node [0] exists: true
/// node [1] exists: true
/// node [2] exists: false
/// node [0] was an integer
/// \eout
///
/// \param index The node's index.
///
/// \returns A pointer to the node at the specified index if one existed, or nullptr.
@ -709,10 +731,12 @@ namespace toml
/// if (auto val = arr.get_as<int64_t>(0))
/// std::cout << "node [0] was an integer with value "sv << **val << std::endl;
///
/// // output:
/// // node [0] was an integer with value 42
/// \ecpp
///
/// \out
/// node [0] was an integer with value 42
/// \eout
///
/// \tparam T The node's type.
/// \param index The node's index.
///
@ -822,12 +846,13 @@ namespace toml
/// arr.flatten();
/// std::cout << arr << std::endl;
///
/// // output:
/// // [1, 2, [3, 4, [5]], 6, []]
/// // [1, 2, 3, 4, 5, 6]
///
/// \ecpp
///
/// \out
/// [1, 2, [3, 4, [5]], 6, []]
/// [1, 2, 3, 4, 5, 6]
/// \eout
///
/// \remarks Arrays inside child tables are not flattened.
void flatten() TOML_MAY_THROW
{

View File

@ -276,6 +276,8 @@ namespace toml
{
using namespace std::string_literals;
using namespace std::string_view_literals;
using size_t = std::size_t;
using ptrdiff_t = std::ptrdiff_t;
[[nodiscard]] TOML_ALWAYS_INLINE
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
@ -350,18 +352,19 @@ namespace toml
/// << table.get("description")->source().begin()
/// << std::endl;
///
/// // possible output:
/// // The value 'description' was defined at line 7, column 15
/// \ecpp
///
/// \out
/// The value 'description' was defined at line 7, column 15
/// \eout
///
/// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
/// various non-conventional whitespace and newline characters, but it doesn't give
/// much thought to combining marks, grapheme clusters vs. characters, et cetera.
/// If a TOML document contains lots of codepoints outside of the ASCII range
/// you may find that your source_positions don't match those given by a text editor
/// (typically the line numbers will be accurate but column numbers will be too high).
/// <br><br>
/// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off
/// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
/// between parser complexity and correctness.
struct source_position
{
@ -412,8 +415,25 @@ namespace toml
|| (lhs.line == rhs.line && lhs.column <= rhs.column);
}
/// \brief Prints a source_position to a stream.
///
/// \detail \cpp
/// auto tbl = toml::parse("bar = 42"sv);
///
/// std::cout << "The value for 'bar' was found on "sv
/// << tbl.get("bar")->source()
/// << std::endl;
///
/// \ecpp
///
/// \out
/// The value for 'bar' was found on line 1, column 7
/// \eout
///
/// \param lhs The stream.
/// \param rhs The source_position.
///
/// \returns The input stream.
template <typename CHAR>
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_position& rhs)
TOML_MAY_THROW;
@ -425,23 +445,31 @@ namespace toml
/// \brief A source document region.
///
/// \detail \cpp
/// auto table = toml::parse_file("config.toml"sv);
/// std::cout << "The node 'server' was defined at "sv
/// << table.get("server")->source()
/// << std::endl;
/// #include <fstream>
///
/// auto tbl = toml::parse_file("config.toml"sv);
/// if (auto server = tbl.get("server"))
/// {
/// std::cout << "begin: "sv << server->source().begin << std::endl;
/// std::cout << "end: "sv << server->source().end << std::endl;
/// std::cout << "path: "sv << *server->source().path << std::endl;
/// }
///
/// // possible output:
/// // The node 'server' was defined at line 3, column 1 - line 10, column 25 of 'config.toml'
/// \ecpp
///
/// \out
/// begin: line 3, column 1
/// end: line 3, column 22
/// path: config.toml
/// \eout
///
/// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
/// various non-conventional whitespace and newline characters, but it doesn't give
/// much thought to combining marks, grapheme clusters vs. characters, et cetera.
/// If a TOML document contains lots of codepoints outside of the ASCII range
/// you may find that your source_positions don't match those given by a text editor
/// (typically the line numbers will be accurate but column numbers will be too high).
/// <br><br>
/// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off
/// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
/// between parser complexity and correctness.
struct source_region
{
@ -457,6 +485,24 @@ namespace toml
source_path_ptr path;
/// \brief Prints a source_region to a stream.
///
/// \detail \cpp
/// auto tbl = toml::parse("bar = 42", "config.toml");
///
/// std::cout << "The value for 'bar' was found on "sv
/// << tbl.get("bar")->source()
/// << std::endl;
///
/// \ecpp
///
/// \out
/// The value for 'bar' was found on line 1, column 7 of 'config.toml'
/// \eout
///
/// \param lhs The stream.
/// \param rhs The source_position.
///
/// \returns The input stream.
template <typename CHAR>
friend std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, const source_region& rhs)
TOML_MAY_THROW;
@ -469,7 +515,7 @@ namespace toml
/// \brief An error thrown/returned when parsing fails.
///
/// \remarks This class inherits from `std::runtime_error` when exceptions are enabled.
/// \remarks This class inherits from std::runtime_error when exceptions are enabled.
/// The public interface is the same regardless of exception mode.
class parse_error final
{
@ -810,12 +856,14 @@ namespace toml
/// for (size_t i = 0; i < arr.size() i++)
/// std::cout << "Element ["sv << i << "] is: "sv << arr[i].type() << std::endl;
///
/// // output:
/// // Element [0] is: integer
/// // Element [1] is: floating-point
/// // Element [2] is: string
/// // Element [3] is: boolean
/// \ecpp
///
/// \out
/// Element [0] is: integer
/// Element [1] is: floating-point
/// Element [2] is: string
/// Element [3] is: boolean
/// \eout
template <typename CHAR>
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs) TOML_MAY_THROW
{

View File

@ -116,13 +116,15 @@ namespace toml
/// std::cout << time_offset::from_hh_mm(-2, -30) << std::endl;
/// std::cout << time_offset::from_hh_mm(0,0) << std::endl;
///
/// // output:
/// // +02:30
/// // -01:30
/// // -02:30
/// // Z
/// \ecpp
///
/// \out
/// +02:30
/// -01:30
/// -02:30
/// Z
/// \eout
///
/// \param hours The total hours.
/// \param minutes The total minutes.
///

View File

@ -151,15 +151,17 @@ namespace toml
/// std::cout << toml::default_formatter{ tbl } << std::endl;
/// std::cout << tbl << std::endl;
///
/// // output (twice):
/// // description = "This is some TOML, yo."
/// // fruit = ["apple", "orange", "pear"]
/// // numbers = [1, 2, 3, 4, 5]
/// //
/// // [table]
/// // foo = "bar"
/// \ecpp
///
/// \out
/// description = "This is some TOML, yo."
/// fruit = ["apple", "orange", "pear"]
/// numbers = [1, 2, 3, 4, 5]
///
/// [table]
/// foo = "bar"
/// \eout
///
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
template <typename CHAR = char>
class default_formatter final : impl::formatter<CHAR>
@ -395,7 +397,7 @@ namespace toml
case node_type::table:
{
auto& tbl = *reinterpret_cast<const table*>(&base::source());
if (tbl.is_inline() || (base::flags() & format_flags::always_print_as_inline) != format_flags::none)
if (tbl.is_inline())
print_inline(tbl);
else
{

View File

@ -3,11 +3,11 @@
namespace toml
{
/// \brief Format flags for modifying how TOML data is printed to streams.
enum class format_flags : uint8_t
{
none,
always_print_as_inline = 1,
quote_dates_and_times = 2
quote_dates_and_times = 1
};
[[nodiscard]] constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
{

View File

@ -16,22 +16,24 @@ namespace toml
/// )"sv);
/// std::cout << toml::json_formatter{ some_toml } << std::endl;
///
/// // output:
/// // {
/// // "fruit" : {
/// // "apple" : {
/// // "color" : "red",
/// // "taste" : {
/// // "sweet" : true
/// // },
/// // "texture" : {
/// // "smooth" : true
/// // }
/// // }
/// // }
/// // }
/// \ecpp
///
/// \out
/// {
/// "fruit" : {
/// "apple" : {
/// "color" : "red",
/// "taste" : {
/// "sweet" : true
/// },
/// "texture" : {
/// "smooth" : true
/// }
/// }
/// }
/// }
/// \eout
///
/// \tparam CHAR The underlying character type of the output stream. Must be 1 byte in size.
template <typename CHAR = char>
class json_formatter final : impl::formatter<CHAR>

View File

@ -365,7 +365,7 @@ namespace toml
/// else if constexpr (toml::is_integer<decltype(n)>)
/// do_something_with_an_int(*n); //n is a toml::value<int64_t>
/// else
/// throw std::exception("Expected string or integer")
/// throw std::exception{ "Expected string or integer" };
/// });
///
/// \ecpp

View File

@ -10,9 +10,22 @@ namespace toml
/// \brief The result of a parsing operation.
///
/// \attention This type only exists when exceptions are disabled.
/// When exceptions are enabled parse_result is just an alias for toml::table
/// and parsing failures are indicated by raising a toml::parse_error as an exception.
/// \warning <strong>This type only exists when exceptions are disabled.</strong>
/// Otherwise parse_result is just an alias for toml::table: \cpp
/// #if ARE_EXCEPTIONS_ENABLED // some compiler-specific test
///
/// using parse_result = table;
/// // parsing failures are indicated by throwing a toml::parse_error as an exception
///
/// #else
///
/// class parse_result final
/// {
/// // ...
/// };
///
/// #endif
/// \ecpp
///
/// \detail A parse_result is effectively a discriminated union containing either a toml::table
/// or a toml::parse_error. Most member functions assume a particular one of these two states,
@ -48,7 +61,6 @@ namespace toml
public:
/// \brief Returns true if parsing succeeeded.
[[nodiscard]] bool succeeded() const noexcept { return !is_err; }
/// \brief Returns true if parsing failed.
@ -56,7 +68,6 @@ namespace toml
/// \brief Returns true if parsing succeeeded.
[[nodiscard]] explicit operator bool() const noexcept { return !is_err; }
/// \brief Returns the internal toml::table.
[[nodiscard]] table& get() & noexcept
{
@ -123,6 +134,8 @@ namespace toml
::new (&storage) parse_error{ std::move(err) };
}
/// \brief Move constructor.
TOML_NODISCARD_CTOR
parse_result(parse_result&& res) noexcept
: is_err{ res.is_err }
@ -133,6 +146,7 @@ namespace toml
::new (&storage) table{ std::move(res).get() };
}
/// \brief Move-assignment operator.
parse_result& operator=(parse_result&& rhs) noexcept
{
if (is_err != rhs.is_err)
@ -154,6 +168,7 @@ namespace toml
return *this;
}
/// \brief Destructor.
~parse_result() noexcept
{
destroy();
@ -3053,17 +3068,19 @@ namespace toml
/// auto tbl = toml::parse("a = 3"sv);
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
/// If you don't have a path (or you have no intention of using paths in diagnostics)
/// then this parameter can safely be left blank.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
[[nodiscard]]
inline parse_result parse(std::string_view doc, std::string_view source_path = {}) TOML_MAY_THROW
{
@ -3077,15 +3094,17 @@ namespace toml
/// auto tbl = toml::parse("a = 3"sv, "foo.toml");
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
[[nodiscard]]
inline parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW
{
@ -3100,17 +3119,19 @@ namespace toml
/// auto tbl = toml::parse(u8"a = 3"sv);
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
/// If you don't have a path (or you have no intention of using paths in diagnostics)
/// then this parameter can safely be left blank.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
///
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
[[nodiscard]]
@ -3125,15 +3146,17 @@ namespace toml
/// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
///
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
[[nodiscard]]
@ -3153,18 +3176,20 @@ namespace toml
/// auto tbl = toml::parse(ss);
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \tparam CHAR The stream's underlying character type. Must be 1 byte in size.
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
/// If you don't have a path (or you have no intention of using paths in diagnostics)
/// then this parameter can safely be left blank.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
template <typename CHAR>
[[nodiscard]]
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string_view source_path = {}) TOML_MAY_THROW
@ -3186,16 +3211,18 @@ namespace toml
/// auto tbl = toml::parse(ss, "foo.toml");
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \tparam CHAR The stream's underlying character type. Must be 1 byte in size.
/// \param doc The TOML document to parse. Must be valid UTF-8.
/// \param source_path The path used to initialize each node's `source().path`.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
template <typename CHAR>
[[nodiscard]]
inline parse_result parse(std::basic_istream<CHAR>& doc, std::string&& source_path) TOML_MAY_THROW
@ -3222,8 +3249,8 @@ namespace toml
/// \tparam CHAR The path's character type. Must be 1 byte in size.
/// \param file_path The TOML document to parse. Must be valid UTF-8.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
///
/// \attention You must `#include <fstream>` to use this function (toml++
/// does not transitively include it for you).
@ -3260,15 +3287,17 @@ namespace toml
/// auto tbl = "a = 3"_toml;
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param str The string data.
/// \param len The string length.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
[[nodiscard]]
inline parse_result operator"" _toml(const char* str, size_t len) noexcept
{
@ -3285,15 +3314,17 @@ namespace toml
/// auto tbl = u8"a = 3"_toml;
/// std::cout << tbl["a"] << std::endl;
///
/// // output:
/// // 3
/// \ecpp
///
/// \out
/// 3
/// \eout
///
/// \param str The string data.
/// \param len The string length.
///
/// \returns <em>With exceptions:</em> A toml::table. <br>
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
///
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
[[nodiscard]]

View File

@ -310,12 +310,6 @@ namespace toml
"The stream's underlying character type must be 1 byte in size."
);
lhs << rhs.begin;
if (rhs.begin < rhs.end
&& (rhs.end.line != rhs.begin.line || rhs.end.column > rhs.begin.column + source_index{1}))
{
impl::print_to_stream(" - "sv, lhs);
lhs << rhs.end;
}
if (rhs.path)
{
impl::print_to_stream(" of '"sv, lhs);

View File

@ -118,12 +118,6 @@ namespace toml
/// additional considerations made for the heterogeneous nature of a
/// TOML table, and for the removal of some cruft (the public interface of
/// std::map is, simply, _a hot mess_).
///
/// \detail \cpp
/// // example
/// // code
/// // here
/// \ecpp
class table final
: public node
{
@ -155,10 +149,12 @@ namespace toml
/// }};
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { foo = 1, bar = 2.0, kek = "three" }
/// \ecpp
///
/// \out
/// { foo = 1, bar = 2.0, kek = "three" }
/// \eout
///
/// \tparam N Number of key-value pairs used to initialize the table.
/// \param arr An array of key-value pairs used to initialize the table.
///
@ -235,18 +231,20 @@ namespace toml
/// std::cout << "is inline? "sv << tbl.is_inline() << std::endl;
/// std::cout << tbl << std::endl;
///
/// // example output:
/// // is inline? false
/// // a = 1
/// // b = 2
/// // c = 3
/// // [d]
/// // e = 4
/// //
/// // is inline? true
/// // { a = 1, b = 2, c = 3, d = { e = 4 } }
/// \ecpp
///
/// \out
/// is inline? false
/// a = 1
/// b = 2
/// c = 3
/// [d]
/// e = 4
///
/// is inline? true
/// { a = 1, b = 2, c = 3, d = { e = 4 } }
/// \eout
///
/// \remarks A table being 'inline' is only relevent during printing;
/// it has no effect on the general functionality of the table
/// object.
@ -262,7 +260,7 @@ namespace toml
///
/// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
/// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
/// This Is Not An Error (tm).
/// <strong>This is not an error.</strong>
///
/// \see toml::node_view
[[nodiscard]] inline node_view<table> operator[] (string_view key) noexcept;
@ -308,13 +306,15 @@ namespace toml
/// }
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // inserted a value with key 'a': false
/// // inserted a value with key 'd': true
/// // { a = 1, b = 2, c = 3, d = 42 }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// inserted a value with key 'a': false
/// inserted a value with key 'd': true
/// { a = 1, b = 2, c = 3, d = 42 }
/// \eout
///
/// \tparam K toml::string (or a type convertible to it).
/// \tparam V One of the TOML value types (or a type promotable to one).
/// \param key The key at which to insert the new value.
@ -354,11 +354,13 @@ namespace toml
/// tbl.insert(kvps.begin(), kvps.end());
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // { a = 1, b = 2, c = 3, d = 42 } //"a" already existed
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// { a = 1, b = 2, c = 3, d = 42 } //"a" already existed
/// \eout
///
/// \tparam ITER An InputIterator to a collection of key-value pairs.
/// \param first An iterator to the first value in the input collection.
/// \param last An iterator to one-past-the-last value in the input collection.
@ -400,13 +402,15 @@ namespace toml
/// }
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // value at key 'a' was assigned
/// // value at key 'd' was inserted
/// // { a = 42, b = 2, c = 3, d = 42 }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// value at key 'a' was assigned
/// value at key 'd' was inserted
/// { a = 42, b = 2, c = 3, d = 42 }
/// \eout
///
/// \tparam K toml::string (or a type convertible to it).
/// \tparam V One of the TOML value types (or a type promotable to one).
/// \param key The key at which to insert or assign the value.
@ -449,13 +453,15 @@ namespace toml
/// }
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // emplaced a value with key 'a': false
/// // emplaced a value with key 'd': true
/// // { a = 1, b = 2, c = 3, d = "drill" }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// emplaced a value with key 'a': false
/// emplaced a value with key 'd': true
/// { a = 1, b = 2, c = 3, d = "drill" }
/// \eout
///
/// \tparam U One of the TOML node or value types.
/// \tparam K toml::string (or a type convertible to it).
/// \tparam V Value constructor argument types.
@ -466,7 +472,7 @@ namespace toml
/// - An iterator to the emplacement position (or the position of the value that prevented emplacement)
/// - A boolean indicating if the emplacement was successful.
///
/// \remark There is no difference between insert and emplace for trivial value types (floats, ints, bools).
/// \remark There is no difference between insert() and emplace() for trivial value types (floats, ints, bools).
template <typename U, typename K, typename... V>
std::pair<iterator, bool> emplace(K&& key, V&&... args) noexcept
{
@ -502,11 +508,13 @@ namespace toml
/// tbl.erase(tbl.begin() + 1);
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // { a = 1, c = 3 }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// { a = 1, c = 3 }
/// \eout
///
/// \param pos Iterator to the key-value pair being erased.
///
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
@ -528,11 +536,13 @@ namespace toml
/// tbl.erase(tbl.cbegin() + 1);
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // { a = 1, c = 3 }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// { a = 1, c = 3 }
/// \eout
///
/// \param pos Iterator to the key-value pair being erased.
///
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
@ -555,11 +565,13 @@ namespace toml
/// tbl.erase(tbl.cbegin() + 1, tbl.cbegin() + 3);
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = "bad", c = "karma", d = 2 }
/// // { a = 1, d = 2 }
/// \ecpp
///
/// \out
/// { a = 1, b = "bad", c = "karma", d = 2 }
/// { a = 1, d = 2 }
/// \eout
///
/// \param first Iterator to the first key-value pair being erased.
/// \param last Iterator to the one-past-the-last key-value pair being erased.
///
@ -583,13 +595,15 @@ namespace toml
/// std::cout << tbl.erase("not an existing key") << std::endl;
/// std::cout << tbl << std::endl;
///
/// // output:
/// // { a = 1, b = 2, c = 3 }
/// // true
/// // false
/// // { a = 1, c = 3 }
/// \ecpp
///
/// \out
/// { a = 1, b = 2, c = 3 }
/// true
/// false
/// { a = 1, c = 3 }
/// \eout
///
/// \param key Key to erase.
///
/// \returns True if any values with matching keys were found and erased.
@ -652,13 +666,15 @@ namespace toml
/// if (auto val = arr.get("a"))
/// std::cout << R"(node ["a"] was an )"sv << val->type() << std::endl;
///
/// // output:
/// // node ["a"] exists: true
/// // node ["b"] exists: true
/// // node ["c"] exists: false
/// // node ["a"] was an integer
/// \ecpp
///
/// \out
/// node ["a"] exists: true
/// node ["b"] exists: true
/// node ["c"] exists: false
/// node ["a"] was an integer
/// \eout
///
/// \tparam T The node's type.
/// \param key The node's key.
///
@ -686,10 +702,12 @@ namespace toml
/// if (auto val = arr.get_as<int64_t>("a"))
/// std::cout << R"(node ["a"] was an integer with value )"sv << **val << std::endl;
///
/// // output:
/// // node ["a"] was an integer with value 42
/// \ecpp
///
/// \out
/// node ["a"] was an integer with value 42
/// \eout
///
/// \tparam T The node's type.
/// \param key The node's key.
///

View File

@ -41,6 +41,9 @@ namespace toml
public:
/// \brief The value's underlying data type.
using value_type = T;
/// \brief Constructs a toml value.
///
/// \tparam U Constructor argument types.
@ -93,20 +96,34 @@ namespace toml
[[nodiscard]] bool is_time() const noexcept override { return std::is_same_v<T, time>; }
[[nodiscard]] bool is_date_time() const noexcept override { return std::is_same_v<T, date_time>; }
/// \brief Returns a pointer to the value if the data type is a string.
[[nodiscard]] value<string>* as_string() noexcept override { return as_value<string>(this); }
/// \brief Returns a pointer to the value if the data type is an integer.
[[nodiscard]] value<int64_t>* as_integer() noexcept override { return as_value<int64_t>(this); }
/// \brief Returns a pointer to the value if the data type is a floating-point.
[[nodiscard]] value<double>* as_floating_point() noexcept override { return as_value<double>(this); }
/// \brief Returns a pointer to the value if the data type is boolean.
[[nodiscard]] value<bool>* as_boolean() noexcept override { return as_value<bool>(this); }
/// \brief Returns a pointer to the value if the data type is a date.
[[nodiscard]] value<date>* as_date() noexcept override { return as_value<date>(this); }
/// \brief Returns a pointer to the value if the data type is a time.
[[nodiscard]] value<time>* as_time() noexcept override { return as_value<time>(this); }
/// \brief Returns a pointer to the value if the data type is date-time.
[[nodiscard]] value<date_time>* as_date_time() noexcept override { return as_value<date_time>(this); }
/// \brief Returns a const pointer to the value if the data type is a string.
[[nodiscard]] const value<string>* as_string() const noexcept override { return as_value<string>(this); }
/// \brief Returns a const pointer to the value if the data type is an integer.
[[nodiscard]] const value<int64_t>* as_integer() const noexcept override { return as_value<int64_t>(this); }
/// \brief Returns a const pointer to the value if the data type is a floating-point.
[[nodiscard]] const value<double>* as_floating_point() const noexcept override { return as_value<double>(this); }
/// \brief Returns a const pointer to the value if the data type is a boolean.
[[nodiscard]] const value<bool>* as_boolean() const noexcept override { return as_value<bool>(this); }
/// \brief Returns a const pointer to the value if the data type is a date.
[[nodiscard]] const value<date>* as_date() const noexcept override { return as_value<date>(this); }
/// \brief Returns a const pointer to the value if the data type is a time.
[[nodiscard]] const value<time>* as_time() const noexcept override { return as_value<time>(this); }
/// \brief Returns a const pointer to the value if the data type is a date-time.
[[nodiscard]] const value<date_time>* as_date_time() const noexcept override { return as_value<date_time>(this); }
/// \brief Returns a reference to the underlying value.
@ -148,13 +165,34 @@ namespace toml
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<T, string>,
string_view,
std::conditional_t<impl::is_one_of<T, double, int64_t, bool>, T, const T&>
>;
/// \brief Value-assignment operator.
value& operator= (value_arg_t rhs) noexcept
{
if constexpr (std::is_same_v<T, string>)
val_.assign(rhs);
else
val_ = rhs;
return *this;
}
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, string>>>
value& operator= (string&& rhs) noexcept
{
val_ = std::move(rhs);
return *this;
}
/// \brief Value equality operator.
[[nodiscard]] friend bool operator == (const value& lhs, value_arg_t rhs) noexcept { return lhs.val_ == rhs; }
/// \brief Value equality operator.
@ -217,8 +255,8 @@ namespace toml
/// \param lhs The LHS toml::value.
/// \param rhs The RHS toml::value.
///
/// \returns Values of the same data type: `lhs.get() < rhs.get()` <br>
/// Values of different types: `lhs.type() < rhs.type()`
/// \returns <strong><em>Same value types:</em></strong> `lhs.get() < rhs.get()` <br>
/// <strong><em>Different value types:</em></strong> `lhs.type() < rhs.type()`
template <typename U>
[[nodiscard]] friend bool operator < (const value& lhs, const value<U>& rhs) noexcept
{
@ -233,8 +271,8 @@ namespace toml
/// \param lhs The LHS toml::value.
/// \param rhs The RHS toml::value.
///
/// \returns Values of the same data type: `lhs.get() <= rhs.get()` <br>
/// Values of different types: `lhs.type() <= rhs.type()`
/// \returns <strong><em>Same value types:</em></strong> `lhs.get() <= rhs.get()` <br>
/// <strong><em>Different value types:</em></strong> `lhs.type() <= rhs.type()`
template <typename U>
[[nodiscard]] friend bool operator <= (const value& lhs, const value<U>& rhs) noexcept
{
@ -249,8 +287,8 @@ namespace toml
/// \param lhs The LHS toml::value.
/// \param rhs The RHS toml::value.
///
/// \returns Values of the same data type: `lhs.get() > rhs.get()` <br>
/// Values of different types: `lhs.type() > rhs.type()`
/// \returns <strong><em>Same value types:</em></strong> `lhs.get() > rhs.get()` <br>
/// <strong><em>Different value types:</em></strong> `lhs.type() > rhs.type()`
template <typename U>
[[nodiscard]] friend bool operator > (const value& lhs, const value<U>& rhs) noexcept
{
@ -265,8 +303,8 @@ namespace toml
/// \param lhs The LHS toml::value.
/// \param rhs The RHS toml::value.
///
/// \returns Values of the same data type: `lhs.get() >= rhs.get()` <br>
/// Values of different types: `lhs.type() >= rhs.type()`
/// \returns <strong><em>Same value types:</em></strong> `lhs.get() >= rhs.get()` <br>
/// <strong><em>Different value types:</em></strong> `lhs.type() >= rhs.type()`
template <typename U>
[[nodiscard]] friend bool operator >= (const value& lhs, const value<U>& rhs) noexcept
{

View File

@ -30,8 +30,12 @@ type_names = [
'date_time',
'string',
'string_view',
'string_char',
'parse_result',
'parse_error',
'json_formatter',
'default_formatter',
'format_flags',
'size_t',
'uint8_t',
'uint16_t',
@ -64,8 +68,11 @@ all_namespaces = [
'literals',
'impl'
]
string_literals = [
's',
'sv',
'_toml'
]
def is_tool(name):
return shutil.which(name) is not None
@ -509,33 +516,65 @@ class InlineNamespaceFix3(InlineNamespaceFixBase):
# adds some additional colouring to the syntax highlighting in code blocks.
class SyntaxHighlightingFix(object):
__missing_keywords = [
'constexpr',
'if'
]
def __call__(self, file, doc):
global type_names
global all_namespaces
global string_literals
code_blocks = doc.body('pre', class_='m-code')
changed = False
for code_block in code_blocks:
names = code_block('span', class_='n')
# namespaces
names = code_block('span', class_='n')
names_ = []
for name in names:
if (name.string is None or name.string not in all_namespaces):
names_.append(name)
continue
next = name.next_sibling
if (next is None or next.string is None or next.string != '::'):
names_.append(name)
continue
next.extract()
name.string.replace_with(name.string + '::')
name['class'] = 'ns'
changed = True
# string literals
names = names_
names_ = []
for name in names:
if (name.string is None or name.string not in string_literals):
names_.append(name)
continue
prev = name.previous_sibling
if (prev is None or prev['class'] is None or 's' not in prev['class']):
names_.append(name)
continue
name['class'] = 'sa'
changed = True
# user types and typedefs
names += code_block('span', class_='kt')
names = names_ + code_block('span', class_='kt')
for name in names:
if (name.string is not None and name.string in type_names):
name['class'] = 'ut'
changed = True
# misidentifed keywords
nfs = code_block('span', class_='nf')
for nf in nfs:
if (nf.string is not None and nf.string in self.__missing_keywords):
nf['class'] = 'k'
changed = True
return changed
@ -633,19 +672,19 @@ class ExtDocLinksFix(object):
(r'(?:Legacy)?BidirectionalIterators?', 'https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator'),
(r'(?:Legacy)?RandomAccessIterators?', 'https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator'),
(r'(?:Legacy)?ContiguousIterators?', 'https://en.cppreference.com/w/cpp/named_req/ContiguousIterator'),
(r'(?:Legacy)?Iterators?', 'https://en.cppreference.com/w/cpp/named_req/Iterator'),
#(r'(?:Legacy)?Iterators?', 'https://en.cppreference.com/w/cpp/named_req/Iterator'),
# toml-specific
(r'toml::values?', 'classtoml_1_1value.html'),
(r'(toml::)?date_times?', 'structtoml_1_1date__time.html'),
(r'(toml::)?time', 'structtoml_1_1time.html'),
(r'(toml::)?date', 'structtoml_1_1date.html')
(r'(toml::)?times?', 'structtoml_1_1time.html'),
(r'(toml::)?dates?', 'structtoml_1_1date.html')
]
__allowedNames = ['dd', 'p', 'dt', 'h3', 'td']
def __init__(self):
self.__expressions = []
for type, uri in self.__types:
self.__expressions.append((re.compile(type), uri))
self.__expressions.append((re.compile('(?<![a-zA-Z_])'+type+'(?![a-zA-Z_])'), uri))
@classmethod
def __substitute(cls, m, uri):
@ -858,8 +897,8 @@ def main():
fixes = [
CustomTagsFix()
, SyntaxHighlightingFix()
# , NavBarFix()
, IndexHrefFix()
#, NavBarFix()
#, IndexHrefFix()
, ModifiersFix1()
, ModifiersFix2()
, InlineNamespaceFix1()
@ -882,24 +921,6 @@ def main():
if _threadError:
sys.exit(1)
# replace index.html with a redirect
index_html_path = path.join(html_dir, 'index.html')
with open(index_html_path,'w', encoding='utf-8', newline='\n') as output_file:
print('''<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Refresh" content="0; url=./namespacetoml.html" />
</head>
<body>
<p>Please follow <a href="namespacetoml.html">this link</a>.</p>
</body>
</html>
''',
file=output_file
)
if __name__ == '__main__':
try:

View File

@ -340,6 +340,8 @@ namespace toml
{
using namespace std::string_literals;
using namespace std::string_view_literals;
using size_t = std::size_t;
using ptrdiff_t = std::ptrdiff_t;
[[nodiscard]] TOML_ALWAYS_INLINE
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
@ -1245,12 +1247,6 @@ namespace toml
"The stream's underlying character type must be 1 byte in size."
);
lhs << rhs.begin;
if (rhs.begin < rhs.end
&& (rhs.end.line != rhs.begin.line || rhs.end.column > rhs.begin.column + source_index{1}))
{
impl::print_to_stream(" - "sv, lhs);
lhs << rhs.end;
}
if (rhs.path)
{
impl::print_to_stream(" of '"sv, lhs);
@ -1611,6 +1607,8 @@ namespace toml
public:
using value_type = T;
template <typename... U>
TOML_NODISCARD_CTOR
explicit value(U&&... args) TOML_MAY_THROW_UNLESS(std::is_nothrow_constructible_v<T, U &&...>)
@ -1689,6 +1687,22 @@ namespace toml
std::conditional_t<impl::is_one_of<T, double, int64_t, bool>, T, const T&>
>;
value& operator= (value_arg_t rhs) noexcept
{
if constexpr (std::is_same_v<T, string>)
val_.assign(rhs);
else
val_ = rhs;
return *this;
}
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, string>>>
value& operator= (string&& rhs) noexcept
{
val_ = std::move(rhs);
return *this;
}
[[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; }
@ -7675,8 +7689,7 @@ namespace toml
enum class format_flags : uint8_t
{
none,
always_print_as_inline = 1,
quote_dates_and_times = 2
quote_dates_and_times = 1
};
[[nodiscard]] constexpr format_flags operator & (format_flags lhs, format_flags rhs) noexcept
{
@ -8179,7 +8192,7 @@ namespace toml
case node_type::table:
{
auto& tbl = *reinterpret_cast<const table*>(&base::source());
if (tbl.is_inline() || (base::flags() & format_flags::always_print_as_inline) != format_flags::none)
if (tbl.is_inline())
print_inline(tbl);
else
{
@ -8400,7 +8413,7 @@ namespace toml
#pragma endregion
//------------- ↑ toml_json_formatter.h ------------------------------------------------------------------------------
//macro hygiene
// macro hygiene
#if TOML_UNDEF_MACROS
#undef TOML_EXCEPTIONS
#undef TOML_USE_STREAMS_FOR_FLOATS