diff --git a/README.md b/README.md index 47e9fc3..9ae0c49 100644 --- a/README.md +++ b/README.md @@ -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) - do_something_with_string_values(node) - }); + v.visit([](auto& node) noexcept + { + std::cout << node << std:endl; + if constexpr (toml::is_string) + do_something_with_string_values(node); + }); } // re-serialize as TOML diff --git a/docs/Doxyfile b/docs/Doxyfile index 7e2c232..0b417b3 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -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 diff --git a/docs/Doxyfile-mcss b/docs/Doxyfile-mcss index eb8ca38..a2b25d9 100644 --- a/docs/Doxyfile-mcss +++ b/docs/Doxyfile-mcss @@ -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 \ -##! "Github" +##! "Github" ##! M_SEARCH_DOWNLOAD_BINARY = NO ##! M_CLASS_TREE_EXPAND_LEVELS = 3 ##! M_FILE_TREE_EXPAND_LEVELS = 3 diff --git a/docs/github-icon.png b/docs/github-icon.png new file mode 100644 index 0000000..6e62b6c Binary files /dev/null and b/docs/github-icon.png differ diff --git a/docs/tomlplusplus.css b/docs/tomlplusplus.css index 31e5414..535053e 100644 --- a/docs/tomlplusplus.css +++ b/docs/tomlplusplus.css @@ -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); -} \ No newline at end of file +} diff --git a/include/toml++/toml.h b/include/toml++/toml.h index c56460a..cf112c7 100644 --- a/include/toml++/toml.h +++ b/include/toml++/toml.h @@ -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. +/// +/// 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)! +/// +/// \cpp +/// #include +/// #include +/// +/// 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 +/// diff --git a/include/toml++/toml_array.h b/include/toml++/toml_array.h index 3be33bf..e597ff1 100644 --- a/include/toml++/toml_array.h +++ b/include/toml++/toml_array.h @@ -197,7 +197,7 @@ namespace toml /// arr[i].visit([=](auto&& el) noexcept /// { /// if constexpr (toml::is_integer) - /// el++; + /// (*el)++; /// else /// el = "six"sv; /// }); @@ -213,12 +213,14 @@ namespace toml /// arr.emplace_back(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() << std::endl; /// std::cout << "all integers: "sv << arr.is_homogeneous() << 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.
+ /// Explicitly specified: "is every node a T?"
+ /// Left as `void`: "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(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 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(3, "four"sv); + /// arr.emplace_back(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(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 { diff --git a/include/toml++/toml_common.h b/include/toml++/toml_common.h index 3295928..d9b5d07 100644 --- a/include/toml++/toml_common.h +++ b/include/toml++/toml_common.h @@ -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). - ///

- /// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off + /// This is not an error. 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 friend std::basic_ostream& operator << (std::basic_ostream& 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 + /// + /// 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). - ///

- /// This Is Not An Error (tm). I've chosen this behaviour as a deliberate trade-off + /// This is not an error. 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 friend std::basic_ostream& operator << (std::basic_ostream& 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 inline std::basic_ostream& operator << (std::basic_ostream& lhs, node_type rhs) TOML_MAY_THROW { diff --git a/include/toml++/toml_date_time.h b/include/toml++/toml_date_time.h index b8129ce..878fe97 100644 --- a/include/toml++/toml_date_time.h +++ b/include/toml++/toml_date_time.h @@ -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. /// diff --git a/include/toml++/toml_default_formatter.h b/include/toml++/toml_default_formatter.h index 3cd0bd7..020be1b 100644 --- a/include/toml++/toml_default_formatter.h +++ b/include/toml++/toml_default_formatter.h @@ -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 class default_formatter final : impl::formatter @@ -395,7 +397,7 @@ namespace toml case node_type::table: { auto& tbl = *reinterpret_cast(&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 { diff --git a/include/toml++/toml_formatter.h b/include/toml++/toml_formatter.h index 5d52be8..b2b7a69 100644 --- a/include/toml++/toml_formatter.h +++ b/include/toml++/toml_formatter.h @@ -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 { diff --git a/include/toml++/toml_json_formatter.h b/include/toml++/toml_json_formatter.h index 48370fd..db1634f 100644 --- a/include/toml++/toml_json_formatter.h +++ b/include/toml++/toml_json_formatter.h @@ -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 class json_formatter final : impl::formatter diff --git a/include/toml++/toml_node.h b/include/toml++/toml_node.h index cb19bc9..5e84b98 100644 --- a/include/toml++/toml_node.h +++ b/include/toml++/toml_node.h @@ -365,7 +365,7 @@ namespace toml /// else if constexpr (toml::is_integer) /// do_something_with_an_int(*n); //n is a toml::value /// else - /// throw std::exception("Expected string or integer") + /// throw std::exception{ "Expected string or integer" }; /// }); /// /// \ecpp diff --git a/include/toml++/toml_parser.h b/include/toml++/toml_parser.h index 26e2b53..f114830 100644 --- a/include/toml++/toml_parser.h +++ b/include/toml++/toml_parser.h @@ -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 This type only exists when exceptions are disabled. + /// 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: A toml::parse_result detailing the parsing outcome. template [[nodiscard]] inline parse_result parse(std::basic_istream& 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: A toml::parse_result detailing the parsing outcome. template [[nodiscard]] inline parse_result parse(std::basic_istream& 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: A toml::parse_result detailing the parsing outcome. /// /// \attention You must `#include ` 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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 With exceptions: A toml::table.
- /// Without exceptions: A toml::parse_result detailing the parsing outcome. + /// \returns With exceptions: A toml::table.
+ /// Without exceptions: 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]] diff --git a/include/toml++/toml_print_to_stream.h b/include/toml++/toml_print_to_stream.h index 068701b..16e4318 100644 --- a/include/toml++/toml_print_to_stream.h +++ b/include/toml++/toml_print_to_stream.h @@ -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); diff --git a/include/toml++/toml_table.h b/include/toml++/toml_table.h index 382a644..616b8fe 100644 --- a/include/toml++/toml_table.h +++ b/include/toml++/toml_table.h @@ -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). + /// This is not an error. /// /// \see toml::node_view [[nodiscard]] inline node_view 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 std::pair 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("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. /// diff --git a/include/toml++/toml_value.h b/include/toml++/toml_value.h index 6fca4de..8a74fd8 100644 --- a/include/toml++/toml_value.h +++ b/include/toml++/toml_value.h @@ -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; } [[nodiscard]] bool is_date_time() const noexcept override { return std::is_same_v; } + /// \brief Returns a pointer to the value if the data type is a string. [[nodiscard]] value* as_string() noexcept override { return as_value(this); } + /// \brief Returns a pointer to the value if the data type is an integer. [[nodiscard]] value* as_integer() noexcept override { return as_value(this); } + /// \brief Returns a pointer to the value if the data type is a floating-point. [[nodiscard]] value* as_floating_point() noexcept override { return as_value(this); } + /// \brief Returns a pointer to the value if the data type is boolean. [[nodiscard]] value* as_boolean() noexcept override { return as_value(this); } + /// \brief Returns a pointer to the value if the data type is a date. [[nodiscard]] value* as_date() noexcept override { return as_value(this); } + /// \brief Returns a pointer to the value if the data type is a time. [[nodiscard]] value