added array::get
also: - moved node_of to impl namespace - added a lot more documentation - fixed some bugs in the documentation generator - fixed the license ID breaking github's license recognition
This commit is contained in:
parent
c7483cb92c
commit
1f8f3c7baa
2
LICENSE
2
LICENSE
@ -14,5 +14,3 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
21
README.md
21
README.md
@ -30,6 +30,27 @@ std::string_view library_version = config["library"]["version"].as_string()->get
|
||||
std::string_view library_author = config["library"]["authors"][0].as_string()->get();
|
||||
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"
|
||||
});
|
||||
|
||||
// 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)
|
||||
});
|
||||
}
|
||||
|
||||
// re-serialize as TOML
|
||||
std::cout << config << std::endl;
|
||||
|
||||
// re-serialize as JSON
|
||||
std::cout << toml::json_formatter{ config } << std::endl;
|
||||
|
||||
|
@ -82,7 +82,7 @@ INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
@ -112,7 +112,7 @@ WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_AS_ERROR = YES
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE = ./doc/doxygen_warnings.log
|
||||
#---------------------------------------------------------------------------
|
||||
@ -202,7 +202,7 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
GENERATE_HTML = NO
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
@ -302,9 +302,9 @@ MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
XML_PROGRAMLISTING = YES
|
||||
XML_PROGRAMLISTING = NO
|
||||
XML_NS_MEMB_FILE_SCOPE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the DOCBOOK output
|
||||
@ -336,7 +336,8 @@ PREDEFINED = TOML_DOXYGEN=1 \
|
||||
__cplusplus=201703L \
|
||||
TOML_ALWAYS_INLINE=inline \
|
||||
TOML_MAY_THROW= \
|
||||
TOML_NODISCARD_CTOR=
|
||||
TOML_NODISCARD_CTOR= \
|
||||
__cpp_lib_char8_t=201811L
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1,14 +1,8 @@
|
||||
@INCLUDE = ./Doxyfile
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_XML = YES
|
||||
XML_PROGRAMLISTING = NO
|
||||
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
|
||||
WARN_AS_ERROR = NO
|
||||
TAB_SIZE = 4
|
||||
HTML_EXTRA_FILES = tomlplusplus.js
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
##! M_THEME_COLOR = #22272e
|
||||
##! M_LINKS_NAVBAR1 = \
|
||||
##! namespaces
|
||||
@ -22,4 +16,3 @@ SHOW_INCLUDE_FILES = NO
|
||||
##! <a target="_blank" href="https://github.com/marzer/tomlplusplus/issues">Report an issue</a> \
|
||||
##! <br><br>Documentation generated using <a href="https://mcss.mosra.cz/">m.css</a>
|
||||
##! M_HTML_HEADER = <script src="tomlplusplus.js"></script>
|
||||
##! M_MAIN_PROJECT_URL = https://github.com/marzer/tomlplusplus/
|
||||
|
@ -62,21 +62,6 @@ dl.m-doc dd
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
body > header > nav
|
||||
{
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
html
|
||||
{
|
||||
background-color: #2d2d30;
|
||||
}
|
||||
|
||||
pre, code, .m-label, .tpp-enable-if > a
|
||||
{
|
||||
font-family: 'Consolas', monospace;
|
||||
}
|
||||
|
||||
pre, .m-doc-search-content
|
||||
{
|
||||
background-color: #1e1e1e;
|
||||
@ -186,28 +171,71 @@ nav .m-thin {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.m-code .c1 {
|
||||
color: rgb(87,166,74);
|
||||
}
|
||||
|
||||
.m-code .mi, .m-code .mf {
|
||||
color: rgb(181,206,168);
|
||||
}
|
||||
|
||||
.m-code .k {
|
||||
color: rgb(86,156,214);
|
||||
}
|
||||
|
||||
.m-code .n {
|
||||
color: rgb(220,220,220);
|
||||
}
|
||||
|
||||
.m-code .p {
|
||||
color: rgb(120,120,120);
|
||||
}
|
||||
|
||||
.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
|
||||
{
|
||||
color: #a5c9ea;
|
||||
}
|
||||
|
||||
/* comments */
|
||||
.m-code .c1
|
||||
{
|
||||
color: rgb(87,166,74);
|
||||
}
|
||||
|
||||
/* int and float literals */
|
||||
.m-code .mi,
|
||||
.m-code .mf
|
||||
{
|
||||
color: rgb(181,206,168);
|
||||
}
|
||||
|
||||
/* keywords */
|
||||
.m-code .k
|
||||
{
|
||||
color: rgb(86,156,214);
|
||||
}
|
||||
|
||||
/* identifier names */
|
||||
.m-code .n
|
||||
{
|
||||
color: rgb(220,220,220);
|
||||
}
|
||||
|
||||
/* punctuators (brackets etc) */
|
||||
.m-code .p
|
||||
{
|
||||
color: rgb(120,120,120);
|
||||
}
|
||||
|
||||
/* preprocessor directives */
|
||||
.m-code .cp
|
||||
{
|
||||
color: rgb(120,120,120);
|
||||
}
|
||||
|
||||
/* string literals, "includes" */
|
||||
.m-code .s,
|
||||
.m-code .s + .n,
|
||||
.m-code .cpf
|
||||
{
|
||||
color: rgb(214,157,133);
|
||||
}
|
||||
|
||||
.m-code .kt,
|
||||
.m-code .k
|
||||
{
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* user types and typedefs */
|
||||
.m-code .ut
|
||||
{
|
||||
color: rgb(78,201,176);
|
||||
}
|
||||
|
||||
/* namespace::scopes:: */
|
||||
.m-code .ns
|
||||
{
|
||||
color: rgb(140,140,140);
|
||||
}
|
@ -188,8 +188,8 @@ namespace toml
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto table = toml::parse("arr = [1, 2, 3, 4, 'five']"sv);
|
||||
/// auto& arr = *table.get_as<toml::array>("arr");
|
||||
/// auto tbl = toml::parse("arr = [1, 2, 3, 4, 'five']"sv);
|
||||
/// auto& arr = *tbl.get_as<toml::array>("arr");
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// for (size_t i = 0; i < arr.size(); i++)
|
||||
@ -265,12 +265,7 @@ namespace toml
|
||||
/// \brief Constructs an array with one or more initial values.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2.0,
|
||||
/// "three"sv,
|
||||
/// toml::array{ 4, 5 }
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2.0, "three"sv, toml::array{ 4, 5 } };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
@ -304,7 +299,7 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Always returns `node_type::array` for array nodes.
|
||||
/// \brief Always returns node_type::array for array nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override { return node_type::array; }
|
||||
/// \brief Always returns `false` for array nodes.
|
||||
[[nodiscard]] bool is_table() const noexcept override { return false; }
|
||||
@ -318,11 +313,7 @@ namespace toml
|
||||
/// \brief Checks if the array contains nodes of only one type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// 3
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << std::endl;
|
||||
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << std::endl;
|
||||
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << std::endl;
|
||||
@ -411,10 +402,7 @@ namespace toml
|
||||
/// \brief Inserts a new node at a specific position in the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 3
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 3 };
|
||||
/// arr.insert(arr.cbegin() + 1, "two");
|
||||
/// arr.insert(arr.cend(), toml::array{ 4, 5 });
|
||||
/// std::cout << arr << std::endl;
|
||||
@ -539,10 +527,7 @@ namespace toml
|
||||
/// \brief Emplaces a new value at a specific position in the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2 };
|
||||
///
|
||||
/// //add a string using std::string's substring constructor
|
||||
/// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
|
||||
@ -555,12 +540,12 @@ namespace toml
|
||||
/// \tparam U One of the TOML node or value types.
|
||||
/// \tparam V Value constructor argument types.
|
||||
/// \param pos The insertion position.
|
||||
/// \param args Arguments to pass to the value constructor.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
///
|
||||
/// \returns An iterator to the inserted value.
|
||||
///
|
||||
/// \remarks There is no difference between insert and emplace
|
||||
/// For trivial value types (floats, ints, bools).
|
||||
/// for trivial value types (floats, ints, bools).
|
||||
template <typename U, typename... V>
|
||||
iterator emplace(const_iterator pos, V&&... args) noexcept
|
||||
{
|
||||
@ -570,17 +555,13 @@ namespace toml
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
return { values.emplace(pos.raw_, new node_of<type>{ std::forward<V>(args)...} ) };
|
||||
return { values.emplace(pos.raw_, new impl::node_of<type>{ std::forward<V>(args)...} ) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified node from the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// 3
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2, 3 };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.erase(arr.cbegin() + 1);
|
||||
@ -602,12 +583,7 @@ namespace toml
|
||||
/// \brief Removes the nodes in the range [first, last) from the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// "bad",
|
||||
/// "karma"
|
||||
/// 2,
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, "bad", "karma" 2 };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
|
||||
@ -630,10 +606,7 @@ namespace toml
|
||||
/// \brief Appends a new value to the end of the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2 };
|
||||
/// arr.push_back(3);
|
||||
/// arr.push_back(4.0);
|
||||
/// arr.push_back(array{ 5, "six"sv });
|
||||
@ -658,10 +631,7 @@ namespace toml
|
||||
/// \brief Emplaces a new value at the end of the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2 };
|
||||
/// arr.emplace_back<array>(3, "four"sv);
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
@ -671,7 +641,7 @@ namespace toml
|
||||
///
|
||||
/// \tparam U One of the TOML value types.
|
||||
/// \tparam V Value constructor argument types.
|
||||
/// \param args Arguments to pass to the value constructor.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
///
|
||||
/// \returns A reference to the newly-constructed value node.
|
||||
///
|
||||
@ -686,7 +656,7 @@ namespace toml
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
auto nde = new node_of<type>{ std::forward<V>(args)... };
|
||||
auto nde = new impl::node_of<type>{ std::forward<V>(args)... };
|
||||
values.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
@ -697,13 +667,45 @@ namespace toml
|
||||
values.pop_back();
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific index.
|
||||
///
|
||||
/// \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;
|
||||
/// if (auto val = arr.get(0))
|
||||
/// std::cout << R"(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
|
||||
///
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified index if one existed, or nullptr.
|
||||
[[nodiscard]] node* get(size_t index) noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific index (const overload).
|
||||
///
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified index if one existed, or nullptr.
|
||||
[[nodiscard]] const node* get(size_t index) const noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific index if it is a particular type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{
|
||||
/// 42,
|
||||
/// "is the meaning of life, apparently."sv
|
||||
/// };
|
||||
/// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
|
||||
/// if (auto val = arr.get_as<int64_t>(0))
|
||||
/// std::cout << "node [0] was an integer with value "sv << **val << std::endl;
|
||||
///
|
||||
@ -714,11 +716,13 @@ namespace toml
|
||||
/// \tparam T The node's type.
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the selected node if it existed and was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(size_t index) noexcept
|
||||
[[nodiscard]] impl::node_of<T>* get_as(size_t index) noexcept
|
||||
{
|
||||
return values[index]->as<T>();
|
||||
if (auto val = get(index))
|
||||
return val->as<T>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific index if it is a particular type (const overload).
|
||||
@ -726,11 +730,13 @@ namespace toml
|
||||
/// \tparam T The node's type.
|
||||
/// \param index The node's index.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the selected node if it existed and was of the specified type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(size_t index) const noexcept
|
||||
[[nodiscard]] const impl::node_of<T>* get_as(size_t index) const noexcept
|
||||
{
|
||||
return values[index]->as<T>();
|
||||
if (auto val = get(index))
|
||||
return val->as<T>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// \brief Equality operator.
|
||||
@ -810,17 +816,7 @@ namespace toml
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto arr = toml::array{
|
||||
/// 1,
|
||||
/// 2,
|
||||
/// toml::array{
|
||||
/// 3,
|
||||
/// 4,
|
||||
/// toml::array{ 5 }
|
||||
/// },
|
||||
/// 6,
|
||||
/// toml::array{}
|
||||
/// };
|
||||
/// auto arr = toml::array{ 1, 2, toml::array{ 3, 4, toml::array{ 5 } }, 6, toml::array{} };
|
||||
/// std::cout << arr << std::endl;
|
||||
///
|
||||
/// arr.flatten();
|
||||
|
@ -274,16 +274,13 @@ TOML_POP_WARNINGS
|
||||
/// \brief The root namespace for all toml++ functions and types.
|
||||
namespace toml
|
||||
{
|
||||
inline namespace literals
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<size_t>(n);
|
||||
}
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<size_t>(n);
|
||||
}
|
||||
|
||||
#if TOML_CHAR_8_STRINGS
|
||||
@ -328,9 +325,9 @@ namespace toml
|
||||
integer, ///< The node is a toml::value<int64_t>.
|
||||
floating_point, ///< The node is a toml::value<double>.
|
||||
boolean, ///< The node is a toml::value<bool>.
|
||||
date, ///< The node is a toml::value<toml::date>.
|
||||
time, ///< The node is a toml::value<toml::time>.
|
||||
date_time ///< The node is a toml::value<toml::date_time>.
|
||||
date, ///< The node is a toml::value<date>.
|
||||
time, ///< The node is a toml::value<time>.
|
||||
date_time ///< The node is a toml::value<date_time>.
|
||||
};
|
||||
|
||||
#if TOML_LARGE_FILES
|
||||
@ -599,13 +596,12 @@ namespace toml::impl
|
||||
|
||||
// Q: "why not use std::find??"
|
||||
// A: Because <algorithm> is _huge_ and std::find would be the only thing I used from it.
|
||||
// I don't want to impose such a heavy burden on users.
|
||||
// I don't want to impose such a heavy compile-time burden on users.
|
||||
|
||||
template <typename T>
|
||||
inline std::optional<size_t> find(const std::vector<T>& haystack, const T& needle) noexcept
|
||||
{
|
||||
const auto end = haystack.size();
|
||||
for (size_t i = 0; i < end; i++)
|
||||
for (size_t i = 0, e = haystack.size(); i < e; i++)
|
||||
if (haystack[i] == needle)
|
||||
return i;
|
||||
return {};
|
||||
@ -658,6 +654,9 @@ namespace toml::impl
|
||||
template <> struct node_wrapper<time> { using type = value<time>; };
|
||||
template <> struct node_wrapper<date_time> { using type = value<date_time>; };
|
||||
|
||||
template <typename T>
|
||||
using node_of = typename impl::node_wrapper<T>::type;
|
||||
|
||||
template <typename T> struct node_unwrapper { using type = T; };
|
||||
template <typename T> struct node_unwrapper<value<T>> { using type = T; };
|
||||
|
||||
@ -776,39 +775,47 @@ namespace toml::impl
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief Helper alias that wraps a type up as it's TOML node equivalent.
|
||||
template <typename T>
|
||||
using node_of = typename impl::node_wrapper<T>::type;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::table.
|
||||
template <typename T>
|
||||
inline constexpr bool is_table = std::is_same_v<impl::remove_cvref_t<T>, table>;
|
||||
/// \brief Metafunction for determining if a type is a toml::array.
|
||||
template <typename T>
|
||||
inline constexpr bool is_array = std::is_same_v<impl::remove_cvref_t<T>, array>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<string>.
|
||||
/// \brief Metafunction for determining if a type is a toml::string or toml::value<toml::string>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_string = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<string>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<int64_t>.
|
||||
inline constexpr bool is_string = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<string>>;
|
||||
/// \brief Metafunction for determining if a type is an int64_t or toml::value<int64_t>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_integer = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<int64_t>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<double>.
|
||||
inline constexpr bool is_integer = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<int64_t>>;
|
||||
/// \brief Metafunction for determining if a type is a double or toml::value<double>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_floating_point = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<double>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<bool>.
|
||||
inline constexpr bool is_floating_point = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<double>>;
|
||||
/// \brief Metafunction for determining if a type is a bool toml::value<bool>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_boolean = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<bool>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<toml::date>.
|
||||
inline constexpr bool is_boolean = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<bool>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::date or toml::value<date>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_date = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<date>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<toml::time>.
|
||||
inline constexpr bool is_date = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<date>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::time or toml::value<time>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_time = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<time>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::value<toml::date_time>.
|
||||
inline constexpr bool is_time = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<time>>;
|
||||
/// \brief Metafunction for determining if a type is a toml::date_time or toml::value<date_time>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_date_time = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
inline constexpr bool is_date_time = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
|
||||
/// \brief Pretty-prints the value of a node_type to a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto arr = toml::array{ 1, 2.0, "3", false };
|
||||
/// 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
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs) TOML_MAY_THROW
|
||||
{
|
||||
|
@ -32,15 +32,15 @@ namespace toml
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>& ref_cast() & noexcept { return *reinterpret_cast<node_of<T>*>(this); }
|
||||
impl::node_of<T>& ref_cast() & noexcept { return *reinterpret_cast<impl::node_of<T>*>(this); }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>&& ref_cast() && noexcept { return std::move(*reinterpret_cast<node_of<T>*>(this)); }
|
||||
impl::node_of<T>&& ref_cast() && noexcept { return std::move(*reinterpret_cast<impl::node_of<T>*>(this)); }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const node_of<T>& ref_cast() const & noexcept { return *reinterpret_cast<const node_of<T>*>(this); }
|
||||
const impl::node_of<T>& ref_cast() const & noexcept { return *reinterpret_cast<const impl::node_of<T>*>(this); }
|
||||
|
||||
template <typename N, typename T>
|
||||
using ref_cast_type = decltype(std::declval<N>().template ref_cast<T>());
|
||||
@ -158,7 +158,7 @@ namespace toml
|
||||
/// \returns A pointer to the node as the given type, or nullptr if it was a different type.
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>* as() noexcept
|
||||
impl::node_of<T>* as() noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
@ -180,7 +180,7 @@ namespace toml
|
||||
/// \brief Gets a pointer to the node as a more specific node type (const overload).
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const node_of<T>* as() const noexcept
|
||||
const impl::node_of<T>* as() const noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
|
@ -127,6 +127,10 @@ namespace toml::impl
|
||||
|
||||
namespace toml
|
||||
{
|
||||
/// \brief A read-only view into a node.
|
||||
///
|
||||
/// \warning This type is experimental. Functionality may change radically between versions
|
||||
/// until I decide that I'm happy with it. Use it at your own risk.
|
||||
template <typename T>
|
||||
class node_view final
|
||||
{
|
||||
@ -164,7 +168,7 @@ namespace toml
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
[[nodiscard]] const node_of<U>* as() const noexcept
|
||||
[[nodiscard]] const impl::node_of<U>* as() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value_or_node<impl::unwrapped<U>>,
|
||||
|
@ -3049,13 +3049,21 @@ namespace toml
|
||||
{
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> 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
|
||||
{
|
||||
@ -3065,59 +3073,98 @@ namespace toml
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ impl::utf8_reader{ doc, std::move(source_path) } };
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> 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]]
|
||||
inline parse_result parse(std::u8string_view doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ impl::utf8_reader{ doc, source_path } };
|
||||
}
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> 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]]
|
||||
inline parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ impl::utf8_reader{ doc, std::move(source_path) } };
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(__cpp_lib_char8_t)
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::stringstream ss;
|
||||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> 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
|
||||
@ -3132,12 +3179,23 @@ namespace toml
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::stringstream ss;
|
||||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss, "foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> 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
|
||||
@ -3152,13 +3210,22 @@ namespace toml
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// #include <fstream>
|
||||
///
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file("foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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 A TOML table if exceptions are in use,
|
||||
/// or a parse_result detailing the parsing outcome if exceptions are disabled.
|
||||
/// \returns <em>With exceptions:</em> A toml::table. <br>
|
||||
/// <em>Without exceptions:</em> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \remarks You must `#include <fstream>` to use this function (toml++
|
||||
/// \attention You must `#include <fstream>` to use this function (toml++
|
||||
/// does not transitively include it for you).
|
||||
template <typename CHAR>
|
||||
inline parse_result parse_file(std::basic_string_view<CHAR> file_path) TOML_MAY_THROW
|
||||
@ -3178,4 +3245,64 @@ namespace toml
|
||||
std::string_view{ reinterpret_cast<const char*>(file_path.data()), file_path.length() }
|
||||
);
|
||||
}
|
||||
|
||||
/// \brief Convenience literal operators for working with TOML++.
|
||||
///
|
||||
/// \remark This namespace exists so you can safely hoist the UDL operators into another scope
|
||||
/// without dragging in everything in the toml namespace.
|
||||
inline namespace literals
|
||||
{
|
||||
/// \brief Parses TOML data from a string.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// auto tbl = "a = 3"_toml;
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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.
|
||||
[[nodiscard]]
|
||||
inline parse_result operator"" _toml(const char* str, size_t len) noexcept
|
||||
{
|
||||
return parse(std::string_view{ str, len });
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
/// \brief Parses TOML data from a string.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
///
|
||||
/// auto tbl = u8"a = 3"_toml;
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // 3
|
||||
/// \ecpp
|
||||
///
|
||||
/// \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.
|
||||
///
|
||||
/// \attention This overload is not available if your compiler does not support char8_t-based strings.
|
||||
[[nodiscard]]
|
||||
inline parse_result operator"" _toml(const char8_t* str, size_t len) noexcept
|
||||
{
|
||||
return parse(std::u8string_view{ str, len });
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ namespace toml
|
||||
/// \brief Constructs a table with one or more initial key-value pairs.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{ //double braces required :( - see Remarks
|
||||
/// auto tbl = toml::table{{ // double braces required :( - see remark
|
||||
/// { "foo", 1 },
|
||||
/// { "bar", 2.0 },
|
||||
/// { "kek", "three" }
|
||||
@ -165,13 +165,13 @@ namespace toml
|
||||
/// \remarks C++ std::initializer_lists represent their member elements as
|
||||
/// const even if the list's value type is non-const. This is great for
|
||||
/// compiler writers, I guess, but pretty annoying for me since
|
||||
/// TOML key-value pairs are polymorphic. This means that for the
|
||||
/// human-friendly braced init list syntax to work I can't use
|
||||
/// TOML key-value pairs are polymorphic (and thus move-only). This means
|
||||
/// that for the human-friendly braced init list syntax to work I can't use
|
||||
/// std::initializer_list and must instead invent an annoying proxy type,
|
||||
/// which means an extra level of nesting.
|
||||
/// <br><br>
|
||||
/// See https://en.cppreference.com/w/cpp/utility/initializer_list
|
||||
/// if you'd like to be more annoyed about this.
|
||||
/// if you'd like to learn more about this.
|
||||
template <size_t N>
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit table(impl::table_init_pair(&& arr)[N]) noexcept
|
||||
@ -213,7 +213,6 @@ namespace toml
|
||||
[[nodiscard]] table* as_table() noexcept override { return this; }
|
||||
[[nodiscard]] const table* as_table() const noexcept override { return this; }
|
||||
|
||||
|
||||
/// \brief Returns true if this table is an inline table.
|
||||
///
|
||||
/// \remarks Runtime-constructed tables (i.e. those not created during
|
||||
@ -261,9 +260,9 @@ namespace toml
|
||||
///
|
||||
/// \returns A node_view.
|
||||
///
|
||||
/// \remarks std::map::operator[]'s behaviour of constructing an element at a key if it
|
||||
/// didn't exist is terribad, so I've deliberately chosen not to emulate that
|
||||
/// insane bug-factory. This Is Not An Error (tm).
|
||||
/// \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).
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]] inline node_view<table> operator[] (string_view key) noexcept;
|
||||
@ -292,6 +291,38 @@ namespace toml
|
||||
/// \brief Removes all key-value pairs from the table.
|
||||
void clear() noexcept { values.clear(); }
|
||||
|
||||
/// \brief Inserts a new value at a specific key if one did not already exist.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// for (auto k : { "a", "d" })
|
||||
/// {
|
||||
/// auto result = tbl.insert(k, 42);
|
||||
/// std::cout << "inserted a value with key '"sv << k << "': "sv << result.second << std::endl;
|
||||
/// }
|
||||
/// 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
|
||||
///
|
||||
/// \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.
|
||||
/// \param val The new value to insert.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// - An iterator to the insertion position (or the position of the value that prevented insertion)
|
||||
/// - A boolean indicating if the insertion was successful.
|
||||
template <typename K, typename V, typename = std::enable_if_t<
|
||||
std::is_convertible_v<K&&, string_view>
|
||||
>>
|
||||
@ -306,6 +337,35 @@ namespace toml
|
||||
return { ipos, false };
|
||||
}
|
||||
|
||||
/// \brief Inserts a series of key-value pairs into the table.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// auto kvps = std::array<std::pair<toml::string, int>>{{
|
||||
/// { "d", 42 },
|
||||
/// { "a", 43 }
|
||||
/// }};
|
||||
/// 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
|
||||
///
|
||||
/// \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.
|
||||
///
|
||||
/// \remarks This function is morally equivalent to calling insert(key, value) for each
|
||||
/// key-value pair covered by the iterator range, so any values with keys already found in the
|
||||
/// table will not be replaced.
|
||||
template <typename ITER, typename = std::enable_if_t<
|
||||
!std::is_convertible_v<ITER&&, string_view>
|
||||
>>
|
||||
@ -322,6 +382,39 @@ namespace toml
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Inserts or assigns a value at a specific key.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// for (auto k : { "a", "d" })
|
||||
/// {
|
||||
/// auto result = tbl.insert_or_assign(k, 42);
|
||||
/// std::cout << "value at key '"sv << k
|
||||
/// << "' was "sv << (result.second ? "inserted"sv : "assigned"sv) << std::endl;
|
||||
/// }
|
||||
/// 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
|
||||
///
|
||||
/// \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.
|
||||
/// \param val The value to insert/assign.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// - An iterator to the value's position
|
||||
/// - A boolean containing `true` if the value was inserted, `false` if it was assigned.
|
||||
template <typename K, typename V>
|
||||
std::pair<iterator, bool> insert_or_assign(K&& key, V&& val) noexcept
|
||||
{
|
||||
@ -338,6 +431,42 @@ namespace toml
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new value at a specific key if one did not already exist.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 1 },
|
||||
/// { "b", 2 },
|
||||
/// { "c", 3 }
|
||||
/// }};
|
||||
/// std::cout << tbl << std::endl;
|
||||
///
|
||||
/// for (auto k : { "a", "d" })
|
||||
/// {
|
||||
/// // add a string using std::string's substring constructor
|
||||
/// auto result = tbl.emplace<std::string>(k, "this is not a drill"sv, 14, 5);
|
||||
/// std::cout << "emplaced a value with key '"sv << k << "': "sv << result.second << std::endl;
|
||||
/// }
|
||||
/// 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
|
||||
///
|
||||
/// \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.
|
||||
/// \param key The key at which to emplace the new value.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// - 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).
|
||||
template <typename U, typename K, typename... V>
|
||||
std::pair<iterator, bool> emplace(K&& key, V&&... args) noexcept
|
||||
{
|
||||
@ -353,7 +482,7 @@ namespace toml
|
||||
ipos = values.emplace_hint(
|
||||
ipos,
|
||||
std::forward<K>(key),
|
||||
new node_of<type>{ std::forward<V>(args)... }
|
||||
new impl::node_of<type>{ std::forward<V>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
}
|
||||
@ -510,7 +639,38 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Gets the node at a specific key.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::table{{
|
||||
/// { "a", 42, },
|
||||
/// { "b", "is the meaning of life, apparently." }
|
||||
/// }};
|
||||
/// std::cout << R"(node ["a"] exists: )"sv << !!arr.get("a") << std::endl;
|
||||
/// std::cout << R"(node ["b"] exists: )"sv << !!arr.get("b") << std::endl;
|
||||
/// std::cout << R"(node ["c"] exists: )"sv << !!arr.get("c") << std::endl;
|
||||
/// 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
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key, or nullptr.
|
||||
[[nodiscard]] node* get(string_view key) noexcept { return do_get(values, key); }
|
||||
|
||||
/// \brief Gets the node at a specific key (const overload).
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key, or nullptr.
|
||||
[[nodiscard]] const node* get(string_view key) const noexcept { return do_get(values, key); }
|
||||
|
||||
[[nodiscard]] iterator find(string_view key) noexcept { return { values.find(key) }; }
|
||||
@ -524,7 +684,7 @@ namespace toml
|
||||
/// { "b", "is the meaning of life, apparently." }
|
||||
/// }};
|
||||
/// if (auto val = arr.get_as<int64_t>("a"))
|
||||
/// std::cout << node [\"a\"] was an integer with value "sv << **val << std::endl;
|
||||
/// std::cout << R"(node ["a"] was an integer with value )"sv << **val << std::endl;
|
||||
///
|
||||
/// // output:
|
||||
/// // node ["a"] was an integer with value 42
|
||||
@ -533,18 +693,18 @@ namespace toml
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(string_view key) noexcept { return do_get_as<T>(values, key); }
|
||||
[[nodiscard]] impl::node_of<T>* get_as(string_view key) noexcept { return do_get_as<T>(values, key); }
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type (const overload).
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the selected node if it was of the specified type, or nullptr.
|
||||
/// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(string_view key) const noexcept { return do_get_as<T>(values, key); }
|
||||
[[nodiscard]] const impl::node_of<T>* get_as(string_view key) const noexcept { return do_get_as<T>(values, key); }
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
[[nodiscard]] bool contains(string_view key) const noexcept { return do_contains(values, key); }
|
||||
|
@ -44,7 +44,7 @@ namespace toml
|
||||
/// \brief Constructs a toml value.
|
||||
///
|
||||
/// \tparam U Constructor argument types.
|
||||
/// \param args Variadic list of arguments that are forwarded to the internal value's constructor.
|
||||
/// \param args Arguments to forward to the internal value's constructor.
|
||||
template <typename... U>
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit value(U&&... args) TOML_MAY_THROW_UNLESS(std::is_nothrow_constructible_v<T, U &&...>)
|
||||
|
@ -16,11 +16,54 @@ import bs4 as soup
|
||||
|
||||
|
||||
|
||||
_inlineNamespaces = [
|
||||
inline_namespaces = [
|
||||
"toml::literals",
|
||||
]
|
||||
_inlineNamespaceExplainer = 'All members of this namespace are automatically members of the parent namespace. ' \
|
||||
inline_namespace_explainer = 'All members of this namespace are automatically members of the parent namespace. ' \
|
||||
+ 'It does not require an explicit \'using\' statement.'
|
||||
type_names = [
|
||||
'table',
|
||||
'array',
|
||||
'value',
|
||||
'date',
|
||||
'time',
|
||||
'date_time',
|
||||
'string',
|
||||
'string_view',
|
||||
'parse_result',
|
||||
'parse_error',
|
||||
'size_t',
|
||||
'uint8_t',
|
||||
'uint16_t',
|
||||
'uint32_t',
|
||||
'uint64_t',
|
||||
'int8_t',
|
||||
'int16_t',
|
||||
'int32_t',
|
||||
'int64_t',
|
||||
'ptrdiff_t',
|
||||
'intptr_t',
|
||||
'uintptr_t',
|
||||
'exception',
|
||||
'iterator',
|
||||
'const_iterator',
|
||||
'int',
|
||||
'long',
|
||||
'short',
|
||||
'signed',
|
||||
'unsigned',
|
||||
'float',
|
||||
'double',
|
||||
'bool',
|
||||
'pair',
|
||||
'tuple',
|
||||
]
|
||||
all_namespaces = [
|
||||
'std',
|
||||
'toml',
|
||||
'literals',
|
||||
'impl'
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -28,6 +71,7 @@ def is_tool(name):
|
||||
return shutil.which(name) is not None
|
||||
|
||||
|
||||
|
||||
def is_collection(val):
|
||||
if isinstance(val, (list, tuple, dict, set)):
|
||||
return True
|
||||
@ -35,6 +79,14 @@ def is_collection(val):
|
||||
|
||||
|
||||
|
||||
def read_all_text_from_file(path):
|
||||
print("Reading {}".format(path))
|
||||
with open(path, 'r', encoding='utf-8') as file:
|
||||
text = file.read()
|
||||
return text
|
||||
|
||||
|
||||
|
||||
def get_all_files(dir, all=None, any=None):
|
||||
files = [f for f in [path.join(dir, f) for f in os.listdir(dir)] if path.isfile(f)]
|
||||
if (files and all is not None):
|
||||
@ -91,6 +143,7 @@ class HTMLDocument(object):
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
def find_all_from_sections(self, name=None, select=None, section=None, **kwargs):
|
||||
tags = []
|
||||
sectionArgs = { }
|
||||
@ -355,7 +408,7 @@ class ModifiersFix2(ModifiersFixBase):
|
||||
|
||||
# base type for applying inline namespace annotations.
|
||||
class InlineNamespaceFixBase(object):
|
||||
_namespaceFiles = ['namespace{}.html'.format(ns.lower().replace('::','_1_1')) for ns in _inlineNamespaces]
|
||||
_namespaceFiles = ['namespace{}.html'.format(ns.lower().replace('::','_1_1')) for ns in inline_namespaces]
|
||||
|
||||
|
||||
|
||||
@ -368,7 +421,7 @@ class InlineNamespaceFix1(InlineNamespaceFixBase):
|
||||
__allowedFiles = ['annotated.html', 'namespaces.html']
|
||||
|
||||
def __call__(self, file, doc):
|
||||
global _inlineNamespaceExplainer
|
||||
global inline_namespace_explainer
|
||||
changed = False
|
||||
if (file in self.__allowedFiles):
|
||||
anchors = []
|
||||
@ -383,7 +436,7 @@ class InlineNamespaceFix1(InlineNamespaceFixBase):
|
||||
doc.new_tag('span',
|
||||
after=anchor,
|
||||
string='inline',
|
||||
title=_inlineNamespaceExplainer,
|
||||
title=inline_namespace_explainer,
|
||||
class_='m-label m-info m-flat tpp-injected tpp-inline-namespace'
|
||||
)
|
||||
anchor.insert_after(' ')
|
||||
@ -400,7 +453,7 @@ class InlineNamespaceFix1(InlineNamespaceFixBase):
|
||||
class InlineNamespaceFix2(InlineNamespaceFixBase):
|
||||
|
||||
def __call__(self, file, doc):
|
||||
global _inlineNamespaceExplainer
|
||||
global inline_namespace_explainer
|
||||
changed = False
|
||||
if (file in self._namespaceFiles):
|
||||
h1 = doc.body.find('h1')
|
||||
@ -409,7 +462,7 @@ class InlineNamespaceFix2(InlineNamespaceFixBase):
|
||||
tag = doc.new_tag('span',
|
||||
parent=h1,
|
||||
string='inline',
|
||||
title=_inlineNamespaceExplainer,
|
||||
title=inline_namespace_explainer,
|
||||
class_='m-label m-info tpp-injected tpp-inline-namespace'
|
||||
)
|
||||
tag.insert_before(' ')
|
||||
@ -426,7 +479,7 @@ class InlineNamespaceFix2(InlineNamespaceFixBase):
|
||||
class InlineNamespaceFix3(InlineNamespaceFixBase):
|
||||
|
||||
def __call__(self, file, doc):
|
||||
global _inlineNamespaceExplainer
|
||||
global inline_namespace_explainer
|
||||
anchors = doc.find_all_from_sections('a', section='namespaces')
|
||||
changed = False
|
||||
for anchor in anchors:
|
||||
@ -440,7 +493,7 @@ class InlineNamespaceFix3(InlineNamespaceFixBase):
|
||||
doc.new_tag('span',
|
||||
after=anchor,
|
||||
string='inline',
|
||||
title=_inlineNamespaceExplainer,
|
||||
title=inline_namespace_explainer,
|
||||
class_='m-label m-info m-flat tpp-injected tpp-inline-namespace'
|
||||
)
|
||||
anchor.insert_after(' ')
|
||||
@ -453,6 +506,44 @@ class InlineNamespaceFix3(InlineNamespaceFixBase):
|
||||
|
||||
|
||||
|
||||
# adds some additional colouring to the syntax highlighting in code blocks.
|
||||
class SyntaxHighlightingFix(object):
|
||||
|
||||
def __call__(self, file, doc):
|
||||
global type_names
|
||||
global all_namespaces
|
||||
code_blocks = doc.body('pre', class_='m-code')
|
||||
changed = False
|
||||
for code_block in code_blocks:
|
||||
names = code_block('span', class_='n')
|
||||
|
||||
# namespaces
|
||||
for name in names:
|
||||
if (name.string is None or name.string not in all_namespaces):
|
||||
continue
|
||||
next = name.next_sibling
|
||||
if (next is None or next.string is None or next.string != '::'):
|
||||
continue
|
||||
next.extract()
|
||||
name.string.replace_with(name.string + '::')
|
||||
name['class'] = 'ns'
|
||||
changed = True
|
||||
|
||||
# user types and typedefs
|
||||
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
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
|
||||
|
||||
|
||||
# adds links to external sources where appropriate
|
||||
class ExtDocLinksFix(object):
|
||||
__types = [
|
||||
@ -497,12 +588,12 @@ class ExtDocLinksFix(object):
|
||||
(r'std::(?:basic_|w|u8)?string_views?', 'https://en.cppreference.com/w/cpp/string/basic_string_view'),
|
||||
(r'std::(?:basic_|w|u8)?strings?', 'https://en.cppreference.com/w/cpp/string/basic_string'),
|
||||
|
||||
(r'(?:<|<)fstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/fstream'),
|
||||
(r'(?:<|<)sstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/sstream'),
|
||||
(r'(?:<|<)iostream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iostream'),
|
||||
(r'(?:<|<)iosfwd(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iosfwd'),
|
||||
(r'(?:<|<)string(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string'),
|
||||
(r'(?:<|<)string_view(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string_view'),
|
||||
(r'\s(?:<|<)fstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/fstream'),
|
||||
(r'\s(?:<|<)sstream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/sstream'),
|
||||
(r'\s(?:<|<)iostream(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iostream'),
|
||||
(r'\s(?:<|<)iosfwd(?:>|>)', 'https://en.cppreference.com/w/cpp/header/iosfwd'),
|
||||
(r'\s(?:<|<)string(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string'),
|
||||
(r'\s(?:<|<)string_view(?:>|>)', 'https://en.cppreference.com/w/cpp/header/string_view'),
|
||||
|
||||
|
||||
(r'char(?:8|16|32)_ts?', 'https://en.cppreference.com/w/cpp/language/types'),
|
||||
@ -542,30 +633,42 @@ 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')
|
||||
]
|
||||
__allowedNames = ['dd', 'p', 'dt', 'h3', 'td']
|
||||
|
||||
def __init__(self):
|
||||
self.__expressions = []
|
||||
for type, uri in self.__types:
|
||||
self.__expressions.append((re.compile(type+'(?!</a>)'), uri))
|
||||
self.__expressions.append((re.compile(type), uri))
|
||||
|
||||
@classmethod
|
||||
def __substitute(cls, m, uri):
|
||||
return r'<a href="{}" class="m-doc tpp-injected tpp-external" target="_blank">{}</a>'.format(
|
||||
external = uri.startswith('http')
|
||||
return r'<a href="{}" class="m-doc tpp-injected{}"{}>{}</a>'.format(
|
||||
uri,
|
||||
m.group(0)
|
||||
' tpp-external' if external else '',
|
||||
' target="_blank"' if external else '',
|
||||
m.group(0),
|
||||
)
|
||||
|
||||
def __process_tag(self, tag):
|
||||
for expr, uri in self.__expressions:
|
||||
for descendant in tag.descendants:
|
||||
if (not isinstance(descendant, soup.NavigableString) or html_find_parent(descendant, 'a', tag) is not None):
|
||||
continue
|
||||
for descendant in tag.descendants:
|
||||
if (not isinstance(descendant, soup.NavigableString) or html_find_parent(descendant, 'a', tag) is not None):
|
||||
continue
|
||||
for expr, uri in self.__expressions:
|
||||
replacer = RegexReplacer(expr, lambda m: self.__substitute(m, uri), html.escape(str(descendant), quote=False))
|
||||
if (replacer):
|
||||
html_replace_tag(descendant, str(replacer))
|
||||
repl_str = str(replacer)
|
||||
begins_with_ws = len(repl_str) > 0 and repl_str[:1].isspace()
|
||||
new_tag = html_replace_tag(descendant, repl_str)[0]
|
||||
if (begins_with_ws and new_tag.string is not None and not new_tag.string[:1].isspace()):
|
||||
new_tag.insert_before(' ')
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -695,6 +798,35 @@ def run_python_script(script_path, *args):
|
||||
|
||||
|
||||
|
||||
def preprocess_xml(xml_dir):
|
||||
|
||||
# fix value not knowing it's a child of node
|
||||
toml_value_path = path.join(xml_dir, 'classtoml_1_1value.xml')
|
||||
toml_value_text = read_all_text_from_file(toml_value_path)
|
||||
toml_value_search_string = '<compoundname>toml::value</compoundname>'
|
||||
toml_value_insert_pos = toml_value_text.find(toml_value_search_string)
|
||||
if (toml_value_insert_pos != -1):
|
||||
toml_value_insert_pos += len(toml_value_search_string)
|
||||
toml_value_text = toml_value_text[:toml_value_insert_pos] \
|
||||
+ '\n <basecompoundref refid="classtoml_1_1node" prot="public" virt="non-virtual">toml::node</basecompoundref>' \
|
||||
+ toml_value_text[toml_value_insert_pos:]
|
||||
with open(toml_value_path,'w', encoding='utf-8', newline='\n') as output_file:
|
||||
print(toml_value_text, file=output_file)
|
||||
|
||||
# fix node not knowing it has value as a child
|
||||
toml_node_path = path.join(xml_dir, 'classtoml_1_1node.xml')
|
||||
toml_node_text = read_all_text_from_file(toml_node_path)
|
||||
toml_node_search_string = '<compoundname>toml::node</compoundname>'
|
||||
toml_node_insert_pos = toml_node_text.find(toml_node_search_string)
|
||||
if (toml_node_insert_pos != -1):
|
||||
toml_node_insert_pos += len(toml_node_search_string)
|
||||
toml_node_text = toml_node_text[:toml_node_insert_pos] \
|
||||
+ '\n <derivedcompoundref refid="classtoml_1_1value" prot="public" virt="non-virtual">toml::value</derivedcompoundref>' \
|
||||
+ toml_node_text[toml_node_insert_pos:]
|
||||
with open(toml_node_path,'w', encoding='utf-8', newline='\n') as output_file:
|
||||
print(toml_node_text, file=output_file)
|
||||
|
||||
|
||||
def main():
|
||||
global _threadError
|
||||
|
||||
@ -710,21 +842,22 @@ def main():
|
||||
delete_directory(xml_dir)
|
||||
delete_directory(html_dir)
|
||||
|
||||
# run doxygen (via m.css)
|
||||
run_python_script(doxygen, path.join(docs_dir, 'Doxyfile-mcss'))
|
||||
# run doxygen
|
||||
subprocess.check_call( ['doxygen', 'Doxyfile'], shell=True, cwd=docs_dir )
|
||||
|
||||
# clean up xml and tmp files
|
||||
# fix some shit that's broken in the xml
|
||||
preprocess_xml(xml_dir)
|
||||
|
||||
# run doxygen.py (m.css)
|
||||
run_python_script(doxygen, path.join(docs_dir, 'Doxyfile-mcss'), '--no-doxygen')
|
||||
|
||||
# delete xml
|
||||
delete_directory(xml_dir)
|
||||
#for file in get_all_files(cwd, '*.tmp'):
|
||||
# try:
|
||||
# print('Deleting {}'.format(file))
|
||||
# os.remove(file)
|
||||
# except Exception as e:
|
||||
# fatal_error(e)
|
||||
|
||||
# post-process html files
|
||||
fixes = [
|
||||
CustomTagsFix()
|
||||
, SyntaxHighlightingFix()
|
||||
# , NavBarFix()
|
||||
, IndexHrefFix()
|
||||
, ModifiersFix1()
|
||||
|
@ -122,7 +122,8 @@ def main():
|
||||
preamble = []
|
||||
preamble.append('''
|
||||
toml++ v{}
|
||||
https://github.com/marzer/tomlplusplus'''.format('.'.join(str(x) for x in library_version)))
|
||||
https://github.com/marzer/tomlplusplus
|
||||
SPDX-License-Identifier: MIT'''.format('.'.join(str(x) for x in library_version)))
|
||||
preamble.append('''
|
||||
- THIS FILE WAS ASSEMBLED FROM MULTIPLE HEADER FILES BY A SCRIPT - PLEASE DON'T EDIT IT DIRECTLY -
|
||||
|
||||
|
113
toml.hpp
113
toml.hpp
@ -2,6 +2,7 @@
|
||||
//
|
||||
// toml++ v0.1.0
|
||||
// https://github.com/marzer/tomlplusplus
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
@ -37,8 +38,6 @@
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// UTF-8 decoding is performed using a derivative of Bjoern Hoehrmann's 'Flexible and Economical UTF-8 Decoder'
|
||||
@ -339,16 +338,13 @@ TOML_POP_WARNINGS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
inline namespace literals
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<size_t>(n);
|
||||
}
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<size_t>(n);
|
||||
}
|
||||
|
||||
#if TOML_CHAR_8_STRINGS
|
||||
@ -581,13 +577,12 @@ namespace toml::impl
|
||||
|
||||
// Q: "why not use std::find??"
|
||||
// A: Because <algorithm> is _huge_ and std::find would be the only thing I used from it.
|
||||
// I don't want to impose such a heavy burden on users.
|
||||
// I don't want to impose such a heavy compile-time burden on users.
|
||||
|
||||
template <typename T>
|
||||
inline std::optional<size_t> find(const std::vector<T>& haystack, const T& needle) noexcept
|
||||
{
|
||||
const auto end = haystack.size();
|
||||
for (size_t i = 0; i < end; i++)
|
||||
for (size_t i = 0, e = haystack.size(); i < e; i++)
|
||||
if (haystack[i] == needle)
|
||||
return i;
|
||||
return {};
|
||||
@ -640,6 +635,9 @@ namespace toml::impl
|
||||
template <> struct node_wrapper<time> { using type = value<time>; };
|
||||
template <> struct node_wrapper<date_time> { using type = value<date_time>; };
|
||||
|
||||
template <typename T>
|
||||
using node_of = typename impl::node_wrapper<T>::type;
|
||||
|
||||
template <typename T> struct node_unwrapper { using type = T; };
|
||||
template <typename T> struct node_unwrapper<value<T>> { using type = T; };
|
||||
|
||||
@ -757,27 +755,24 @@ namespace toml::impl
|
||||
|
||||
namespace toml
|
||||
{
|
||||
template <typename T>
|
||||
using node_of = typename impl::node_wrapper<T>::type;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_table = std::is_same_v<impl::remove_cvref_t<T>, table>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_array = std::is_same_v<impl::remove_cvref_t<T>, array>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_string = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<string>>;
|
||||
inline constexpr bool is_string = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<string>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_integer = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<int64_t>>;
|
||||
inline constexpr bool is_integer = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<int64_t>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_floating_point = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<double>>;
|
||||
inline constexpr bool is_floating_point = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<double>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_boolean = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<bool>>;
|
||||
inline constexpr bool is_boolean = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<bool>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_date = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<date>>;
|
||||
inline constexpr bool is_date = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<date>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_time = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<time>>;
|
||||
inline constexpr bool is_time = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<time>>;
|
||||
template <typename T>
|
||||
inline constexpr bool is_date_time = std::is_same_v<node_of<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
inline constexpr bool is_date_time = std::is_same_v<impl::node_of<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
|
||||
template <typename CHAR>
|
||||
inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>& lhs, node_type rhs) TOML_MAY_THROW
|
||||
@ -1299,15 +1294,15 @@ namespace toml
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>& ref_cast() & noexcept { return *reinterpret_cast<node_of<T>*>(this); }
|
||||
impl::node_of<T>& ref_cast() & noexcept { return *reinterpret_cast<impl::node_of<T>*>(this); }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>&& ref_cast() && noexcept { return std::move(*reinterpret_cast<node_of<T>*>(this)); }
|
||||
impl::node_of<T>&& ref_cast() && noexcept { return std::move(*reinterpret_cast<impl::node_of<T>*>(this)); }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const node_of<T>& ref_cast() const & noexcept { return *reinterpret_cast<const node_of<T>*>(this); }
|
||||
const impl::node_of<T>& ref_cast() const & noexcept { return *reinterpret_cast<const impl::node_of<T>*>(this); }
|
||||
|
||||
template <typename N, typename T>
|
||||
using ref_cast_type = decltype(std::declval<N>().template ref_cast<T>());
|
||||
@ -1375,7 +1370,7 @@ namespace toml
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
node_of<T>* as() noexcept
|
||||
impl::node_of<T>* as() noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
@ -1396,7 +1391,7 @@ namespace toml
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
const node_of<T>* as() const noexcept
|
||||
const impl::node_of<T>* as() const noexcept
|
||||
{
|
||||
using type = impl::unwrapped<T>;
|
||||
static_assert(
|
||||
@ -2160,7 +2155,7 @@ namespace toml
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
return { values.emplace(pos.raw_, new node_of<type>{ std::forward<V>(args)...} ) };
|
||||
return { values.emplace(pos.raw_, new impl::node_of<type>{ std::forward<V>(args)...} ) };
|
||||
}
|
||||
|
||||
iterator erase(const_iterator pos) noexcept
|
||||
@ -2190,7 +2185,7 @@ namespace toml
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
|
||||
auto nde = new node_of<type>{ std::forward<V>(args)... };
|
||||
auto nde = new impl::node_of<type>{ std::forward<V>(args)... };
|
||||
values.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
@ -2200,16 +2195,30 @@ namespace toml
|
||||
values.pop_back();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(size_t index) noexcept
|
||||
[[nodiscard]] node* get(size_t index) noexcept
|
||||
{
|
||||
return values[index]->as<T>();
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] const node* get(size_t index) const noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(size_t index) const noexcept
|
||||
[[nodiscard]] impl::node_of<T>* get_as(size_t index) noexcept
|
||||
{
|
||||
return values[index]->as<T>();
|
||||
if (auto val = get(index))
|
||||
return val->as<T>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] const impl::node_of<T>* get_as(size_t index) const noexcept
|
||||
{
|
||||
if (auto val = get(index))
|
||||
return val->as<T>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator == (const array& lhs, const array& rhs) noexcept
|
||||
@ -2567,7 +2576,7 @@ namespace toml
|
||||
ipos = values.emplace_hint(
|
||||
ipos,
|
||||
std::forward<K>(key),
|
||||
new node_of<type>{ std::forward<V>(args)... }
|
||||
new impl::node_of<type>{ std::forward<V>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
}
|
||||
@ -2641,10 +2650,10 @@ namespace toml
|
||||
[[nodiscard]] const_iterator find(string_view key) const noexcept { return { values.find(key) }; }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] node_of<T>* get_as(string_view key) noexcept { return do_get_as<T>(values, key); }
|
||||
[[nodiscard]] impl::node_of<T>* get_as(string_view key) noexcept { return do_get_as<T>(values, key); }
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] const node_of<T>* get_as(string_view key) const noexcept { return do_get_as<T>(values, key); }
|
||||
[[nodiscard]] const impl::node_of<T>* get_as(string_view key) const noexcept { return do_get_as<T>(values, key); }
|
||||
[[nodiscard]] bool contains(string_view key) const noexcept { return do_contains(values, key); }
|
||||
[[nodiscard]] friend bool operator == (const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
@ -2850,7 +2859,7 @@ namespace toml
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
[[nodiscard]] const node_of<U>* as() const noexcept
|
||||
[[nodiscard]] const impl::node_of<U>* as() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value_or_node<impl::unwrapped<U>>,
|
||||
@ -7575,7 +7584,7 @@ namespace toml
|
||||
return impl::parser{ impl::utf8_reader{ doc, std::move(source_path) } };
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
[[nodiscard]]
|
||||
inline parse_result parse(std::u8string_view doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
@ -7589,7 +7598,7 @@ namespace toml
|
||||
return impl::parser{ impl::utf8_reader{ doc, std::move(source_path) } };
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(__cpp_lib_char8_t)
|
||||
|
||||
template <typename CHAR>
|
||||
[[nodiscard]]
|
||||
@ -7633,6 +7642,26 @@ namespace toml
|
||||
std::string_view{ reinterpret_cast<const char*>(file_path.data()), file_path.length() }
|
||||
);
|
||||
}
|
||||
|
||||
inline namespace literals
|
||||
{
|
||||
[[nodiscard]]
|
||||
inline parse_result operator"" _toml(const char* str, size_t len) noexcept
|
||||
{
|
||||
return parse(std::string_view{ str, len });
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
|
||||
[[nodiscard]]
|
||||
inline parse_result operator"" _toml(const char8_t* str, size_t len) noexcept
|
||||
{
|
||||
return parse(std::u8string_view{ str, len });
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
Loading…
Reference in New Issue
Block a user