mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-10-06 06:49:43 +00:00
greatly simplified project header structure
also: - removed `TOML_LARGE_FILES` - removed unnecessary template machinery (esp. where ostreams were involved) - made all overloaded operators 'hidden friends' - documentation fixes - version bump - this will form the foundation of v3
This commit is contained in:
parent
0f589ceba8
commit
516b8e2096
@ -96,7 +96,7 @@ IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: Indent
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
@ -124,6 +124,7 @@ PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortJavaStaticImport: Before
|
||||
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(
|
||||
tomlplusplus
|
||||
VERSION 2.6.0
|
||||
VERSION 3.0.0
|
||||
DESCRIPTION "Header-only TOML config file parser and serializer for C++17 (and later!)"
|
||||
HOMEPAGE_URL "https://marzer.github.io/tomlplusplus/"
|
||||
LANGUAGES CXX
|
||||
|
@ -144,7 +144,6 @@ won't need to mess with these at all, but if you do, set them before including t
|
||||
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
|
||||
| `TOML_EXCEPTIONS` | boolean | per your compiler's settings | Sets whether the library uses exceptions. |
|
||||
| `TOML_IMPLEMENTATION` | define | undefined | Define this to enable compilation of the library's implementation. Meaningless if `TOML_HEADER_ONLY` is `1`. |
|
||||
| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
|
||||
| `TOML_OPTIONAL_TYPE` | type name | undefined | Overrides the `optional<T>` type used by the library if you need [something better than std::optional]. |
|
||||
| `TOML_PARSER` | boolean | `1` | Disable this to prevent inclusion of the parser-related parts of the library if you don't need them. |
|
||||
| `TOML_SMALL_FLOAT_TYPE` | type name | undefined | If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. |
|
||||
|
21
cpp.hint
21
cpp.hint
@ -1,16 +1,25 @@
|
||||
#define TOML_API
|
||||
#define TOML_ATTR(...)
|
||||
#define TOML_ALWAYS_INLINE inline
|
||||
#define TOML_ALWAYS_INLINE inline
|
||||
#define TOML_NEVER_INLINE
|
||||
#define TOML_TRIVIAL_ABI
|
||||
#define TOML_ABSTRACT_BASE
|
||||
#define TOML_EMPTY_BASES
|
||||
#define TOML_MAY_THROW
|
||||
#define TOML_CONSTEVAL constexpr
|
||||
#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__>
|
||||
#define TOML_LIKELY(...) (__VA_ARGS__)
|
||||
#define TOML_UNLIKELY(...) (__VA_ARGS__)
|
||||
#define TOML_CONSTEVAL constexpr
|
||||
#define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__>
|
||||
#define TOML_LIKELY(...) (__VA_ARGS__)
|
||||
#define TOML_UNLIKELY(...) (__VA_ARGS__)
|
||||
#define TOML_NODISCARD
|
||||
#define TOML_NODISCARD_CTOR
|
||||
#define TOML_RETURNS_BY_THROWING
|
||||
#define TOML_EXTERNAL_LINKAGE
|
||||
#define TOML_INTERNAL_LINKAGE
|
||||
#define TOML_INTERNAL_LINKAGE static
|
||||
#define TOML_ANON_NAMESPACE_START namespace
|
||||
#define TOML_ANON_NAMESPACE_END static_assert(true)
|
||||
#define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true)
|
||||
#define TOML_ABI_NAMESPACE_END static_assert(true)
|
||||
#define TOML_NAMESPACE_START namespace toml
|
||||
#define TOML_NAMESPACE_END static_assert(true)
|
||||
#define TOML_IMPL_NAMESPACE_START namespace toml::impl
|
||||
#define TOML_IMPL_NAMESPACE_END static_assert(true)
|
||||
|
@ -87,3 +87,8 @@ string_literals = [ '_toml' ]
|
||||
'(?:toml::)?default[_ ]formatters?' = 'classtoml_1_1default__formatter.html'
|
||||
'(?:toml::)?source[_ ]positions?' = 'structtoml_1_1source__position.html'
|
||||
'(?:toml::)?source[_ ]regions?' = 'structtoml_1_1source__region.html'
|
||||
'toml::values?' = 'classtoml_1_1value.html'
|
||||
'toml::dates?' = 'structtoml_1_1date.html'
|
||||
'toml::times?' = 'structtoml_1_1time.html'
|
||||
'(?:toml::)?time[_ ]offsets?' = 'structtoml_1_1time__offset.html'
|
||||
'(?:toml::)?date_times?' = 'structtoml_1_1date__time.html'
|
||||
|
@ -2,9 +2,11 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "value.h"
|
||||
#include "std_vector.h"
|
||||
#include "make_node.h"
|
||||
#include "header_start.h"
|
||||
|
||||
/// \cond
|
||||
@ -240,7 +242,7 @@ TOML_NAMESPACE_START
|
||||
/// [ 3, 4, 5, 'six', 7, 8.0, 'nine' ]
|
||||
/// [ 3, 4, 5, 'six', 7, 8.0, 'nine', 'ten', [ 11, 12.0 ] ]
|
||||
/// \eout
|
||||
class TOML_API array final : public node
|
||||
class array final : public node
|
||||
{
|
||||
private:
|
||||
/// \cond
|
||||
@ -248,6 +250,7 @@ TOML_NAMESPACE_START
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
std::vector<std::unique_ptr<node>> elements;
|
||||
|
||||
TOML_API
|
||||
void preinsertion_resize(size_t idx, size_t count) noexcept;
|
||||
|
||||
template <typename T>
|
||||
@ -262,8 +265,10 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
size_t total_leaf_count() const noexcept;
|
||||
|
||||
TOML_API
|
||||
void flatten_child(array&& child, size_t& dest_index) noexcept;
|
||||
/// \endcond
|
||||
|
||||
@ -279,31 +284,45 @@ TOML_NAMESPACE_START
|
||||
/// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
|
||||
using const_iterator = const_array_iterator;
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
array() noexcept
|
||||
{
|
||||
TOML_ARRAY_CREATED;
|
||||
}
|
||||
|
||||
~array() noexcept
|
||||
{
|
||||
TOML_ARRAY_DESTROYED;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/// \brief Default constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
array() noexcept;
|
||||
array() noexcept = default;
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Copy constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
array(const array&) noexcept;
|
||||
|
||||
/// \brief Move constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
array(array&& other) noexcept;
|
||||
|
||||
/// \brief Copy-assignment operator.
|
||||
TOML_API
|
||||
array& operator=(const array&) noexcept;
|
||||
|
||||
/// \brief Move-assignment operator.
|
||||
TOML_API
|
||||
array& operator=(array&& rhs) noexcept;
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
~array() noexcept override
|
||||
{
|
||||
TOML_ARRAY_DESTROYED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Constructs an array with one or more initial elements.
|
||||
///
|
||||
/// \detail \cpp
|
||||
@ -360,47 +379,40 @@ TOML_NAMESPACE_START
|
||||
/// @{
|
||||
|
||||
TOML_NODISCARD
|
||||
node_type type() const noexcept override
|
||||
node_type type() const noexcept final
|
||||
{
|
||||
return node_type::array;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_table() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_array() const noexcept override
|
||||
bool is_array() const noexcept final
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_value() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
array* as_array() noexcept override
|
||||
array* as_array() noexcept final
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const array* as_array() const noexcept override
|
||||
const array* as_array() const noexcept final
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype) const noexcept override;
|
||||
TOML_API
|
||||
bool is_homogeneous(node_type ntype) const noexcept final;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
||||
TOML_API
|
||||
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
||||
TOML_API
|
||||
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
|
||||
|
||||
template <typename ElemType = void>
|
||||
TOML_NODISCARD
|
||||
@ -416,7 +428,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_array_of_tables() const noexcept override
|
||||
bool is_array_of_tables() const noexcept final
|
||||
{
|
||||
return is_homogeneous(node_type::table);
|
||||
}
|
||||
@ -428,11 +440,17 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// \brief Gets a reference to the element at a specific index.
|
||||
TOML_NODISCARD
|
||||
node& operator[](size_t index) noexcept;
|
||||
node& operator[](size_t index) noexcept
|
||||
{
|
||||
return *elements[index];
|
||||
}
|
||||
|
||||
/// \brief Gets a reference to the element at a specific index.
|
||||
TOML_NODISCARD
|
||||
const node& operator[](size_t index) const noexcept;
|
||||
const node& operator[](size_t index) const noexcept
|
||||
{
|
||||
return *elements[index];
|
||||
}
|
||||
|
||||
/// \brief Returns a reference to the first element in the array.
|
||||
TOML_NODISCARD
|
||||
@ -961,7 +979,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
|
||||
TOML_NODISCARD
|
||||
node* get(size_t index) noexcept;
|
||||
node* get(size_t index) noexcept
|
||||
{
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Gets the element at a specific index (const overload).
|
||||
///
|
||||
@ -969,7 +990,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
|
||||
TOML_NODISCARD
|
||||
const node* get(size_t index) const noexcept;
|
||||
const node* get(size_t index) const noexcept
|
||||
{
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Gets the element at a specific index if it is a particular type.
|
||||
///
|
||||
@ -1032,10 +1056,13 @@ TOML_NAMESPACE_START
|
||||
/// \remarks Arrays inside child tables are not flattened.
|
||||
///
|
||||
/// \returns A reference to the array.
|
||||
TOML_API
|
||||
array& flatten() &;
|
||||
|
||||
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
|
||||
///
|
||||
/// \returns An rvalue reference to the array.
|
||||
TOML_API
|
||||
array&& flatten() &&
|
||||
{
|
||||
return static_cast<toml::array&&>(this->flatten());
|
||||
@ -1043,29 +1070,16 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Equality
|
||||
/// @{
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS array.
|
||||
/// \param rhs The RHS array.
|
||||
///
|
||||
/// \returns True if the arrays contained the same elements.
|
||||
friend bool operator==(const array& lhs, const array& rhs) noexcept;
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS array.
|
||||
/// \param rhs The RHS array.
|
||||
///
|
||||
/// \returns True if the arrays did not contain the same elements.
|
||||
friend bool operator!=(const array& lhs, const array& rhs) noexcept;
|
||||
|
||||
private:
|
||||
/// \cond
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
static bool equal(const array&, const array&) noexcept;
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
static bool container_equality(const array& lhs, const T& rhs) noexcept
|
||||
static bool equal_to_container(const array& lhs, const T& rhs) noexcept
|
||||
{
|
||||
using element_type = std::remove_const_t<typename T::value_type>;
|
||||
static_assert(impl::is_native<element_type> || impl::is_losslessly_convertible_to_native<element_type>,
|
||||
@ -1087,13 +1101,42 @@ TOML_NAMESPACE_START
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
public:
|
||||
/// \name Equality
|
||||
/// @{
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
/// \param lhs The LHS array.
|
||||
/// \param rhs The RHS array.
|
||||
///
|
||||
/// \returns True if the arrays contained the same elements.
|
||||
TOML_NODISCARD
|
||||
friend bool operator==(const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
return equal(lhs, rhs);
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
/// \param lhs The LHS array.
|
||||
/// \param rhs The RHS array.
|
||||
///
|
||||
/// \returns True if the arrays did not contain the same elements.
|
||||
TOML_NODISCARD
|
||||
friend bool operator!=(const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
return !equal(lhs, rhs);
|
||||
}
|
||||
|
||||
/// \brief Initializer list equality operator.
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
friend bool operator==(const array& lhs, const std::initializer_list<T>& rhs) noexcept
|
||||
{
|
||||
return container_equality(lhs, rhs);
|
||||
return equal_to_container(lhs, rhs);
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::initializer_list<T>&, template <typename T>);
|
||||
|
||||
@ -1102,16 +1145,18 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
friend bool operator==(const array& lhs, const std::vector<T>& rhs) noexcept
|
||||
{
|
||||
return container_equality(lhs, rhs);
|
||||
return equal_to_container(lhs, rhs);
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::vector<T>&, template <typename T>);
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Prints the array out to a stream as formatted TOML.
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>&, const array&);
|
||||
// implemented in toml_default_formatter.h
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const array& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
@ -2,29 +2,53 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "array.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_ANON_NAMESPACE_START
|
||||
{
|
||||
#if !TOML_HEADER_ONLY
|
||||
using namespace toml;
|
||||
#endif
|
||||
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool array_is_homogeneous(T & elements, node_type ntype, U & first_nonmatch) noexcept
|
||||
{
|
||||
using namespace toml;
|
||||
|
||||
if (elements.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
for (const auto& val : elements)
|
||||
{
|
||||
if (val->type() != ntype)
|
||||
{
|
||||
first_nonmatch = val.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
TOML_ANON_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
TOML_ARRAY_CREATED;
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array(const array& other) noexcept //
|
||||
: node(other)
|
||||
@ -89,20 +113,6 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
const node& array::operator[](size_t index) const noexcept
|
||||
{
|
||||
return *elements[index];
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
node& array::operator[](size_t index) noexcept
|
||||
{
|
||||
return *elements[index];
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
@ -119,59 +129,20 @@ TOML_NAMESPACE_START
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool array_is_homogeneous(T& elements, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (elements.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = elements[0]->type();
|
||||
for (const auto& val : elements)
|
||||
{
|
||||
if (val->type() != ntype)
|
||||
{
|
||||
first_nonmatch = val.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return TOML_ANON_NAMESPACE::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, toml::node * &first_nonmatch) noexcept
|
||||
bool array::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
return TOML_ANON_NAMESPACE::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool array::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::array_is_homogeneous(elements, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
node* array::get(size_t index) noexcept
|
||||
{
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(pure)
|
||||
const node* array::get(size_t index) const noexcept
|
||||
{
|
||||
return index < elements.size() ? elements[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator==(const array& lhs, const array& rhs) noexcept
|
||||
bool array::equal(const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
if (&lhs == &rhs)
|
||||
return true;
|
||||
@ -194,12 +165,6 @@ TOML_NAMESPACE_START
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator!=(const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
size_t array::total_leaf_count() const noexcept
|
||||
{
|
||||
@ -280,5 +245,5 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
||||
|
@ -2,9 +2,10 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
#include "forward_declarations.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
@ -14,21 +15,23 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief The year component.
|
||||
uint16_t year;
|
||||
|
||||
/// \brief The month component, from 1 - 12.
|
||||
uint8_t month;
|
||||
|
||||
/// \brief The day component, from 1 - 31.
|
||||
uint8_t day;
|
||||
|
||||
/// \brief Equality operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator==(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator==(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return lhs.year == rhs.year && lhs.month == rhs.month && lhs.day == rhs.day;
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator!=(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator!=(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return lhs.year != rhs.year || lhs.month != rhs.month || lhs.day != rhs.day;
|
||||
}
|
||||
@ -45,62 +48,60 @@ TOML_NAMESPACE_START
|
||||
public:
|
||||
/// \brief Less-than operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator<(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) < pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Less-than-or-equal-to operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<=(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator<=(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) <= pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Greater-than operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator>(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator>(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) > pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Greater-than-or-equal-to operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator>=(date lhs, date rhs) noexcept
|
||||
friend constexpr bool operator>=(const date& lhs, const date& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) >= pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date{ 1987, 3, 16 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 1987-03-16
|
||||
/// \eout
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const date& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date{ 1987, 3, 16 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 1987-03-16
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const date& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const date&);
|
||||
#endif
|
||||
|
||||
/// \brief A local time-of-day.
|
||||
struct TOML_TRIVIAL_ABI time
|
||||
{
|
||||
/// \brief The hour component, from 0 - 23.
|
||||
uint8_t hour;
|
||||
|
||||
/// \brief The minute component, from 0 - 59.
|
||||
uint8_t minute;
|
||||
|
||||
/// \brief The second component, from 0 - 59.
|
||||
uint8_t second;
|
||||
|
||||
/// \brief The fractional nanoseconds component, from 0 - 999999999.
|
||||
uint32_t nanosecond;
|
||||
|
||||
@ -122,7 +123,7 @@ TOML_NAMESPACE_START
|
||||
private:
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
static constexpr uint64_t pack(time t) noexcept
|
||||
static constexpr uint64_t pack(const time& t) noexcept
|
||||
{
|
||||
return static_cast<uint64_t>(t.hour) << 48 | static_cast<uint64_t>(t.minute) << 40
|
||||
| static_cast<uint64_t>(t.second) << 32 | static_cast<uint64_t>(t.nanosecond);
|
||||
@ -131,55 +132,49 @@ TOML_NAMESPACE_START
|
||||
public:
|
||||
/// \brief Less-than operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<(time lhs, time rhs) noexcept
|
||||
friend constexpr bool operator<(const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) < pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Less-than-or-equal-to operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<=(time lhs, time rhs) noexcept
|
||||
friend constexpr bool operator<=(const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) <= pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Greater-than operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator>(time lhs, time rhs) noexcept
|
||||
friend constexpr bool operator>(const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) > pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Greater-than-or-equal-to operator.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator>=(time lhs, time rhs) noexcept
|
||||
friend constexpr bool operator>=(const time& lhs, const time& rhs) noexcept
|
||||
{
|
||||
return pack(lhs) >= pack(rhs);
|
||||
}
|
||||
|
||||
/// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time{ 10, 20, 34 } << "\n";
|
||||
/// std::cout << toml::time{ 10, 20, 34, 500000000 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 10:20:34
|
||||
/// 10:20:34.5
|
||||
/// \eout
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const time& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time{ 10, 20, 34 } << "\n";
|
||||
/// std::cout << toml::time{ 10, 20, 34, 500000000 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 10:20:34
|
||||
/// 10:20:34.5
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const time&);
|
||||
#endif
|
||||
|
||||
/// \brief A timezone offset.
|
||||
struct TOML_TRIVIAL_ABI time_offset
|
||||
{
|
||||
@ -257,36 +252,30 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
return lhs.minutes >= rhs.minutes;
|
||||
}
|
||||
|
||||
/// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ 2, -30 } << "\n";
|
||||
/// std::cout << toml::time_offset{} << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// +02:30
|
||||
/// +01:30
|
||||
/// Z
|
||||
/// -01:30
|
||||
/// -02:30
|
||||
/// \eout
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const time_offset& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::time_offset{ 2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ 2, -30 } << "\n";
|
||||
/// std::cout << toml::time_offset{} << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, 30 } << "\n";
|
||||
/// std::cout << toml::time_offset{ -2, -30 } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// +02:30
|
||||
/// +01:30
|
||||
/// Z
|
||||
/// -01:30
|
||||
/// -02:30
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const time_offset& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const time_offset&);
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
|
||||
|
||||
/// \brief A date-time.
|
||||
@ -294,8 +283,10 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief The date component.
|
||||
toml::date date;
|
||||
|
||||
/// \brief The time component.
|
||||
toml::time time;
|
||||
|
||||
/// \brief The timezone offset component.
|
||||
///
|
||||
/// \remarks The date_time is said to be 'local' if the offset is empty.
|
||||
@ -314,7 +305,7 @@ TOML_NAMESPACE_START
|
||||
/// \param d The date component.
|
||||
/// \param t The time component.
|
||||
TOML_NODISCARD_CTOR
|
||||
constexpr date_time(toml::date d, toml::time t) noexcept //
|
||||
constexpr date_time(const toml::date& d, const toml::time& t) noexcept //
|
||||
: date{ d },
|
||||
time{ t },
|
||||
offset{} // TINAE - icc bugfix
|
||||
@ -326,7 +317,7 @@ TOML_NAMESPACE_START
|
||||
/// \param t The time component.
|
||||
/// \param off The timezone offset.
|
||||
TOML_NODISCARD_CTOR
|
||||
constexpr date_time(toml::date d, toml::time t, toml::time_offset off) noexcept
|
||||
constexpr date_time(const toml::date& d, const toml::time& t, const toml::time_offset& off) noexcept
|
||||
: date{ d },
|
||||
time{ t },
|
||||
offset{ off }
|
||||
@ -388,33 +379,27 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
/// \brief Prints a date_time out to a stream in RFC 3339 format.
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 1987-03-16T10:20:34
|
||||
/// 1987-03-16T10:20:34-02:30
|
||||
/// 1987-03-16T10:20:34Z
|
||||
/// \eout
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const date_time& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
/// \brief Prints a date_time out to a stream in RFC 3339 format.
|
||||
/// \detail \cpp
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << "\n";
|
||||
/// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 1987-03-16T10:20:34
|
||||
/// 1987-03-16T10:20:34-02:30
|
||||
/// 1987-03-16T10:20:34Z
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const date_time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const date_time&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
@ -2,32 +2,12 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "formatter.h"
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "utf8.h"
|
||||
#include "std_vector.h"
|
||||
#include "header_start.h"
|
||||
|
||||
/// \cond
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
std::string default_formatter_make_key_segment(const std::string&) noexcept;
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
size_t default_formatter_inline_columns(const node&) noexcept;
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
bool default_formatter_forces_multiline(const node&, size_t = 0) noexcept;
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
/// \endcond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief A wrapper for printing TOML objects out to a stream as formatted TOML.
|
||||
@ -57,272 +37,49 @@ TOML_NAMESPACE_START
|
||||
/// [table]
|
||||
/// foo = "bar"
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename Char = char>
|
||||
class TOML_API default_formatter final : impl::formatter<Char>
|
||||
class default_formatter : impl::formatter
|
||||
{
|
||||
private:
|
||||
/// \cond
|
||||
|
||||
using base = impl::formatter<Char>;
|
||||
std::vector<std::string> key_path;
|
||||
using base = impl::formatter;
|
||||
std::vector<std::string> key_path_;
|
||||
bool pending_table_separator_ = false;
|
||||
|
||||
void print_pending_table_separator()
|
||||
{
|
||||
if (pending_table_separator_)
|
||||
{
|
||||
base::print_newline(true);
|
||||
base::print_newline(true);
|
||||
pending_table_separator_ = false;
|
||||
}
|
||||
}
|
||||
static constexpr size_t line_wrap_cols = 120_sz;
|
||||
|
||||
void print_key_segment(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
impl::print_to_stream("''"sv, base::stream());
|
||||
else
|
||||
{
|
||||
bool requiresQuotes = false;
|
||||
{
|
||||
impl::utf8_decoder decoder;
|
||||
for (size_t i = 0; i < str.length() && !requiresQuotes; i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
requiresQuotes = true;
|
||||
else if (decoder.has_code_point())
|
||||
requiresQuotes = !impl::is_bare_key_character(decoder.codepoint);
|
||||
}
|
||||
}
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
static std::string make_key_segment(const std::string&) noexcept;
|
||||
|
||||
if (requiresQuotes)
|
||||
{
|
||||
impl::print_to_stream('"', base::stream());
|
||||
impl::print_to_stream_with_escapes(str, base::stream());
|
||||
impl::print_to_stream('"', base::stream());
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(str, base::stream());
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
static size_t count_inline_columns(const node&) noexcept;
|
||||
|
||||
void print_key_path()
|
||||
{
|
||||
for (const auto& segment : key_path)
|
||||
{
|
||||
if (std::addressof(segment) > key_path.data())
|
||||
impl::print_to_stream('.', base::stream());
|
||||
impl::print_to_stream(segment, base::stream());
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
static bool forces_multiline(const node&, size_t = 0) noexcept;
|
||||
|
||||
void print_inline(const table& /*tbl*/);
|
||||
TOML_API
|
||||
void print_pending_table_separator();
|
||||
|
||||
void print(const array& arr)
|
||||
{
|
||||
if (arr.empty())
|
||||
impl::print_to_stream("[]"sv, base::stream());
|
||||
else
|
||||
{
|
||||
const auto original_indent = base::indent();
|
||||
const auto multiline = impl::default_formatter_forces_multiline(
|
||||
arr,
|
||||
base::indent_columns * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
impl::print_to_stream("["sv, base::stream());
|
||||
if (multiline)
|
||||
{
|
||||
if (original_indent < 0)
|
||||
base::indent(0);
|
||||
base::increase_indent();
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(' ', base::stream());
|
||||
TOML_API
|
||||
void print_key_segment(const std::string&);
|
||||
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
if (i > 0_sz)
|
||||
{
|
||||
impl::print_to_stream(',', base::stream());
|
||||
if (!multiline)
|
||||
impl::print_to_stream(' ', base::stream());
|
||||
}
|
||||
TOML_API
|
||||
void print_key_path();
|
||||
|
||||
if (multiline)
|
||||
{
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
}
|
||||
TOML_API
|
||||
void print_inline(const toml::table&);
|
||||
|
||||
auto& v = arr[i];
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print_inline(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
if (multiline)
|
||||
{
|
||||
base::indent(original_indent);
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(' ', base::stream());
|
||||
impl::print_to_stream("]"sv, base::stream());
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
TOML_API
|
||||
void print(const toml::array&);
|
||||
|
||||
void print(const table& tbl)
|
||||
{
|
||||
static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept
|
||||
{
|
||||
auto arr = nde.as_array();
|
||||
return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0_sz)->is_inline();
|
||||
};
|
||||
TOML_API
|
||||
void print(const toml::table&);
|
||||
|
||||
// values, arrays, and inline tables/table arrays
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if ((type == node_type::table && !reinterpret_cast<const table*>(&v)->is_inline())
|
||||
|| (type == node_type::array && is_non_inline_array_of_tables(v)))
|
||||
continue;
|
||||
|
||||
pending_table_separator_ = true;
|
||||
base::print_newline();
|
||||
base::print_indent();
|
||||
print_key_segment(k);
|
||||
impl::print_to_stream(" = "sv, base::stream());
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print_inline(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
|
||||
// non-inline tables
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if (type != node_type::table || reinterpret_cast<const table*>(&v)->is_inline())
|
||||
continue;
|
||||
auto& child_tbl = *reinterpret_cast<const table*>(&v);
|
||||
|
||||
// we can skip indenting and emitting the headers for tables that only contain other tables
|
||||
// (so we don't over-nest)
|
||||
size_t child_value_count{}; // includes inline tables and non-table arrays
|
||||
size_t child_table_count{};
|
||||
size_t child_table_array_count{};
|
||||
for (auto&& [child_k, child_v] : child_tbl)
|
||||
{
|
||||
(void)child_k;
|
||||
const auto child_type = child_v.type();
|
||||
TOML_ASSUME(child_type != node_type::none);
|
||||
switch (child_type)
|
||||
{
|
||||
case node_type::table:
|
||||
if (reinterpret_cast<const table*>(&child_v)->is_inline())
|
||||
child_value_count++;
|
||||
else
|
||||
child_table_count++;
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if (is_non_inline_array_of_tables(child_v))
|
||||
child_table_array_count++;
|
||||
else
|
||||
child_value_count++;
|
||||
break;
|
||||
|
||||
default: child_value_count++;
|
||||
}
|
||||
}
|
||||
bool skip_self = false;
|
||||
if (child_value_count == 0_sz && (child_table_count > 0_sz || child_table_array_count > 0_sz))
|
||||
skip_self = true;
|
||||
|
||||
key_path.push_back(impl::default_formatter_make_key_segment(k));
|
||||
|
||||
if (!skip_self)
|
||||
{
|
||||
print_pending_table_separator();
|
||||
base::increase_indent();
|
||||
base::print_indent();
|
||||
impl::print_to_stream("["sv, base::stream());
|
||||
print_key_path();
|
||||
impl::print_to_stream("]"sv, base::stream());
|
||||
pending_table_separator_ = true;
|
||||
}
|
||||
|
||||
print(child_tbl);
|
||||
|
||||
key_path.pop_back();
|
||||
if (!skip_self)
|
||||
base::decrease_indent();
|
||||
}
|
||||
|
||||
// table arrays
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
if (!is_non_inline_array_of_tables(v))
|
||||
continue;
|
||||
auto& arr = *reinterpret_cast<const array*>(&v);
|
||||
|
||||
base::increase_indent();
|
||||
key_path.push_back(impl::default_formatter_make_key_segment(k));
|
||||
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
print_pending_table_separator();
|
||||
base::print_indent();
|
||||
impl::print_to_stream("[["sv, base::stream());
|
||||
print_key_path();
|
||||
impl::print_to_stream("]]"sv, base::stream());
|
||||
pending_table_separator_ = true;
|
||||
print(*reinterpret_cast<const table*>(&arr[i]));
|
||||
}
|
||||
|
||||
key_path.pop_back();
|
||||
base::decrease_indent();
|
||||
}
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
if (base::dump_failed_parse_result())
|
||||
return;
|
||||
|
||||
switch (auto source_type = base::source().type())
|
||||
{
|
||||
case node_type::table:
|
||||
{
|
||||
auto& tbl = *reinterpret_cast<const table*>(&base::source());
|
||||
if (tbl.is_inline())
|
||||
print_inline(tbl);
|
||||
else
|
||||
{
|
||||
base::decrease_indent(); // so root kvps and tables have the same indent
|
||||
print(tbl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&base::source())); break;
|
||||
|
||||
default: base::print_value(base::source(), source_type);
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print();
|
||||
|
||||
/// \endcond
|
||||
|
||||
@ -372,85 +129,22 @@ TOML_NAMESPACE_START
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T, typename U>
|
||||
friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>&, default_formatter<U>&);
|
||||
template <typename T, typename U>
|
||||
friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>&, default_formatter<U>&&);
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, default_formatter& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.key_path_.clear();
|
||||
rhs.print();
|
||||
rhs.detach();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
friend std::ostream& operator<<(std::ostream& lhs, default_formatter&& rhs)
|
||||
{
|
||||
return lhs << rhs; // as lvalue
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API default_formatter<char>;
|
||||
#endif
|
||||
|
||||
default_formatter(const table&)->default_formatter<char>;
|
||||
default_formatter(const array&)->default_formatter<char>;
|
||||
template <typename T>
|
||||
default_formatter(const value<T>&) -> default_formatter<char>;
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.key_path.clear();
|
||||
rhs.print();
|
||||
rhs.detach();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; // as lvalue
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#if !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, default_formatter<char>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, default_formatter<char>&&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const table&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const array&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<std::string>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<int64_t>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<double>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<bool>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<toml::date>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<toml::time>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const value<toml::date_time>&);
|
||||
#endif
|
||||
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const table& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const array& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
#endif // !DOXYGEN
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
@ -2,27 +2,28 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "default_formatter.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "utf8.h"
|
||||
#include "value.h"
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS;
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
inline constexpr size_t default_formatter_line_wrap = 120_sz;
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::string default_formatter_make_key_segment(const std::string& str) noexcept
|
||||
std::string default_formatter::make_key_segment(const std::string& str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return "''"s;
|
||||
@ -30,14 +31,14 @@ TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
bool requires_quotes = false;
|
||||
{
|
||||
utf8_decoder decoder;
|
||||
impl::utf8_decoder decoder;
|
||||
for (size_t i = 0; i < str.length() && !requires_quotes; i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
requires_quotes = true;
|
||||
else if (decoder.has_code_point())
|
||||
requires_quotes = !is_bare_key_character(decoder.codepoint);
|
||||
requires_quotes = !impl::is_bare_key_character(decoder.codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +50,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
for (auto c : str)
|
||||
{
|
||||
if TOML_UNLIKELY(c >= '\x00' && c <= '\x1F')
|
||||
s.append(low_character_escape_table[c]);
|
||||
s.append(impl::low_character_escape_table[c]);
|
||||
else if TOML_UNLIKELY(c == '\x7F')
|
||||
s.append("\\u007F"sv);
|
||||
else if TOML_UNLIKELY(c == '"')
|
||||
@ -66,7 +67,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept
|
||||
size_t default_formatter::count_inline_columns(const node& node) noexcept
|
||||
{
|
||||
switch (node.type())
|
||||
{
|
||||
@ -78,8 +79,8 @@ TOML_IMPL_NAMESPACE_START
|
||||
size_t weight = 3_sz; // "{ }"
|
||||
for (auto&& [k, v] : n)
|
||||
{
|
||||
weight += k.length() + default_formatter_inline_columns(v) + 2_sz; // + ", "
|
||||
if (weight >= default_formatter_line_wrap)
|
||||
weight += k.length() + count_inline_columns(v) + 2_sz; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
break;
|
||||
}
|
||||
return weight;
|
||||
@ -93,8 +94,8 @@ TOML_IMPL_NAMESPACE_START
|
||||
size_t weight = 3_sz; // "[ ]"
|
||||
for (auto& elem : n)
|
||||
{
|
||||
weight += default_formatter_inline_columns(elem) + 2_sz; // + ", "
|
||||
if (weight >= default_formatter_line_wrap)
|
||||
weight += count_inline_columns(elem) + 2_sz; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
break;
|
||||
}
|
||||
return weight;
|
||||
@ -149,33 +150,84 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias) noexcept
|
||||
bool default_formatter::forces_multiline(const node& node, size_t starting_column_bias) noexcept
|
||||
{
|
||||
return (default_formatter_inline_columns(node) + starting_column_bias) >= default_formatter_line_wrap;
|
||||
return (count_inline_columns(node) + starting_column_bias) >= line_wrap_cols;
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename Char>
|
||||
inline void default_formatter<Char>::print_inline(const toml::table& tbl)
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print_pending_table_separator()
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
if (pending_table_separator_)
|
||||
{
|
||||
base::print_newline(true);
|
||||
base::print_newline(true);
|
||||
pending_table_separator_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print_key_segment(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
impl::print_to_stream(base::stream(), "''"sv);
|
||||
else
|
||||
{
|
||||
impl::print_to_stream("{ "sv, base::stream());
|
||||
bool requires_quotes = false;
|
||||
{
|
||||
impl::utf8_decoder decoder;
|
||||
for (size_t i = 0; i < str.length() && !requires_quotes; i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
requires_quotes = true;
|
||||
else if (decoder.has_code_point())
|
||||
requires_quotes = !impl::is_bare_key_character(decoder.codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (requires_quotes)
|
||||
{
|
||||
impl::print_to_stream(base::stream(), '"');
|
||||
impl::print_to_stream_with_escapes(base::stream(), str);
|
||||
impl::print_to_stream(base::stream(), '"');
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(base::stream(), str);
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print_key_path()
|
||||
{
|
||||
for (const auto& segment : key_path_)
|
||||
{
|
||||
if (std::addressof(segment) > key_path_.data())
|
||||
impl::print_to_stream(base::stream(), '.');
|
||||
impl::print_to_stream(base::stream(), segment);
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print_inline(const table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream(base::stream(), "{}"sv);
|
||||
else
|
||||
{
|
||||
impl::print_to_stream(base::stream(), "{ "sv);
|
||||
|
||||
bool first = false;
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
if (first)
|
||||
impl::print_to_stream(", "sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), ", "sv);
|
||||
first = true;
|
||||
|
||||
print_key_segment(k);
|
||||
impl::print_to_stream(" = "sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), " = "sv);
|
||||
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
@ -187,98 +239,216 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
}
|
||||
|
||||
impl::print_to_stream(" }"sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), " }"sv);
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print(const array& arr)
|
||||
{
|
||||
if (arr.empty())
|
||||
impl::print_to_stream(base::stream(), "[]"sv);
|
||||
else
|
||||
{
|
||||
const auto original_indent = base::indent();
|
||||
const auto multiline =
|
||||
forces_multiline(arr,
|
||||
base::indent_columns * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
impl::print_to_stream(base::stream(), "["sv);
|
||||
if (multiline)
|
||||
{
|
||||
if (original_indent < 0)
|
||||
base::indent(0);
|
||||
base::increase_indent();
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(base::stream(), ' ');
|
||||
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
if (i > 0_sz)
|
||||
{
|
||||
impl::print_to_stream(base::stream(), ',');
|
||||
if (!multiline)
|
||||
impl::print_to_stream(base::stream(), ' ');
|
||||
}
|
||||
|
||||
if (multiline)
|
||||
{
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
}
|
||||
|
||||
auto& v = arr[i];
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print_inline(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
if (multiline)
|
||||
{
|
||||
base::indent(original_indent);
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(base::stream(), ' ');
|
||||
impl::print_to_stream(base::stream(), "]"sv);
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print(const table& tbl)
|
||||
{
|
||||
static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept
|
||||
{
|
||||
auto arr = nde.as_array();
|
||||
return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0_sz)->is_inline();
|
||||
};
|
||||
|
||||
// values, arrays, and inline tables/table arrays
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if ((type == node_type::table && !reinterpret_cast<const table*>(&v)->is_inline())
|
||||
|| (type == node_type::array && is_non_inline_array_of_tables(v)))
|
||||
continue;
|
||||
|
||||
pending_table_separator_ = true;
|
||||
base::print_newline();
|
||||
base::print_indent();
|
||||
print_key_segment(k);
|
||||
impl::print_to_stream(base::stream(), " = "sv);
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print_inline(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
|
||||
// non-inline tables
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
const auto type = v.type();
|
||||
if (type != node_type::table || reinterpret_cast<const table*>(&v)->is_inline())
|
||||
continue;
|
||||
auto& child_tbl = *reinterpret_cast<const table*>(&v);
|
||||
|
||||
// we can skip indenting and emitting the headers for tables that only contain other tables
|
||||
// (so we don't over-nest)
|
||||
size_t child_value_count{}; // includes inline tables and non-table arrays
|
||||
size_t child_table_count{};
|
||||
size_t child_table_array_count{};
|
||||
for (auto&& [child_k, child_v] : child_tbl)
|
||||
{
|
||||
(void)child_k;
|
||||
const auto child_type = child_v.type();
|
||||
TOML_ASSUME(child_type != node_type::none);
|
||||
switch (child_type)
|
||||
{
|
||||
case node_type::table:
|
||||
if (reinterpret_cast<const table*>(&child_v)->is_inline())
|
||||
child_value_count++;
|
||||
else
|
||||
child_table_count++;
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if (is_non_inline_array_of_tables(child_v))
|
||||
child_table_array_count++;
|
||||
else
|
||||
child_value_count++;
|
||||
break;
|
||||
|
||||
default: child_value_count++;
|
||||
}
|
||||
}
|
||||
bool skip_self = false;
|
||||
if (child_value_count == 0_sz && (child_table_count > 0_sz || child_table_array_count > 0_sz))
|
||||
skip_self = true;
|
||||
|
||||
key_path_.push_back(make_key_segment(k));
|
||||
|
||||
if (!skip_self)
|
||||
{
|
||||
print_pending_table_separator();
|
||||
base::increase_indent();
|
||||
base::print_indent();
|
||||
impl::print_to_stream(base::stream(), "["sv);
|
||||
print_key_path();
|
||||
impl::print_to_stream(base::stream(), "]"sv);
|
||||
pending_table_separator_ = true;
|
||||
}
|
||||
|
||||
print(child_tbl);
|
||||
|
||||
key_path_.pop_back();
|
||||
if (!skip_self)
|
||||
base::decrease_indent();
|
||||
}
|
||||
|
||||
// table arrays
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
if (!is_non_inline_array_of_tables(v))
|
||||
continue;
|
||||
auto& arr = *reinterpret_cast<const array*>(&v);
|
||||
|
||||
base::increase_indent();
|
||||
key_path_.push_back(make_key_segment(k));
|
||||
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
print_pending_table_separator();
|
||||
base::print_indent();
|
||||
impl::print_to_stream(base::stream(), "[["sv);
|
||||
print_key_path();
|
||||
impl::print_to_stream(base::stream(), "]]"sv);
|
||||
pending_table_separator_ = true;
|
||||
print(*reinterpret_cast<const table*>(&arr[i]));
|
||||
}
|
||||
|
||||
key_path_.pop_back();
|
||||
base::decrease_indent();
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void default_formatter::print()
|
||||
{
|
||||
if (base::dump_failed_parse_result())
|
||||
return;
|
||||
|
||||
switch (auto source_type = base::source().type())
|
||||
{
|
||||
case node_type::table:
|
||||
{
|
||||
auto& tbl = *reinterpret_cast<const table*>(&base::source());
|
||||
if (tbl.is_inline())
|
||||
print_inline(tbl);
|
||||
else
|
||||
{
|
||||
base::decrease_indent(); // so root kvps and tables have the same indent
|
||||
print(tbl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&base::source())); break;
|
||||
|
||||
default: base::print_value(base::source(), source_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
// implementations of windows wide string nonsense
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
#ifndef _WINDOWS_
|
||||
#if TOML_INCLUDE_WINDOWS_H
|
||||
#include <Windows.h>
|
||||
#else
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int CodePage,
|
||||
unsigned long dwFlags,
|
||||
const wchar_t* lpWideCharStr,
|
||||
int cchWideChar,
|
||||
char* lpMultiByteStr,
|
||||
int cbMultiByte,
|
||||
const char* lpDefaultChar,
|
||||
int* lpUsedDefaultChar);
|
||||
|
||||
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage,
|
||||
unsigned long dwFlags,
|
||||
const char* lpMultiByteStr,
|
||||
int cbMultiByte,
|
||||
wchar_t* lpWideCharStr,
|
||||
int cchWideChar);
|
||||
}
|
||||
#endif
|
||||
#endif // _WINDOWS_
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::string narrow(std::wstring_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::string s;
|
||||
const auto len =
|
||||
::WideCharToMultiByte(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
::WideCharToMultiByte(65001,
|
||||
0,
|
||||
str.data(),
|
||||
static_cast<int>(str.length()),
|
||||
s.data(),
|
||||
len,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::wstring s;
|
||||
const auto len = ::MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
::MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::u8string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
return widen(std::string_view{ reinterpret_cast<const char*>(str.data()), str.length() });
|
||||
}
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
||||
|
@ -2,23 +2,20 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "forward_declarations.h"
|
||||
#include "print_to_stream.h"
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
#include "parse_result.h"
|
||||
#endif
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename Char = char>
|
||||
class TOML_API formatter
|
||||
class formatter
|
||||
{
|
||||
private:
|
||||
const toml::node* source_;
|
||||
std::basic_ostream<Char>* stream_ = {};
|
||||
std::ostream* stream_ = {};
|
||||
format_flags flags_;
|
||||
int indent_;
|
||||
bool naked_newline_;
|
||||
@ -28,13 +25,15 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
protected:
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
const toml::node& source() const noexcept
|
||||
{
|
||||
return *source_;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
std::basic_ostream<Char>& stream() const noexcept
|
||||
TOML_ALWAYS_INLINE
|
||||
std::ostream& stream() const noexcept
|
||||
{
|
||||
return *stream_;
|
||||
}
|
||||
@ -66,25 +65,25 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
bool quote_dates_and_times() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::quote_dates_and_times) != format_flags::none;
|
||||
return !!(flags_ & format_flags::quote_dates_and_times);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool literal_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_literal_strings) != format_flags::none;
|
||||
return !!(flags_ & format_flags::allow_literal_strings);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool multi_line_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_multi_line_strings) != format_flags::none;
|
||||
return !!(flags_ & format_flags::allow_multi_line_strings);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool value_format_flags_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_value_format_flags) != format_flags::none;
|
||||
return !!(flags_ & format_flags::allow_value_format_flags);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
@ -98,175 +97,50 @@ TOML_IMPL_NAMESPACE_START
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
void attach(std::basic_ostream<Char>& stream) noexcept
|
||||
{
|
||||
indent_ = {};
|
||||
naked_newline_ = true;
|
||||
stream_ = &stream;
|
||||
}
|
||||
TOML_API
|
||||
void attach(std::ostream& stream) noexcept;
|
||||
|
||||
void detach() noexcept
|
||||
{
|
||||
stream_ = nullptr;
|
||||
}
|
||||
TOML_API
|
||||
void detach() noexcept;
|
||||
|
||||
void print_newline(bool force = false)
|
||||
{
|
||||
if (!naked_newline_ || force)
|
||||
{
|
||||
print_to_stream('\n', *stream_);
|
||||
naked_newline_ = true;
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print_newline(bool force = false);
|
||||
|
||||
void print_indent()
|
||||
{
|
||||
for (int i = 0; i < indent_; i++)
|
||||
{
|
||||
print_to_stream(indent_string, *stream_);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print_indent();
|
||||
|
||||
void print_quoted_string(std::string_view str, bool allow_multi_line = true)
|
||||
{
|
||||
auto literals = literal_strings_allowed();
|
||||
if (str.empty())
|
||||
{
|
||||
print_to_stream(literals ? "''"sv : "\"\""sv, *stream_);
|
||||
clear_naked_newline();
|
||||
return;
|
||||
}
|
||||
TOML_API
|
||||
void print_quoted_string(std::string_view str, bool allow_multi_line = true);
|
||||
|
||||
auto multi_line = allow_multi_line && multi_line_strings_allowed();
|
||||
if (multi_line || literals)
|
||||
{
|
||||
utf8_decoder decoder;
|
||||
bool has_line_breaks = false;
|
||||
bool has_control_chars = false;
|
||||
bool has_single_quotes = false;
|
||||
for (size_t i = 0; i < str.length() && !(has_line_breaks && has_control_chars && has_single_quotes);
|
||||
i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
{
|
||||
has_line_breaks = false;
|
||||
has_control_chars = true; // force ""
|
||||
has_single_quotes = true;
|
||||
break;
|
||||
}
|
||||
else if (decoder.has_code_point())
|
||||
{
|
||||
if (is_line_break(decoder.codepoint))
|
||||
has_line_breaks = true;
|
||||
else if (is_nontab_control_character(decoder.codepoint))
|
||||
has_control_chars = true;
|
||||
else if (decoder.codepoint == U'\'')
|
||||
has_single_quotes = true;
|
||||
}
|
||||
}
|
||||
multi_line = multi_line && has_line_breaks;
|
||||
literals = literals && !has_control_chars && !(!multi_line && has_single_quotes);
|
||||
}
|
||||
TOML_API
|
||||
void print(const value<std::string>&);
|
||||
|
||||
if (literals)
|
||||
{
|
||||
const auto quot = multi_line ? "'''"sv : "'"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(str, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto quot = multi_line ? R"(""")"sv : R"(")"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream_with_escapes(str, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
clear_naked_newline();
|
||||
}
|
||||
TOML_API
|
||||
void print(const value<int64_t>&);
|
||||
|
||||
template <typename T>
|
||||
void print(const value<T>& val)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
{
|
||||
print_quoted_string(val.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (is_one_of<T, date, time, date_time>)
|
||||
{
|
||||
if (quote_dates_and_times())
|
||||
{
|
||||
const auto quot = literal_strings_allowed() ? '\'' : '"';
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(*val, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else if constexpr (is_one_of<T, int64_t /*, double*/>)
|
||||
{
|
||||
if (value_format_flags_allowed() && *val >= 0)
|
||||
{
|
||||
const auto fmt = val.flags() & value_flags::format_as_hexadecimal;
|
||||
if (fmt != value_flags::none)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case value_flags::format_as_binary: print_to_stream("0b"sv, *stream_); break;
|
||||
case value_flags::format_as_octal: print_to_stream("0o"sv, *stream_); break;
|
||||
case value_flags::format_as_hexadecimal: print_to_stream("0x"sv, *stream_); break;
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
print_to_stream(*val, *stream_, fmt);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
TOML_API
|
||||
void print(const value<double>&);
|
||||
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print(const value<bool>&);
|
||||
|
||||
void print_value(const node& val_node, node_type type)
|
||||
{
|
||||
TOML_ASSUME(type > node_type::array);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::string: print(*reinterpret_cast<const value<std::string>*>(&val_node)); break;
|
||||
case node_type::integer: print(*reinterpret_cast<const value<int64_t>*>(&val_node)); break;
|
||||
case node_type::floating_point: print(*reinterpret_cast<const value<double>*>(&val_node)); break;
|
||||
case node_type::boolean: print(*reinterpret_cast<const value<bool>*>(&val_node)); break;
|
||||
case node_type::date: print(*reinterpret_cast<const value<date>*>(&val_node)); break;
|
||||
case node_type::time: print(*reinterpret_cast<const value<time>*>(&val_node)); break;
|
||||
case node_type::date_time: print(*reinterpret_cast<const value<date_time>*>(&val_node)); break;
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print(const value<date>&);
|
||||
|
||||
TOML_API
|
||||
void print(const value<time>&);
|
||||
|
||||
TOML_API
|
||||
void print(const value<date_time>&);
|
||||
|
||||
TOML_API
|
||||
void print_value(const node&, node_type);
|
||||
|
||||
TOML_NODISCARD
|
||||
bool dump_failed_parse_result()
|
||||
{
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
if (result_ && !(*result_))
|
||||
{
|
||||
stream() << result_->error();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
TOML_API
|
||||
bool dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS);
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
formatter(const toml::node& source, format_flags flags) noexcept //
|
||||
: source_{ &source },
|
||||
flags_{ flags }
|
||||
@ -274,18 +148,12 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
formatter(const parse_result& result, format_flags flags) noexcept //
|
||||
: source_{ result ? &result.table() : nullptr },
|
||||
flags_{ flags },
|
||||
result_{ &result }
|
||||
{}
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
formatter(const parse_result& result, format_flags flags) noexcept;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API formatter<char>;
|
||||
#endif
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
|
233
include/toml++/impl/formatter_impl.h
Normal file
233
include/toml++/impl/formatter_impl.h
Normal file
@ -0,0 +1,233 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "formatter.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "utf8.h"
|
||||
#include "value.h"
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "parse_result.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
formatter::formatter(const parse_result& result, format_flags flags) noexcept //
|
||||
: source_{ result ? &result.table() : nullptr },
|
||||
flags_{ flags },
|
||||
result_{ &result }
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::attach(std::ostream & stream) noexcept
|
||||
{
|
||||
indent_ = {};
|
||||
naked_newline_ = true;
|
||||
stream_ = &stream;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::detach() noexcept
|
||||
{
|
||||
stream_ = nullptr;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print_newline(bool force)
|
||||
{
|
||||
if (!naked_newline_ || force)
|
||||
{
|
||||
print_to_stream(*stream_, '\n');
|
||||
naked_newline_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print_indent()
|
||||
{
|
||||
for (int i = 0; i < indent_; i++)
|
||||
{
|
||||
print_to_stream(*stream_, indent_string);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print_quoted_string(std::string_view str, bool allow_multi_line)
|
||||
{
|
||||
auto literals = literal_strings_allowed();
|
||||
if (str.empty())
|
||||
{
|
||||
print_to_stream(*stream_, literals ? "''"sv : "\"\""sv);
|
||||
naked_newline_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
auto multi_line = allow_multi_line && multi_line_strings_allowed();
|
||||
if (multi_line || literals)
|
||||
{
|
||||
utf8_decoder decoder;
|
||||
bool has_line_breaks = false;
|
||||
bool has_control_chars = false;
|
||||
bool has_single_quotes = false;
|
||||
for (size_t i = 0; i < str.length() && !(has_line_breaks && has_control_chars && has_single_quotes); i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
{
|
||||
has_line_breaks = false;
|
||||
has_control_chars = true; // force ""
|
||||
has_single_quotes = true;
|
||||
break;
|
||||
}
|
||||
else if (decoder.has_code_point())
|
||||
{
|
||||
if (is_line_break(decoder.codepoint))
|
||||
has_line_breaks = true;
|
||||
else if (is_nontab_control_character(decoder.codepoint))
|
||||
has_control_chars = true;
|
||||
else if (decoder.codepoint == U'\'')
|
||||
has_single_quotes = true;
|
||||
}
|
||||
}
|
||||
multi_line = multi_line && has_line_breaks;
|
||||
literals = literals && !has_control_chars && !(!multi_line && has_single_quotes);
|
||||
}
|
||||
|
||||
if (literals)
|
||||
print_to_stream_bookended(*stream_, str, multi_line ? "'''"sv : "'"sv);
|
||||
else
|
||||
{
|
||||
const auto quot = multi_line ? R"(""")"sv : R"(")"sv;
|
||||
print_to_stream(*stream_, quot);
|
||||
print_to_stream_with_escapes(*stream_, str);
|
||||
print_to_stream(*stream_, quot);
|
||||
}
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<std::string>& val)
|
||||
{
|
||||
print_quoted_string(val.get());
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<int64_t>& val)
|
||||
{
|
||||
if (value_format_flags_allowed() && *val >= 0)
|
||||
{
|
||||
static constexpr auto value_format_flags =
|
||||
value_flags::format_as_binary | value_flags::format_as_octal | value_flags::format_as_hexadecimal;
|
||||
const auto fmt = val.flags() & value_format_flags;
|
||||
if (fmt != value_flags::none)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case value_flags::format_as_binary: print_to_stream(*stream_, "0b"sv); break;
|
||||
case value_flags::format_as_octal: print_to_stream(*stream_, "0o"sv); break;
|
||||
case value_flags::format_as_hexadecimal: print_to_stream(*stream_, "0x"sv); break;
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
print_to_stream(*stream_, *val, fmt);
|
||||
}
|
||||
else
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<double>& val)
|
||||
{
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<bool>& val)
|
||||
{
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<date>& val)
|
||||
{
|
||||
if (quote_dates_and_times())
|
||||
print_to_stream_bookended(*stream_, *val, literal_strings_allowed() ? '\'' : '"');
|
||||
else
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<time>& val)
|
||||
{
|
||||
if (quote_dates_and_times())
|
||||
print_to_stream_bookended(*stream_, *val, literal_strings_allowed() ? '\'' : '"');
|
||||
else
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print(const value<date_time>& val)
|
||||
{
|
||||
if (quote_dates_and_times())
|
||||
print_to_stream_bookended(*stream_, *val, literal_strings_allowed() ? '\'' : '"');
|
||||
else
|
||||
print_to_stream(*stream_, *val);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::print_value(const node& val_node, node_type type)
|
||||
{
|
||||
TOML_ASSUME(type > node_type::array);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::string: print(*reinterpret_cast<const value<std::string>*>(&val_node)); break;
|
||||
case node_type::integer: print(*reinterpret_cast<const value<int64_t>*>(&val_node)); break;
|
||||
case node_type::floating_point: print(*reinterpret_cast<const value<double>*>(&val_node)); break;
|
||||
case node_type::boolean: print(*reinterpret_cast<const value<bool>*>(&val_node)); break;
|
||||
case node_type::date: print(*reinterpret_cast<const value<date>*>(&val_node)); break;
|
||||
case node_type::time: print(*reinterpret_cast<const value<time>*>(&val_node)); break;
|
||||
case node_type::date_time: print(*reinterpret_cast<const value<date_time>*>(&val_node)); break;
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool formatter::dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS)
|
||||
{
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
if (result_ && !(*result_))
|
||||
{
|
||||
stream() << result_->error();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
//# {{
|
||||
#ifdef __INTELLISENSE__
|
||||
#include "preprocessor.h"
|
||||
#include "preprocessor.h"
|
||||
#endif
|
||||
//# }}
|
||||
TOML_POP_WARNINGS;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//# {{
|
||||
#ifdef __INTELLISENSE__
|
||||
#include "preprocessor.h"
|
||||
#include "preprocessor.h"
|
||||
#endif
|
||||
//# }}
|
||||
TOML_PUSH_WARNINGS;
|
||||
|
@ -2,11 +2,9 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "formatter.h"
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
@ -41,65 +39,21 @@ TOML_NAMESPACE_START
|
||||
/// }
|
||||
/// }
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The underlying character type of the output stream. Must be 1 byte in size.
|
||||
template <typename Char = char>
|
||||
class TOML_API json_formatter final : impl::formatter<Char>
|
||||
class json_formatter : impl::formatter
|
||||
{
|
||||
private:
|
||||
/// \cond
|
||||
|
||||
using base = impl::formatter<Char>;
|
||||
using base = impl::formatter;
|
||||
|
||||
void print(const toml::table& tbl);
|
||||
TOML_API
|
||||
void print(const toml::table&);
|
||||
|
||||
void print(const array& arr)
|
||||
{
|
||||
if (arr.empty())
|
||||
impl::print_to_stream("[]"sv, base::stream());
|
||||
else
|
||||
{
|
||||
impl::print_to_stream('[', base::stream());
|
||||
base::increase_indent();
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
if (i > 0_sz)
|
||||
impl::print_to_stream(',', base::stream());
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
TOML_API
|
||||
void print(const toml::array&);
|
||||
|
||||
auto& v = arr[i];
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
base::decrease_indent();
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
impl::print_to_stream(']', base::stream());
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
if (base::dump_failed_parse_result())
|
||||
return;
|
||||
|
||||
switch (auto source_type = base::source().type())
|
||||
{
|
||||
case node_type::table: print(*reinterpret_cast<const table*>(&base::source())); break;
|
||||
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&base::source())); break;
|
||||
|
||||
default: base::print_value(base::source(), source_type);
|
||||
}
|
||||
}
|
||||
TOML_API
|
||||
void print();
|
||||
|
||||
/// \endcond
|
||||
|
||||
@ -149,44 +103,21 @@ TOML_NAMESPACE_START
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T, typename U>
|
||||
friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>&, json_formatter<U>&);
|
||||
template <typename T, typename U>
|
||||
friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>&, json_formatter<U>&&);
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, json_formatter& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.print();
|
||||
rhs.detach();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
friend std::ostream& operator<<(std::ostream& lhs, json_formatter&& rhs)
|
||||
{
|
||||
return lhs << rhs; // as lvalue
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template class TOML_API json_formatter<char>;
|
||||
#endif
|
||||
|
||||
json_formatter(const table&)->json_formatter<char>;
|
||||
json_formatter(const array&)->json_formatter<char>;
|
||||
template <typename T>
|
||||
json_formatter(const value<T>&) -> json_formatter<char>;
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
rhs.print();
|
||||
rhs.detach();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
inline std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; // as lvalue
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, json_formatter<char>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, json_formatter<char>&&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
@ -2,41 +2,44 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "json_formatter.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template <typename Char>
|
||||
inline void json_formatter<Char>::print(const toml::table& tbl)
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void json_formatter::print(const toml::table& tbl)
|
||||
{
|
||||
if (tbl.empty())
|
||||
impl::print_to_stream("{}"sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), "{}"sv);
|
||||
else
|
||||
{
|
||||
impl::print_to_stream('{', base::stream());
|
||||
impl::print_to_stream(base::stream(), '{');
|
||||
base::increase_indent();
|
||||
bool first = false;
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
if (first)
|
||||
impl::print_to_stream(", "sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), ", "sv);
|
||||
first = true;
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
|
||||
base::print_quoted_string(k, false);
|
||||
impl::print_to_stream(" : "sv, base::stream());
|
||||
impl::print_to_stream(base::stream(), " : "sv);
|
||||
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
@ -50,12 +53,60 @@ TOML_NAMESPACE_START
|
||||
base::decrease_indent();
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
impl::print_to_stream('}', base::stream());
|
||||
impl::print_to_stream(base::stream(), '}');
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void json_formatter::print(const toml::array& arr)
|
||||
{
|
||||
if (arr.empty())
|
||||
impl::print_to_stream(base::stream(), "[]"sv);
|
||||
else
|
||||
{
|
||||
impl::print_to_stream(base::stream(), '[');
|
||||
base::increase_indent();
|
||||
for (size_t i = 0; i < arr.size(); i++)
|
||||
{
|
||||
if (i > 0_sz)
|
||||
impl::print_to_stream(base::stream(), ',');
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
|
||||
auto& v = arr[i];
|
||||
const auto type = v.type();
|
||||
TOML_ASSUME(type != node_type::none);
|
||||
switch (type)
|
||||
{
|
||||
case node_type::table: print(*reinterpret_cast<const table*>(&v)); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&v)); break;
|
||||
default: base::print_value(v, type);
|
||||
}
|
||||
}
|
||||
base::decrease_indent();
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
impl::print_to_stream(base::stream(), ']');
|
||||
}
|
||||
base::clear_naked_newline();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void json_formatter::print()
|
||||
{
|
||||
if (base::dump_failed_parse_result())
|
||||
return;
|
||||
|
||||
switch (auto source_type = base::source().type())
|
||||
{
|
||||
case node_type::table: print(*reinterpret_cast<const table*>(&base::source())); break;
|
||||
case node_type::array: print(*reinterpret_cast<const array*>(&base::source())); break;
|
||||
default: base::print_value(base::source(), source_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
||||
|
122
include/toml++/impl/make_node.h
Normal file
122
include/toml++/impl/make_node.h
Normal file
@ -0,0 +1,122 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "forward_declarations.h"
|
||||
#include "header_start.h"
|
||||
|
||||
/// \cond
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T && val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref_t<T>, type>)
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled.");
|
||||
static_assert(is_native<type> || is_losslessly_convertible_to_native<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types");
|
||||
|
||||
using value_type = native_type_of<remove_cvref_t<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
#else
|
||||
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return new value<value_type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(T && val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
{
|
||||
if constexpr (is_node_view<type>)
|
||||
{
|
||||
if (!val)
|
||||
return static_cast<toml::node*>(nullptr);
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit(
|
||||
[](auto&& concrete) noexcept {
|
||||
return static_cast<toml::node*>(make_node_specialized(static_cast<decltype(concrete)&&>(concrete)));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(inserter<T> && val) noexcept
|
||||
{
|
||||
return make_node(static_cast<T&&>(val.value));
|
||||
}
|
||||
|
||||
template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
|
||||
struct inserted_type_of_
|
||||
{
|
||||
using type = std::remove_pointer_t<decltype(make_node(std::declval<T>()))>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct inserted_type_of_<inserter<T>, false>
|
||||
{
|
||||
using type = typename inserted_type_of_<T>::type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct inserted_type_of_<T, false>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
/// \endcond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief Metafunction for determining which node type would be constructed
|
||||
/// if an object of this type was inserted into a toml::table or toml::array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// static_assert(std::is_same_v<toml::inserted_type_of<const char*>, toml::value<std::string>);
|
||||
/// static_assert(std::is_same_v<toml::inserted_type_of<int>, toml::value<int64_t>);
|
||||
/// static_assert(std::is_same_v<toml::inserted_type_of<float>, toml::value<double>);
|
||||
/// static_assert(std::is_same_v<toml::inserted_type_of<bool>, toml::value<bool>);
|
||||
/// \ecpp
|
||||
///
|
||||
/// \note This will return toml::node for nodes and node_views, even though a more specific node subclass
|
||||
/// would actually be inserted. There is no way around this in a compile-time metafunction.
|
||||
template <typename T>
|
||||
using inserted_type_of =
|
||||
POXY_IMPLEMENTATION_DETAIL(typename impl::inserted_type_of_<impl::remove_cvref_t<T>>::type);
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
@ -2,9 +2,10 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
#include "forward_declarations.h"
|
||||
#include "source_region.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
@ -13,14 +14,14 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
|
||||
/// This type is the base of each of those, providing a lot of the polymorphic plumbing.
|
||||
class TOML_ABSTRACT_BASE TOML_API node
|
||||
class TOML_ABSTRACT_BASE node
|
||||
{
|
||||
private:
|
||||
/// \cond
|
||||
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
source_region source_{};
|
||||
|
||||
/// \cond
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
decltype(auto) get_value_exact() const noexcept;
|
||||
@ -42,13 +43,19 @@ TOML_NAMESPACE_START
|
||||
return static_cast<N&&>(n).template ref_cast<type>();
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
protected:
|
||||
node() noexcept = default;
|
||||
|
||||
TOML_API
|
||||
node(const node&) noexcept;
|
||||
|
||||
TOML_API
|
||||
node(node&&) noexcept;
|
||||
|
||||
TOML_API
|
||||
node& operator=(const node&) noexcept;
|
||||
|
||||
TOML_API
|
||||
node& operator=(node&&) noexcept;
|
||||
|
||||
template <typename T>
|
||||
@ -81,43 +88,39 @@ TOML_NAMESPACE_START
|
||||
template <typename N, typename T>
|
||||
using ref_cast_type = decltype(std::declval<N>().template ref_cast<T>());
|
||||
|
||||
/// \endcond
|
||||
|
||||
public:
|
||||
virtual ~node() noexcept = default;
|
||||
TOML_API
|
||||
virtual ~node() noexcept;
|
||||
|
||||
/// \name Type checks
|
||||
/// @{
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_ICC || TOML_ICC_CL
|
||||
|
||||
/// \brief Returns the node's type identifier.
|
||||
TOML_NODISCARD
|
||||
virtual node_type type() const noexcept = 0;
|
||||
|
||||
#else
|
||||
|
||||
TOML_NODISCARD
|
||||
virtual node_type type() const noexcept
|
||||
{
|
||||
// Q: "what the fuck?"
|
||||
// A: https://github.com/marzer/tomlplusplus/issues/83
|
||||
// tl,dr: go home ICC, you're drunk.
|
||||
|
||||
return type();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Returns true if this node is a table.
|
||||
TOML_NODISCARD
|
||||
virtual bool is_table() const noexcept = 0;
|
||||
virtual bool is_table() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Returns true if this node is an array.
|
||||
TOML_NODISCARD
|
||||
virtual bool is_array() const noexcept = 0;
|
||||
virtual bool is_array() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Returns true if this node is a value.
|
||||
TOML_NODISCARD
|
||||
virtual bool is_value() const noexcept = 0;
|
||||
virtual bool is_value() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Returns true if this node is a string value.
|
||||
TOML_NODISCARD
|
||||
@ -699,13 +702,13 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
auto value_or(T&& default_value) const noexcept;
|
||||
|
||||
// template <typename T>
|
||||
// TOML_NODISCARD
|
||||
// std::vector<T> select_exact() const noexcept;
|
||||
//# template <typename T>
|
||||
//# TOML_NODISCARD
|
||||
//# std::vector<T> select_exact() const noexcept;
|
||||
|
||||
// template <typename T>
|
||||
// TOML_NODISCARD
|
||||
// std::vector<T> select() const noexcept;
|
||||
//# template <typename T>
|
||||
//# TOML_NODISCARD
|
||||
//# std::vector<T> select() const noexcept;
|
||||
|
||||
/// \brief Gets a raw reference to a value node's underlying data.
|
||||
///
|
||||
|
@ -2,18 +2,19 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "node.h"
|
||||
#include "node_view.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
@ -50,18 +51,9 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::operator node_view<node>() noexcept
|
||||
{
|
||||
return node_view<node>(this);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::operator node_view<const node>() const noexcept
|
||||
{
|
||||
return node_view<const node>(this);
|
||||
}
|
||||
node::~node() noexcept = default;
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
||||
|
@ -4,13 +4,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
#include "table.h"
|
||||
#include "array.h"
|
||||
#include "value.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "node.h"
|
||||
#include "std_vector.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief A view of a node.
|
||||
@ -57,12 +55,13 @@ TOML_NAMESPACE_START
|
||||
/// product[2]:
|
||||
/// \eout
|
||||
template <typename ViewedType>
|
||||
class TOML_API TOML_TRIVIAL_ABI node_view
|
||||
class TOML_TRIVIAL_ABI node_view
|
||||
{
|
||||
static_assert(impl::is_one_of<ViewedType, toml::node, const toml::node>,
|
||||
"A toml::node_view<> must wrap toml::node or const toml::node.");
|
||||
|
||||
public:
|
||||
/// \brief The node type being viewed - either `node` or `const node`.
|
||||
using viewed_type = ViewedType;
|
||||
|
||||
private:
|
||||
@ -440,9 +439,6 @@ TOML_NAMESPACE_START
|
||||
return {};
|
||||
}
|
||||
|
||||
TOML_PUSH_WARNINGS;
|
||||
TOML_DISABLE_INIT_WARNINGS;
|
||||
|
||||
/// \brief Gets the value contained by the referenced node.
|
||||
///
|
||||
/// \detail This function has 'permissive' retrieval semantics; some value types are allowed
|
||||
@ -471,8 +467,6 @@ TOML_NAMESPACE_START
|
||||
return {};
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS;
|
||||
|
||||
/// \brief Gets the raw value contained by the referenced node, or a default.
|
||||
///
|
||||
/// \tparam T Default value type. Must be one of the native TOML value types,
|
||||
@ -721,48 +715,40 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// @}
|
||||
|
||||
template <typename Char, typename T>
|
||||
friend std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>&, const node_view<T>&);
|
||||
/// \brief Prints the viewed node out to a stream.
|
||||
friend std::ostream& operator<<(std::ostream& os, const node_view& nv)
|
||||
{
|
||||
if (nv.node_)
|
||||
nv.node_->visit([&os](const auto& n) { os << n; });
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
|
||||
template <typename T>
|
||||
node_view(const value<T>&) -> node_view<const node>;
|
||||
node_view(const table&)->node_view<const node>;
|
||||
node_view(const array&)->node_view<const node>;
|
||||
template <typename T>
|
||||
node_view(value<T>&) -> node_view<node>;
|
||||
node_view(table&)->node_view<node>;
|
||||
node_view(array&)->node_view<node>;
|
||||
node_view(const T&) -> node_view<const node>;
|
||||
|
||||
template <typename T>
|
||||
node_view(const T*) -> node_view<const node>;
|
||||
|
||||
template <typename T>
|
||||
node_view(T&) -> node_view<node>;
|
||||
|
||||
template <typename T>
|
||||
node_view(T*) -> node_view<node>;
|
||||
|
||||
/// \brief Prints the viewed node out to a stream.
|
||||
template <typename Char, typename T>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, const node_view<T>& nv)
|
||||
{
|
||||
if (nv.node_)
|
||||
{
|
||||
nv.node_->visit([&os](const auto& n) { os << n; });
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
#if TOML_EXTERN_TEMPLATES
|
||||
|
||||
extern template class TOML_API node_view<node>;
|
||||
extern template class TOML_API node_view<const node>;
|
||||
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const node_view<node>&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const node_view<const node>&);
|
||||
#define TOML_EXTERN(name, T) \
|
||||
extern template TOML_API \
|
||||
optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
extern template TOML_API \
|
||||
optional<T> node_view<const node>::name<T>() const noexcept
|
||||
|
||||
#define TOML_EXTERN(name, T) \
|
||||
extern template TOML_API \
|
||||
optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
extern template TOML_API \
|
||||
optional<T> node_view<const node>::name<T>() const noexcept
|
||||
TOML_EXTERN(value_exact, std::string_view);
|
||||
TOML_EXTERN(value_exact, std::string);
|
||||
TOML_EXTERN(value_exact, const char*);
|
||||
@ -792,23 +778,35 @@ TOML_NAMESPACE_START
|
||||
TOML_EXTERN(value, date_time);
|
||||
TOML_EXTERN(value, bool);
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_EXTERN(value_exact, std::u8string_view);
|
||||
TOML_EXTERN(value_exact, std::u8string);
|
||||
TOML_EXTERN(value_exact, const char8_t*);
|
||||
TOML_EXTERN(value, std::u8string_view);
|
||||
TOML_EXTERN(value, std::u8string);
|
||||
TOML_EXTERN(value, const char8_t*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_EXTERN(value_exact, std::wstring);
|
||||
TOML_EXTERN(value, std::wstring);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef TOML_EXTERN
|
||||
#undef TOML_EXTERN
|
||||
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
|
||||
inline node::operator node_view<node>() noexcept
|
||||
{
|
||||
return node_view<node>(this);
|
||||
}
|
||||
|
||||
inline node::operator node_view<const node>() const noexcept
|
||||
{
|
||||
return node_view<const node>(this);
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
78
include/toml++/impl/node_view_impl.h
Normal file
78
include/toml++/impl/node_view_impl.h
Normal file
@ -0,0 +1,78 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#if TOML_EXTERN_TEMPLATES
|
||||
#include "node_view.h"
|
||||
#include "date_time.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template class node_view<node>;
|
||||
template class node_view<const node>;
|
||||
|
||||
#define TOML_EXTERN(name, T) \
|
||||
template optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
template optional<T> node_view<const node>::name<T>() const noexcept
|
||||
|
||||
TOML_EXTERN(value_exact, std::string_view);
|
||||
TOML_EXTERN(value_exact, std::string);
|
||||
TOML_EXTERN(value_exact, const char*);
|
||||
TOML_EXTERN(value_exact, int64_t);
|
||||
TOML_EXTERN(value_exact, double);
|
||||
TOML_EXTERN(value_exact, date);
|
||||
TOML_EXTERN(value_exact, time);
|
||||
TOML_EXTERN(value_exact, date_time);
|
||||
TOML_EXTERN(value_exact, bool);
|
||||
TOML_EXTERN(value, std::string_view);
|
||||
TOML_EXTERN(value, std::string);
|
||||
TOML_EXTERN(value, const char*);
|
||||
TOML_EXTERN(value, signed char);
|
||||
TOML_EXTERN(value, signed short);
|
||||
TOML_EXTERN(value, signed int);
|
||||
TOML_EXTERN(value, signed long);
|
||||
TOML_EXTERN(value, signed long long);
|
||||
TOML_EXTERN(value, unsigned char);
|
||||
TOML_EXTERN(value, unsigned short);
|
||||
TOML_EXTERN(value, unsigned int);
|
||||
TOML_EXTERN(value, unsigned long);
|
||||
TOML_EXTERN(value, unsigned long long);
|
||||
TOML_EXTERN(value, double);
|
||||
TOML_EXTERN(value, float);
|
||||
TOML_EXTERN(value, date);
|
||||
TOML_EXTERN(value, time);
|
||||
TOML_EXTERN(value, date_time);
|
||||
TOML_EXTERN(value, bool);
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_EXTERN(value_exact, std::u8string_view);
|
||||
TOML_EXTERN(value_exact, std::u8string);
|
||||
TOML_EXTERN(value_exact, const char8_t*);
|
||||
TOML_EXTERN(value, std::u8string_view);
|
||||
TOML_EXTERN(value, std::u8string);
|
||||
TOML_EXTERN(value, const char8_t*);
|
||||
#endif
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_EXTERN(value_exact, std::wstring);
|
||||
TOML_EXTERN(value, std::wstring);
|
||||
#endif
|
||||
|
||||
#undef TOML_EXTERN
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
/// \endcond
|
@ -2,85 +2,53 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "preprocessor.h"
|
||||
#if defined(DOXYGEN) || TOML_PARSER
|
||||
|
||||
#include "std_except.h"
|
||||
#include "source_region.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "header_start.h"
|
||||
TOML_DISABLE_INIT_WARNINGS;
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
#define TOML_PARSE_ERROR_BASE
|
||||
#else
|
||||
#define TOML_PARSE_ERROR_BASE : public std::runtime_error
|
||||
#endif
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
|
||||
/// \brief An error generated when parsing fails.
|
||||
///
|
||||
/// \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
|
||||
class parse_error TOML_PARSE_ERROR_BASE
|
||||
{
|
||||
private:
|
||||
#if !TOML_EXCEPTIONS
|
||||
std::string description_;
|
||||
#endif
|
||||
source_region source_;
|
||||
|
||||
public:
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, source_region&& src) noexcept
|
||||
: description_{ std::move(desc) },
|
||||
source_{ std::move(src) }
|
||||
{}
|
||||
#if TOML_EXCEPTIONS
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, const source_region& src) noexcept
|
||||
: parse_error{ std::move(desc), source_region{ src } }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, const source_position& position, const source_path_ptr& path = {}) noexcept
|
||||
: parse_error{ std::move(desc), source_region{ position, position, path } }
|
||||
{}
|
||||
|
||||
/// \brief Returns a textual description of the error.
|
||||
/// \remark The backing string is guaranteed to be null-terminated.
|
||||
TOML_NODISCARD
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
/// \brief Returns the region of the source document responsible for the error.
|
||||
TOML_NODISCARD
|
||||
const source_region& source() const noexcept
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class parse_error final : public std::runtime_error
|
||||
{
|
||||
private:
|
||||
source_region source_;
|
||||
|
||||
public:
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_ATTR(nonnull)
|
||||
parse_error(const char* desc, source_region&& src) noexcept
|
||||
parse_error(const char* desc, source_region&& src) noexcept //
|
||||
: std::runtime_error{ desc },
|
||||
source_{ std::move(src) }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_ATTR(nonnull)
|
||||
parse_error(const char* desc, const source_region& src) noexcept : parse_error{ desc, source_region{ src } }
|
||||
parse_error(const char* desc, const source_region& src) noexcept //
|
||||
: parse_error{ desc, source_region{ src } }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
@ -89,62 +57,84 @@ TOML_NAMESPACE_START
|
||||
: parse_error{ desc, source_region{ position, position, path } }
|
||||
{}
|
||||
|
||||
#else
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, source_region&& src) noexcept //
|
||||
: description_{ std::move(desc) },
|
||||
source_{ std::move(src) }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, const source_region& src) noexcept //
|
||||
: parse_error{ std::move(desc), source_region{ src } }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
parse_error(std::string&& desc, const source_position& position, const source_path_ptr& path = {}) noexcept
|
||||
: parse_error{ std::move(desc), source_region{ position, position, path } }
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Returns a textual description of the error.
|
||||
/// \remark The backing string is guaranteed to be null-terminated.
|
||||
TOML_NODISCARD
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
return std::string_view{ what() };
|
||||
#else
|
||||
return description_;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Returns the region of the source document responsible for the error.
|
||||
TOML_NODISCARD
|
||||
const source_region& source() const noexcept
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
|
||||
/// \brief Prints a parse_error to a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// try
|
||||
/// {
|
||||
/// auto tbl = toml::parse("enabled = trUe"sv);
|
||||
/// }
|
||||
/// catch (const toml::parse_error & err)
|
||||
/// {
|
||||
/// std::cerr << "Parsing failed:\n"sv << err << "\n";
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// Parsing failed:
|
||||
/// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
|
||||
/// (error occurred at line 1, column 13)
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The parse_error.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const parse_error& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs.description());
|
||||
impl::print_to_stream(lhs, "\n\t(error occurred at "sv);
|
||||
impl::print_to_stream(lhs, rhs.source());
|
||||
impl::print_to_stream(lhs, ")"sv);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
|
||||
/// \brief Prints a parse_error to a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// try
|
||||
/// {
|
||||
/// auto tbl = toml::parse("enabled = trUe"sv);
|
||||
/// }
|
||||
/// catch (const toml::parse_error & err)
|
||||
/// {
|
||||
/// std::cerr << "Parsing failed:\n"sv << err << "\n";
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// Parsing failed:
|
||||
/// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
|
||||
/// (error occurred at line 1, column 13)
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The parse_error.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const parse_error& rhs)
|
||||
{
|
||||
lhs << rhs.description();
|
||||
lhs << "\n\t(error occurred at "sv;
|
||||
lhs << rhs.source();
|
||||
lhs << ")"sv;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const parse_error&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#undef TOML_PARSE_ERROR_BASE
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_PARSER
|
||||
|
@ -2,19 +2,15 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
|
||||
|
||||
#include "table.h"
|
||||
#include "parse_error.h"
|
||||
#include "header_start.h"
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_START(noex);
|
||||
@ -292,7 +288,7 @@ TOML_NAMESPACE_START
|
||||
return err_ ? node_view<const node>{} : table()[key];
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
||||
///
|
||||
@ -326,7 +322,7 @@ TOML_NAMESPACE_START
|
||||
return err_ ? node_view<const node>{} : table()[key];
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
@ -377,8 +373,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
/// \brief Prints the held error or table object out to a text stream.
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, const parse_result& result)
|
||||
friend std::ostream& operator<<(std::ostream& os, const parse_result& result)
|
||||
{
|
||||
return result.err_ ? (os << result.error()) : (os << result.table());
|
||||
}
|
||||
@ -387,6 +382,6 @@ TOML_NAMESPACE_START
|
||||
TOML_ABI_NAMESPACE_END;
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
#endif // !TOML_EXCEPTIONS
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
@ -2,34 +2,15 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
#if defined(DOXYGEN) || TOML_PARSER
|
||||
|
||||
#include "table.h"
|
||||
#include "parse_error.h"
|
||||
#include "parse_result.h"
|
||||
#include "utf8_streams.h"
|
||||
#include "header_start.h"
|
||||
|
||||
/// \cond
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result do_parse(utf8_reader_interface &&) TOML_MAY_THROW;
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
/// \endcond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
@ -84,26 +65,16 @@ TOML_NAMESPACE_START
|
||||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::string && source_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file("foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \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.
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
@ -111,9 +82,7 @@ TOML_NAMESPACE_START
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
parse_result parse_file(std::string_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
@ -167,7 +136,110 @@ TOML_NAMESPACE_START
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string && source_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file(u8"foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse_file(std::u8string_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \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 \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
/// \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"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \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 \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse(std::istream & doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file(L"foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse_file(std::wstring_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#if TOML_HAS_CHAR8 && TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
@ -195,9 +267,7 @@ TOML_NAMESPACE_START
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
#endif // TOML_HAS_CHAR8 && TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
@ -214,7 +284,6 @@ TOML_NAMESPACE_START
|
||||
/// 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)
|
||||
@ -224,14 +293,9 @@ TOML_NAMESPACE_START
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
template <typename Char>
|
||||
TOML_NODISCARD
|
||||
inline parse_result parse(std::basic_istream<Char> & doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
|
||||
return impl::do_parse(impl::utf8_reader{ doc, source_path });
|
||||
}
|
||||
TOML_API
|
||||
parse_result parse(std::istream & doc, std::string_view source_path = {}) TOML_MAY_THROW;
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
@ -248,7 +312,6 @@ TOML_NAMESPACE_START
|
||||
/// 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)
|
||||
@ -258,126 +321,9 @@ TOML_NAMESPACE_START
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
template <typename Char>
|
||||
TOML_NODISCARD
|
||||
inline parse_result parse(std::basic_istream<Char> & doc, std::string && source_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \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"] << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \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 \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
template <typename Char>
|
||||
TOML_NODISCARD
|
||||
inline parse_result parse(std::basic_istream<Char> & doc, std::wstring_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return parse(doc, impl::narrow(source_path));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
extern template TOML_API
|
||||
parse_result parse(std::istream&, std::string &&) TOML_MAY_THROW;
|
||||
#endif
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file("foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse_file(std::string_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file(u8"foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse_file(std::u8string_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a file.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// toml::parse_result get_foo_toml()
|
||||
/// {
|
||||
/// return toml::parse_file(L"foo.toml");
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \availability This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns \conditional_return{With exceptions}
|
||||
/// A toml::table.
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result parse_file(std::wstring_view file_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
parse_result parse(std::istream & doc, std::string && source_path) TOML_MAY_THROW;
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
|
||||
@ -407,8 +353,10 @@ TOML_NAMESPACE_START
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result operator"" _toml(const char* str, size_t len) TOML_MAY_THROW;
|
||||
inline parse_result operator"" _toml(const char* str, size_t len) TOML_MAY_THROW
|
||||
{
|
||||
return parse(std::string_view{ str, len });
|
||||
}
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
@ -434,8 +382,10 @@ TOML_NAMESPACE_START
|
||||
/// \conditional_return{Without exceptions}
|
||||
/// A toml::parse_result.
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
parse_result operator"" _toml(const char8_t* str, size_t len) TOML_MAY_THROW;
|
||||
inline parse_result operator"" _toml(const char8_t* str, size_t len) TOML_MAY_THROW
|
||||
{
|
||||
return parse(std::u8string_view{ str, len });
|
||||
}
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
|
||||
@ -445,3 +395,4 @@ TOML_NAMESPACE_START
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_PARSER
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -379,10 +379,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TOML_LARGE_FILES
|
||||
#define TOML_LARGE_FILES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNDEF_MACROS
|
||||
#define TOML_UNDEF_MACROS 1
|
||||
#endif
|
||||
@ -422,6 +418,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TOML_LARGE_FILES
|
||||
#if !TOML_LARGE_FILES
|
||||
#error Support for !TOML_LARGE_FILES (i.e. 'small files') was removed in toml++ 3.0.0.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#====================================================================================================================
|
||||
//# ATTRIBUTES, UTILITY MACROS ETC
|
||||
//#====================================================================================================================
|
||||
@ -663,6 +665,12 @@
|
||||
#define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
#if (!defined(DOXYGEN) && !TOML_HEADER_ONLY) || TOML_INTELLISENSE
|
||||
#define TOML_EXTERN_TEMPLATES 1
|
||||
#else
|
||||
#define TOML_EXTERN_TEMPLATES 0
|
||||
#endif
|
||||
|
||||
//======================================================================================================================
|
||||
// SFINAE
|
||||
//======================================================================================================================
|
||||
@ -914,12 +922,6 @@ TOML_ENABLE_WARNINGS;
|
||||
/// \detail Not defined by default. Meaningless when #TOML_HEADER_ONLY is enabled.
|
||||
|
||||
|
||||
/// \def TOML_LARGE_FILES
|
||||
/// \brief Sets whether line and column indices are 32-bit integers.
|
||||
/// \detail Defaults to `0`.
|
||||
/// \see toml::source_index
|
||||
|
||||
|
||||
#define TOML_OPTIONAL_TYPE
|
||||
/// \def TOML_OPTIONAL_TYPE
|
||||
/// \brief Overrides the `optional<T>` type used by the library.
|
||||
|
@ -2,464 +2,137 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
#include "date_time.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS;
|
||||
#include "forward_declarations.h"
|
||||
#include "std_string.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
// Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?"
|
||||
// A: - I'm supporting C++20's char8_t as well; wrapping streams allows switching string modes transparently.
|
||||
// - I'm using <charconv> to format numerics. Faster and locale-independent.
|
||||
// - I can avoid forcing users to drag in <sstream> and <iomanip>.
|
||||
|
||||
// Q: "there's a bit of reinterpret_casting here, is any of it UB?"
|
||||
// A: - If the source string data is char and the output string is char8_t, then technically yes,
|
||||
// but not in the other direction. I test in both modes on Clang, GCC and MSVC and have yet to
|
||||
// see it actually causing an issue, but in the event it does present a problem it's not going to
|
||||
// be a show-stopper since all it means is I need to do duplicate some code.
|
||||
// - I can (potentially) avoid forcing users to drag in <sstream> and <iomanip>.
|
||||
// - Strings in C++. Honestly.
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline void print_to_stream(std::basic_string_view<Char1> str, std::basic_ostream<Char2> & stream)
|
||||
{
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
stream.write(reinterpret_cast<const Char2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
}
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline void print_to_stream(const std::basic_string<Char1>& str, std::basic_ostream<Char2>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char1) == 1);
|
||||
static_assert(sizeof(Char2) == 1);
|
||||
stream.write(reinterpret_cast<const Char2*>(str.data()), static_cast<std::streamsize>(str.length()));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(char character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_API
|
||||
TOML_ATTR(nonnull)
|
||||
inline void print_to_stream(const char* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
void print_to_stream(std::ostream&, const char*, size_t);
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, std::string_view);
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(char8_t character, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.put(static_cast<Char>(character));
|
||||
}
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const std::string&);
|
||||
|
||||
template <typename Char>
|
||||
TOML_ATTR(nonnull)
|
||||
inline void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, char);
|
||||
|
||||
#endif
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, int8_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, int16_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, int32_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, int64_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, uint8_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, uint16_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, uint32_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, uint64_t, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, float, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, double, value_flags = {});
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, bool);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const toml::date&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const toml::time&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const toml::time_offset&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const toml::date_time&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const source_position&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const source_region&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const array&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const table&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<std::string>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<int64_t>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<double>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<bool>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<date>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<time>&);
|
||||
|
||||
TOML_API
|
||||
void print_to_stream(std::ostream&, const value<date_time>&);
|
||||
|
||||
template <typename T>
|
||||
inline constexpr size_t charconv_buffer_length = 0;
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<double> = 60;
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<float> = 40;
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint64_t> = 20; // strlen("18446744073709551615")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int64_t> = 20; // strlen("-9223372036854775808")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int32_t> = 11; // strlen("-2147483648")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int16_t> = 6; // strlen("-32768")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int8_t> = 4; // strlen("-128")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint32_t> = 10; // strlen("4294967295")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint16_t> = 5; // strlen("65535")
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint8_t> = 3; // strlen("255")
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline void print_integer_to_stream(T val, std::basic_ostream<Char> & stream, value_flags format = {})
|
||||
inline void print_to_stream_with_escapes(std::ostream & stream, const T& str)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
|
||||
if (!val)
|
||||
{
|
||||
print_to_stream('0', stream);
|
||||
return;
|
||||
}
|
||||
|
||||
int base = 10;
|
||||
if (format != value_flags::none && val >= T{})
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case value_flags::format_as_binary: base = 2; break;
|
||||
case value_flags::format_as_octal: base = 8; break;
|
||||
case value_flags::format_as_hexadecimal: base = 16; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[(sizeof(T) * CHAR_BIT)];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val, base);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
if (base == 16)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (buf[i] >= 'a')
|
||||
buf[i] -= 32;
|
||||
}
|
||||
print_to_stream(buf, len, stream);
|
||||
|
||||
#else
|
||||
|
||||
using unsigned_type = std::conditional_t<(sizeof(T) > sizeof(unsigned)), std::make_unsigned_t<T>, unsigned>;
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, std::make_signed_t<unsigned_type>, unsigned_type>;
|
||||
|
||||
if TOML_UNLIKELY(format == value_flags::format_as_binary)
|
||||
{
|
||||
bool found_one = false;
|
||||
const auto v = static_cast<unsigned_type>(val);
|
||||
unsigned_type mask = unsigned_type{ 1 } << (sizeof(unsigned_type) * CHAR_BIT - 1u);
|
||||
for (unsigned i = 0; i < sizeof(unsigned_type) * CHAR_BIT; i++)
|
||||
{
|
||||
if ((v & mask))
|
||||
{
|
||||
print_to_stream('1', stream);
|
||||
found_one = true;
|
||||
}
|
||||
else if (found_one)
|
||||
print_to_stream('0', stream);
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << std::uppercase << std::setbase(base);
|
||||
ss << static_cast<cast_type>(val);
|
||||
const auto str = std::move(ss).str();
|
||||
print_to_stream(str, stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TOML_P2S_OVERLOAD(T) \
|
||||
template <typename Char> \
|
||||
inline void print_to_stream(T val, std::basic_ostream<Char>& stream, value_flags format) \
|
||||
{ \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_integer_to_stream(val, stream, format); \
|
||||
} \
|
||||
static_assert(true)
|
||||
|
||||
TOML_P2S_OVERLOAD(int8_t);
|
||||
TOML_P2S_OVERLOAD(int16_t);
|
||||
TOML_P2S_OVERLOAD(int32_t);
|
||||
TOML_P2S_OVERLOAD(int64_t);
|
||||
TOML_P2S_OVERLOAD(uint8_t);
|
||||
TOML_P2S_OVERLOAD(uint16_t);
|
||||
TOML_P2S_OVERLOAD(uint32_t);
|
||||
TOML_P2S_OVERLOAD(uint64_t);
|
||||
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline void print_floating_point_to_stream(T val, std::basic_ostream<Char> & stream, bool hexfloat = false)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
|
||||
switch (impl::fpclassify(val))
|
||||
{
|
||||
case fp_class::neg_inf: print_to_stream("-inf"sv, stream); break;
|
||||
|
||||
case fp_class::pos_inf: print_to_stream("inf"sv, stream); break;
|
||||
|
||||
case fp_class::nan: print_to_stream("nan"sv, stream); break;
|
||||
|
||||
case fp_class::ok:
|
||||
{
|
||||
static constexpr auto needs_decimal_point = [](auto&& s) noexcept
|
||||
{
|
||||
for (auto c : s)
|
||||
if (c == '.' || c == 'E' || c == 'e')
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
#if TOML_FLOAT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = hexfloat ? std::to_chars(buf, buf + sizeof(buf), val, std::chars_format::hex)
|
||||
: std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto str = std::string_view{ buf, static_cast<size_t>(res.ptr - buf) };
|
||||
print_to_stream(str, stream);
|
||||
if (!hexfloat && needs_decimal_point(str))
|
||||
print_to_stream(".0"sv, stream);
|
||||
|
||||
#else
|
||||
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(std::numeric_limits<T>::digits10 + 1);
|
||||
if (hexfloat)
|
||||
ss << std::hexfloat;
|
||||
ss << val;
|
||||
const auto str = std::move(ss).str();
|
||||
print_to_stream(str, stream);
|
||||
if (!hexfloat && needs_decimal_point(str))
|
||||
print_to_stream(".0"sv, stream);
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
#endif
|
||||
|
||||
#define TOML_P2S_OVERLOAD(Type) \
|
||||
template <typename Char> \
|
||||
inline void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
|
||||
{ \
|
||||
static_assert(sizeof(Char) == 1); \
|
||||
print_floating_point_to_stream(val, stream); \
|
||||
} \
|
||||
static_assert(true)
|
||||
|
||||
TOML_P2S_OVERLOAD(double);
|
||||
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(bool val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val ? "true"sv : "false"sv, stream);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline void print_to_stream(T val, std::basic_ostream<Char> & stream, size_t zero_pad_to_digits)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
for (size_t i = len; i < zero_pad_to_digits; i++)
|
||||
print_to_stream('0', stream);
|
||||
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream);
|
||||
|
||||
#else
|
||||
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
|
||||
ss << std::setfill('0') << std::setw(static_cast<int>(zero_pad_to_digits)) << static_cast<cast_type>(val);
|
||||
const auto str = std::move(ss).str();
|
||||
print_to_stream(str, stream);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::date& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.year, stream, 4_sz);
|
||||
print_to_stream('-', stream);
|
||||
print_to_stream(val.month, stream, 2_sz);
|
||||
print_to_stream('-', stream);
|
||||
print_to_stream(val.day, stream, 2_sz);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::time& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.hour, stream, 2_sz);
|
||||
print_to_stream(':', stream);
|
||||
print_to_stream(val.minute, stream, 2_sz);
|
||||
print_to_stream(':', stream);
|
||||
print_to_stream(val.second, stream, 2_sz);
|
||||
if (val.nanosecond && val.nanosecond <= 999999999u)
|
||||
{
|
||||
print_to_stream('.', stream);
|
||||
auto ns = val.nanosecond;
|
||||
size_t digits = 9_sz;
|
||||
while (ns % 10u == 0u)
|
||||
{
|
||||
ns /= 10u;
|
||||
digits--;
|
||||
}
|
||||
print_to_stream(ns, stream, digits);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(toml::time_offset val, std::basic_ostream<Char> & stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
if (!val.minutes)
|
||||
print_to_stream('Z', stream);
|
||||
else
|
||||
{
|
||||
auto mins = static_cast<int>(val.minutes);
|
||||
if (mins < 0)
|
||||
{
|
||||
print_to_stream('-', stream);
|
||||
mins = -mins;
|
||||
}
|
||||
else
|
||||
print_to_stream('+', stream);
|
||||
const auto hours = mins / 60;
|
||||
if (hours)
|
||||
{
|
||||
print_to_stream(static_cast<unsigned int>(hours), stream, 2_sz);
|
||||
mins -= hours * 60;
|
||||
}
|
||||
else
|
||||
print_to_stream("00"sv, stream);
|
||||
print_to_stream(':', stream);
|
||||
print_to_stream(static_cast<unsigned int>(mins), stream, 2_sz);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void print_to_stream(const toml::date_time& val, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
print_to_stream(val.date, stream);
|
||||
print_to_stream('T', stream);
|
||||
print_to_stream(val.time, stream);
|
||||
if (val.offset)
|
||||
print_to_stream(*val.offset, stream);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
void print_to_stream_with_escapes(T && str, std::basic_ostream<Char> & stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
for (auto c : str)
|
||||
{
|
||||
if TOML_UNLIKELY(c >= '\x00' && c <= '\x1F')
|
||||
print_to_stream(low_character_escape_table[c], stream);
|
||||
print_to_stream(stream, low_character_escape_table[c]);
|
||||
else if TOML_UNLIKELY(c == '\x7F')
|
||||
print_to_stream("\\u007F"sv, stream);
|
||||
print_to_stream(stream, "\\u007F"sv);
|
||||
else if TOML_UNLIKELY(c == '"')
|
||||
print_to_stream("\\\""sv, stream);
|
||||
print_to_stream(stream, "\\\""sv);
|
||||
else if TOML_UNLIKELY(c == '\\')
|
||||
print_to_stream("\\\\"sv, stream);
|
||||
print_to_stream(stream, "\\\\"sv);
|
||||
else
|
||||
print_to_stream(c, stream);
|
||||
print_to_stream(stream, c);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void print_to_stream_bookended(std::ostream & stream, const T& val, const U& bookend)
|
||||
{
|
||||
print_to_stream(stream, bookend);
|
||||
print_to_stream(stream, val);
|
||||
print_to_stream(stream, bookend);
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \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().begin()
|
||||
/// << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// The value for 'bar' was found on line 1, column 7
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The source_position.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const source_position& rhs)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
impl::print_to_stream("line "sv, lhs);
|
||||
impl::print_to_stream(rhs.line, lhs);
|
||||
impl::print_to_stream(", column "sv, lhs);
|
||||
impl::print_to_stream(rhs.column, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \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()
|
||||
/// << "\n";
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// The value for 'bar' was found on line 1, column 7 of 'config.toml'
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param lhs The stream.
|
||||
/// \param rhs The source_position.
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const source_region& rhs)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1, "The stream's underlying character type must be 1 byte in size.");
|
||||
lhs << rhs.begin;
|
||||
if (rhs.path)
|
||||
{
|
||||
impl::print_to_stream(" of '"sv, lhs);
|
||||
impl::print_to_stream(*rhs.path, lhs);
|
||||
impl::print_to_stream('\'', lhs);
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN) && !TOML_HEADER_ONLY
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const source_position&);
|
||||
extern template TOML_API
|
||||
std::ostream& operator<<(std::ostream&, const source_region&);
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
|
474
include/toml++/impl/print_to_stream_impl.h
Normal file
474
include/toml++/impl/print_to_stream_impl.h
Normal file
@ -0,0 +1,474 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "print_to_stream.h"
|
||||
#include "source_region.h"
|
||||
#include "date_time.h"
|
||||
#include "default_formatter.h"
|
||||
#include "value.h"
|
||||
#include "array.h"
|
||||
#include "table.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <ostream>
|
||||
#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
|
||||
#include <charconv>
|
||||
#endif
|
||||
#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV
|
||||
#include <sstream>
|
||||
#endif
|
||||
#if !TOML_INT_CHARCONV
|
||||
#include <iomanip>
|
||||
#endif
|
||||
TOML_ENABLE_WARNINGS;
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_ANON_NAMESPACE_START
|
||||
{
|
||||
#if !TOML_HEADER_ONLY
|
||||
using namespace toml;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline constexpr size_t charconv_buffer_length = 0;
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int8_t> = 4; // strlen("-128")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int16_t> = 6; // strlen("-32768")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int32_t> = 11; // strlen("-2147483648")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<int64_t> = 20; // strlen("-9223372036854775808")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint8_t> = 3; // strlen("255")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint16_t> = 5; // strlen("65535")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint32_t> = 10; // strlen("4294967295")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<uint64_t> = 20; // strlen("18446744073709551615")
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<float> = 40;
|
||||
|
||||
template <>
|
||||
inline constexpr size_t charconv_buffer_length<double> = 60;
|
||||
|
||||
template <typename T>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
void print_integer_to_stream(std::ostream & stream, T val, value_flags format = {})
|
||||
{
|
||||
using namespace toml;
|
||||
|
||||
if (!val)
|
||||
{
|
||||
stream.put('0');
|
||||
return;
|
||||
}
|
||||
|
||||
int base = 10;
|
||||
if (format != value_flags::none && val >= T{})
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case value_flags::format_as_binary: base = 2; break;
|
||||
case value_flags::format_as_octal: base = 8; break;
|
||||
case value_flags::format_as_hexadecimal: base = 16; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[(sizeof(T) * CHAR_BIT)];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val, base);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
if (base == 16)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (buf[i] >= 'a')
|
||||
buf[i] -= 32;
|
||||
}
|
||||
impl::print_to_stream(stream, buf, len);
|
||||
|
||||
#else
|
||||
|
||||
using unsigned_type = std::conditional_t<(sizeof(T) > sizeof(unsigned)), std::make_unsigned_t<T>, unsigned>;
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, std::make_signed_t<unsigned_type>, unsigned_type>;
|
||||
|
||||
if TOML_UNLIKELY(format == value_flags::format_as_binary)
|
||||
{
|
||||
bool found_one = false;
|
||||
const auto v = static_cast<unsigned_type>(val);
|
||||
unsigned_type mask = unsigned_type{ 1 } << (sizeof(unsigned_type) * CHAR_BIT - 1u);
|
||||
for (unsigned i = 0; i < sizeof(unsigned_type) * CHAR_BIT; i++)
|
||||
{
|
||||
if ((v & mask))
|
||||
{
|
||||
stream.put('1');
|
||||
found_one = true;
|
||||
}
|
||||
else if (found_one)
|
||||
stream.put('0');
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << std::uppercase << std::setbase(base);
|
||||
ss << static_cast<cast_type>(val);
|
||||
const auto str = std::move(ss).str();
|
||||
impl::print_to_stream(str, stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
void print_floating_point_to_stream(std::ostream & stream, T val, value_flags format = {})
|
||||
{
|
||||
using namespace toml;
|
||||
|
||||
switch (impl::fpclassify(val))
|
||||
{
|
||||
case impl::fp_class::neg_inf: impl::print_to_stream(stream, "-inf"sv); break;
|
||||
|
||||
case impl::fp_class::pos_inf: impl::print_to_stream(stream, "inf"sv); break;
|
||||
|
||||
case impl::fp_class::nan: impl::print_to_stream(stream, "nan"sv); break;
|
||||
|
||||
case impl::fp_class::ok:
|
||||
{
|
||||
static constexpr auto needs_decimal_point = [](auto&& s) noexcept
|
||||
{
|
||||
for (auto c : s)
|
||||
if (c == '.' || c == 'E' || c == 'e')
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
#if TOML_FLOAT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = !!(format & value_flags::format_as_hexadecimal)
|
||||
? std::to_chars(buf, buf + sizeof(buf), val, std::chars_format::hex)
|
||||
: std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto str = std::string_view{ buf, static_cast<size_t>(res.ptr - buf) };
|
||||
impl::print_to_stream(stream, str);
|
||||
if (!(format & value_flags::format_as_hexadecimal) && needs_decimal_point(str))
|
||||
toml::impl::print_to_stream(stream, ".0"sv);
|
||||
|
||||
#else
|
||||
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(std::numeric_limits<T>::digits10 + 1);
|
||||
if (!!(format & value_flags::format_as_hexadecimal))
|
||||
ss << std::hexfloat;
|
||||
ss << val;
|
||||
const auto str = std::move(ss).str();
|
||||
impl::print_to_stream(stream, str);
|
||||
if (!(format & value_flags::format_as_hexadecimal) && needs_decimal_point(str))
|
||||
impl::print_to_stream(stream, ".0"sv);
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default: TOML_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
void print_integer_leftpad_zeros(std::ostream & stream, T val, size_t min_digits)
|
||||
{
|
||||
using namespace toml;
|
||||
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
const auto len = static_cast<size_t>(res.ptr - buf);
|
||||
for (size_t i = len; i < min_digits; i++)
|
||||
stream.put('0');
|
||||
impl::print_to_stream(stream, buf, static_cast<size_t>(res.ptr - buf));
|
||||
|
||||
#else
|
||||
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
using cast_type = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
|
||||
ss << std::setfill('0') << std::setw(static_cast<int>(min_digits)) << static_cast<cast_type>(val);
|
||||
const auto str = std::move(ss).str();
|
||||
impl::print_to_stream(stream, str);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
TOML_ANON_NAMESPACE_END;
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(nonnull)
|
||||
void print_to_stream(std::ostream & stream, const char* val, size_t len)
|
||||
{
|
||||
stream.write(val, static_cast<std::streamsize>(len));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, std::string_view val)
|
||||
{
|
||||
stream.write(val.data(), static_cast<std::streamsize>(val.length()));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const std::string& val)
|
||||
{
|
||||
stream.write(val.data(), static_cast<std::streamsize>(val.length()));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, char val)
|
||||
{
|
||||
stream.put(val);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, int8_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, int16_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, int32_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, int64_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, uint8_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, uint16_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, uint32_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, uint64_t val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_integer_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, float val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_floating_point_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, double val, value_flags format)
|
||||
{
|
||||
TOML_ANON_NAMESPACE::print_floating_point_to_stream(stream, val, format);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, bool val)
|
||||
{
|
||||
print_to_stream(stream, val ? "true"sv : "false"sv);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const toml::date& val)
|
||||
{
|
||||
print_integer_leftpad_zeros(stream, val.year, 4_sz);
|
||||
stream.put('-');
|
||||
print_integer_leftpad_zeros(stream, val.month, 2_sz);
|
||||
stream.put('-');
|
||||
print_integer_leftpad_zeros(stream, val.day, 2_sz);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const toml::time& val)
|
||||
{
|
||||
print_integer_leftpad_zeros(stream, val.hour, 2_sz);
|
||||
stream.put(':');
|
||||
print_integer_leftpad_zeros(stream, val.minute, 2_sz);
|
||||
stream.put(':');
|
||||
print_integer_leftpad_zeros(stream, val.second, 2_sz);
|
||||
if (val.nanosecond && val.nanosecond <= 999999999u)
|
||||
{
|
||||
stream.put('.');
|
||||
auto ns = val.nanosecond;
|
||||
size_t digits = 9_sz;
|
||||
while (ns % 10u == 0u)
|
||||
{
|
||||
ns /= 10u;
|
||||
digits--;
|
||||
}
|
||||
print_integer_leftpad_zeros(stream, ns, digits);
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const toml::time_offset& val)
|
||||
{
|
||||
if (!val.minutes)
|
||||
{
|
||||
stream.put('Z');
|
||||
return;
|
||||
}
|
||||
|
||||
auto mins = static_cast<int>(val.minutes);
|
||||
if (mins < 0)
|
||||
{
|
||||
stream.put('-');
|
||||
mins = -mins;
|
||||
}
|
||||
else
|
||||
stream.put('+');
|
||||
const auto hours = mins / 60;
|
||||
if (hours)
|
||||
{
|
||||
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(hours), 2_sz);
|
||||
mins -= hours * 60;
|
||||
}
|
||||
else
|
||||
print_to_stream(stream, "00"sv);
|
||||
stream.put(':');
|
||||
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(mins), 2_sz);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const toml::date_time& val)
|
||||
{
|
||||
print_to_stream(stream, val.date);
|
||||
stream.put('T');
|
||||
print_to_stream(stream, val.time);
|
||||
if (val.offset)
|
||||
print_to_stream(stream, *val.offset);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const source_position& val)
|
||||
{
|
||||
print_to_stream(stream, "line "sv);
|
||||
print_to_stream(stream, val.line);
|
||||
print_to_stream(stream, ", column "sv);
|
||||
print_to_stream(stream, val.column);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const source_region& val)
|
||||
{
|
||||
print_to_stream(stream, val.begin);
|
||||
if (val.path)
|
||||
{
|
||||
print_to_stream(stream, " of '"sv);
|
||||
print_to_stream(stream, *val.path);
|
||||
stream.put('\'');
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const array& arr)
|
||||
{
|
||||
stream << default_formatter{ arr };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const table& tbl)
|
||||
{
|
||||
stream << default_formatter{ tbl };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<std::string>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<int64_t>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<double>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<bool>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<date>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<time>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_to_stream(std::ostream & stream, const value<date_time>& val)
|
||||
{
|
||||
stream << default_formatter{ val };
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
199
include/toml++/impl/source_region.h
Normal file
199
include/toml++/impl/source_region.h
Normal file
@ -0,0 +1,199 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "forward_declarations.h"
|
||||
#include "std_optional.h"
|
||||
#include "std_string.h"
|
||||
#include "print_to_stream.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief The integer type used to tally line numbers and columns.
|
||||
using source_index = uint32_t;
|
||||
|
||||
/// \brief A pointer to a shared string resource containing a source path.
|
||||
using source_path_ptr = std::shared_ptr<const std::string>;
|
||||
|
||||
/// \brief A source document line-and-column pair.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto table = toml::parse_file("config.toml"sv);
|
||||
/// std::cout << "The node 'description' was defined at "sv
|
||||
/// << table.get("description")->source().begin()
|
||||
/// << "\n";
|
||||
///
|
||||
/// \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).
|
||||
/// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
|
||||
/// between parser complexity and correctness.
|
||||
struct TOML_TRIVIAL_ABI source_position
|
||||
{
|
||||
/// \brief The line number.
|
||||
/// \remarks Valid line numbers start at 1.
|
||||
source_index line;
|
||||
|
||||
/// \brief The column number.
|
||||
/// \remarks Valid column numbers start at 1.
|
||||
source_index column;
|
||||
|
||||
/// \brief Returns true if both line and column numbers are non-zero.
|
||||
TOML_NODISCARD
|
||||
explicit constexpr operator bool() const noexcept
|
||||
{
|
||||
return line > source_index{} && column > source_index{};
|
||||
}
|
||||
|
||||
/// \brief Returns true if two source_positions represent the same line and column.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator==(const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
return lhs.line == rhs.line && lhs.column == rhs.column;
|
||||
}
|
||||
|
||||
/// \brief Returns true if two source_positions do not represent the same line and column.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator!=(const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
return lhs.line != rhs.line || lhs.column != rhs.column;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the LHS position is before the RHS position.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<(const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
return lhs.line < rhs.line || (lhs.line == rhs.line && lhs.column < rhs.column);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the LHS position is before the RHS position or equal to it.
|
||||
TOML_NODISCARD
|
||||
friend constexpr bool operator<=(const source_position& lhs, const source_position& rhs) noexcept
|
||||
{
|
||||
return lhs.line < rhs.line || (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().begin()
|
||||
/// << "\n";
|
||||
///
|
||||
/// \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.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const source_position& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A source document region.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse_file("config.toml"sv);
|
||||
/// if (auto server = tbl.get("server"))
|
||||
/// {
|
||||
/// std::cout << "begin: "sv << server->source().begin << "\n";
|
||||
/// std::cout << "end: "sv << server->source().end << "\n";
|
||||
/// std::cout << "path: "sv << *server->source().path << "\n";
|
||||
/// }
|
||||
///
|
||||
/// \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).
|
||||
/// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
|
||||
/// between parser complexity and correctness.
|
||||
struct source_region
|
||||
{
|
||||
/// \brief The beginning of the region (inclusive).
|
||||
source_position begin;
|
||||
|
||||
/// \brief The end of the region (exclusive).
|
||||
source_position end;
|
||||
|
||||
/// \brief The path to the corresponding source document.
|
||||
///
|
||||
/// \remarks This will be `nullptr` if no path was provided to toml::parse().
|
||||
source_path_ptr path;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief The path to the corresponding source document as a wide-string.
|
||||
///
|
||||
/// \availability This function is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
///
|
||||
/// \remarks This will return an empty optional if no path was provided to toml::parse().
|
||||
TOML_NODISCARD
|
||||
optional<std::wstring> wide_path() const noexcept
|
||||
{
|
||||
if (!path || path->empty())
|
||||
return {};
|
||||
return { impl::widen(*path) };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// \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()
|
||||
/// << "\n";
|
||||
///
|
||||
/// \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.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const source_region& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
12
include/toml++/impl/std_except.h
Normal file
12
include/toml++/impl/std_except.h
Normal file
@ -0,0 +1,12 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#if TOML_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
TOML_ENABLE_WARNINGS;
|
11
include/toml++/impl/std_map.h
Normal file
11
include/toml++/impl/std_map.h
Normal file
@ -0,0 +1,11 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
TOML_ENABLE_WARNINGS;
|
18
include/toml++/impl/std_new.h
Normal file
18
include/toml++/impl/std_new.h
Normal file
@ -0,0 +1,18 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <new>
|
||||
TOML_ENABLE_WARNINGS;
|
||||
|
||||
#if TOML_CLANG >= 8 || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914
|
||||
#define TOML_LAUNDER(x) __builtin_launder(x)
|
||||
#elif defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
|
||||
#define TOML_LAUNDER(x) std::launder(x)
|
||||
#else
|
||||
#define TOML_LAUNDER(x) x
|
||||
#endif
|
32
include/toml++/impl/std_optional.h
Normal file
32
include/toml++/impl/std_optional.h
Normal file
@ -0,0 +1,32 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#if !TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#include <optional>
|
||||
#endif
|
||||
TOML_ENABLE_WARNINGS;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
#if TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
template <typename T>
|
||||
using optional = TOML_OPTIONAL_TYPE<T>;
|
||||
|
||||
#else
|
||||
|
||||
/// \brief The 'optional' type used throughout the library.
|
||||
///
|
||||
/// \remarks By default this will be an alias for std::optional, but you can change the optional type
|
||||
/// used by the library by defining #TOML_OPTIONAL_TYPE.
|
||||
template <typename T>
|
||||
using optional = std::optional<T>;
|
||||
|
||||
#endif
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
58
include/toml++/impl/std_string.h
Normal file
58
include/toml++/impl/std_string.h
Normal file
@ -0,0 +1,58 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
TOML_ENABLE_WARNINGS;
|
||||
|
||||
#if defined(DOXYGEN) \
|
||||
|| (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \
|
||||
&& __cpp_lib_char8_t >= 201907)
|
||||
#define TOML_HAS_CHAR8 1
|
||||
#else
|
||||
#define TOML_HAS_CHAR8 0
|
||||
#endif
|
||||
|
||||
/// \cond
|
||||
|
||||
namespace toml // non-abi namespace; this is not an error
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
// legacy typedefs
|
||||
using string_char = char;
|
||||
using string = std::string;
|
||||
using string_view = std::string_view;
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
std::string narrow(std::wstring_view) noexcept;
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
std::wstring widen(std::string_view) noexcept;
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
std::wstring widen(std::u8string_view) noexcept;
|
||||
|
||||
#endif
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \endcond
|
102
include/toml++/impl/std_string_impl.h
Normal file
102
include/toml++/impl/std_string_impl.h
Normal file
@ -0,0 +1,102 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#include "std_string.h"
|
||||
#include "header_start.h"
|
||||
|
||||
#ifndef _WINDOWS_
|
||||
#if TOML_INCLUDE_WINDOWS_H
|
||||
#include <Windows.h>
|
||||
#else
|
||||
|
||||
extern "C" __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int CodePage,
|
||||
unsigned long dwFlags,
|
||||
const wchar_t* lpWideCharStr,
|
||||
int cchWideChar,
|
||||
char* lpMultiByteStr,
|
||||
int cbMultiByte,
|
||||
const char* lpDefaultChar,
|
||||
int* lpUsedDefaultChar);
|
||||
|
||||
extern "C" __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage,
|
||||
unsigned long dwFlags,
|
||||
const char* lpMultiByteStr,
|
||||
int cbMultiByte,
|
||||
wchar_t* lpWideCharStr,
|
||||
int cchWideChar);
|
||||
|
||||
#endif // TOML_INCLUDE_WINDOWS_H
|
||||
#endif // _WINDOWS_
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::string narrow(std::wstring_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::string s;
|
||||
const auto len =
|
||||
::WideCharToMultiByte(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
::WideCharToMultiByte(65001,
|
||||
0,
|
||||
str.data(),
|
||||
static_cast<int>(str.length()),
|
||||
s.data(),
|
||||
len,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::wstring s;
|
||||
const auto len = ::MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
::MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::u8string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
return widen(std::string_view{ reinterpret_cast<const char*>(str.data()), str.length() });
|
||||
}
|
||||
|
||||
#endif // TOML_HAS_CHAR8
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
/// \endcond
|
11
include/toml++/impl/std_vector.h
Normal file
11
include/toml++/impl/std_vector.h
Normal file
@ -0,0 +1,11 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "preprocessor.h"
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
TOML_ENABLE_WARNINGS;
|
@ -2,9 +2,12 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "array.h"
|
||||
#include "make_node.h"
|
||||
#include "std_map.h"
|
||||
#include "node_view.h"
|
||||
#include "header_start.h"
|
||||
|
||||
/// \cond
|
||||
@ -28,8 +31,8 @@ TOML_IMPL_NAMESPACE_START
|
||||
friend class TOML_NAMESPACE::table;
|
||||
|
||||
using proxy_type = table_proxy_pair<IsConst>;
|
||||
using raw_mutable_iterator = string_map<std::unique_ptr<node>>::iterator;
|
||||
using raw_const_iterator = string_map<std::unique_ptr<node>>::const_iterator;
|
||||
using raw_mutable_iterator = std::map<std::string, std::unique_ptr<node>, std::less<>>::iterator;
|
||||
using raw_const_iterator = std::map<std::string, std::unique_ptr<node>, std::less<>>::const_iterator;
|
||||
using raw_iterator = std::conditional_t<IsConst, raw_const_iterator, raw_mutable_iterator>;
|
||||
|
||||
mutable raw_iterator raw_;
|
||||
@ -217,16 +220,18 @@ TOML_NAMESPACE_START
|
||||
/// 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_).
|
||||
class TOML_API table final : public node
|
||||
class table final : public node
|
||||
{
|
||||
private:
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
|
||||
/// \cond
|
||||
|
||||
impl::string_map<std::unique_ptr<node>> map;
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
|
||||
std::map<std::string, std::unique_ptr<node>, std::less<>> map_;
|
||||
bool inline_ = false;
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
table(impl::table_init_pair*, size_t) noexcept;
|
||||
|
||||
template <typename Map, typename Key>
|
||||
@ -275,34 +280,48 @@ TOML_NAMESPACE_START
|
||||
public:
|
||||
/// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
|
||||
using iterator = table_iterator;
|
||||
|
||||
/// \brief A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
|
||||
using const_iterator = const_table_iterator;
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
table() noexcept
|
||||
{
|
||||
TOML_TABLE_CREATED;
|
||||
}
|
||||
|
||||
~table() noexcept
|
||||
{
|
||||
TOML_TABLE_DESTROYED;
|
||||
}
|
||||
#else
|
||||
|
||||
/// \brief Default constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
table() noexcept;
|
||||
table() noexcept = default;
|
||||
|
||||
#endif
|
||||
|
||||
/// \brief Copy constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
table(const table&) noexcept;
|
||||
|
||||
/// \brief Move constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
table(table&& other) noexcept;
|
||||
|
||||
/// \brief Copy-assignment operator.
|
||||
TOML_API
|
||||
table& operator=(const table&) noexcept;
|
||||
|
||||
/// \brief Move-assignment operator.
|
||||
TOML_API
|
||||
table& operator=(table&& rhs) noexcept;
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
~table() noexcept override
|
||||
{
|
||||
TOML_TABLE_DESTROYED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Constructs a table with one or more initial key-value pairs.
|
||||
///
|
||||
/// \detail \cpp
|
||||
@ -346,48 +365,38 @@ TOML_NAMESPACE_START
|
||||
/// @{
|
||||
|
||||
TOML_NODISCARD
|
||||
node_type type() const noexcept override
|
||||
node_type type() const noexcept final
|
||||
{
|
||||
return node_type::table;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_table() const noexcept override
|
||||
bool is_table() const noexcept final
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_array() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool is_homogeneous(node_type ntype) const noexcept final;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_value() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype) const noexcept override;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept override;
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept override;
|
||||
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
|
||||
|
||||
template <typename ElemType = void>
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous() const noexcept
|
||||
{
|
||||
using type = impl::unwrap_node<ElemType>;
|
||||
|
||||
static_assert(
|
||||
std::is_void_v<
|
||||
type> || ((impl::is_native<type> || impl::is_one_of<type, table, array>)&&!impl::is_cvref<type>),
|
||||
"The template type argument of table::is_homogeneous() must be void or one "
|
||||
"of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
|
||||
|
||||
return is_homogeneous(impl::node_type_of<type>);
|
||||
}
|
||||
|
||||
@ -397,13 +406,13 @@ TOML_NAMESPACE_START
|
||||
/// @{
|
||||
|
||||
TOML_NODISCARD
|
||||
table* as_table() noexcept override
|
||||
table* as_table() noexcept final
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const table* as_table() const noexcept override
|
||||
const table* as_table() const noexcept final
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@ -484,7 +493,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \see toml::node_view
|
||||
TOML_NODISCARD
|
||||
node_view<node> operator[](std::string_view key) noexcept;
|
||||
node_view<node> operator[](std::string_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair (const overload).
|
||||
///
|
||||
@ -498,7 +510,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \see toml::node_view
|
||||
TOML_NODISCARD
|
||||
node_view<const node> operator[](std::string_view key) const noexcept;
|
||||
node_view<const node> operator[](std::string_view key) const noexcept
|
||||
{
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
@ -516,7 +531,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \see toml::node_view
|
||||
TOML_NODISCARD
|
||||
node_view<node> operator[](std::wstring_view key) noexcept;
|
||||
node_view<node> operator[](std::wstring_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair (const overload).
|
||||
///
|
||||
@ -532,7 +550,10 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \see toml::node_view
|
||||
TOML_NODISCARD
|
||||
node_view<const node> operator[](std::wstring_view key) const noexcept;
|
||||
node_view<const node> operator[](std::wstring_view key) const noexcept
|
||||
{
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
@ -545,62 +566,62 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
iterator begin() noexcept
|
||||
{
|
||||
return { map.begin() };
|
||||
return { map_.begin() };
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
TOML_NODISCARD
|
||||
const_iterator begin() const noexcept
|
||||
{
|
||||
return { map.cbegin() };
|
||||
return { map_.cbegin() };
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
TOML_NODISCARD
|
||||
const_iterator cbegin() const noexcept
|
||||
{
|
||||
return { map.cbegin() };
|
||||
return { map_.cbegin() };
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
TOML_NODISCARD
|
||||
iterator end() noexcept
|
||||
{
|
||||
return { map.end() };
|
||||
return { map_.end() };
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
TOML_NODISCARD
|
||||
const_iterator end() const noexcept
|
||||
{
|
||||
return { map.cend() };
|
||||
return { map_.cend() };
|
||||
}
|
||||
|
||||
/// \brief Returns an iterator to one-past-the-last key-value pair.
|
||||
TOML_NODISCARD
|
||||
const_iterator cend() const noexcept
|
||||
{
|
||||
return { map.cend() };
|
||||
return { map_.cend() };
|
||||
}
|
||||
|
||||
/// \brief Returns true if the table is empty.
|
||||
TOML_NODISCARD
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return map.empty();
|
||||
return map_.empty();
|
||||
}
|
||||
|
||||
/// \brief Returns the number of key-value pairs in the table.
|
||||
TOML_NODISCARD
|
||||
size_t size() const noexcept
|
||||
{
|
||||
return map.size();
|
||||
return map_.size();
|
||||
}
|
||||
|
||||
/// \brief Removes all key-value pairs from the table.
|
||||
void clear() noexcept
|
||||
{
|
||||
map.clear();
|
||||
map_.clear();
|
||||
}
|
||||
|
||||
/// \brief Inserts a new value at a specific key if one did not already exist.
|
||||
@ -679,12 +700,12 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ipos = map.lower_bound(key);
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
auto ipos = map_.lower_bound(key);
|
||||
if (ipos == map_.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { iterator{ ipos }, false };
|
||||
@ -820,12 +841,12 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ipos = map.lower_bound(key);
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
auto ipos = map_.lower_bound(key);
|
||||
if (ipos == map_.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
else
|
||||
@ -896,12 +917,12 @@ TOML_NAMESPACE_START
|
||||
"The emplacement type argument of table::emplace() must be one "
|
||||
"of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
|
||||
|
||||
auto ipos = map.lower_bound(key);
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
auto ipos = map_.lower_bound(key);
|
||||
if (ipos == map_.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
new impl::wrap_node<type>{ std::forward<ValueArgs>(args)... });
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
new impl::wrap_node<type>{ std::forward<ValueArgs>(args)... });
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { iterator{ ipos }, false };
|
||||
@ -933,7 +954,7 @@ TOML_NAMESPACE_START
|
||||
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
|
||||
iterator erase(iterator pos) noexcept
|
||||
{
|
||||
return { map.erase(pos.raw_) };
|
||||
return { map_.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified key-value pair from the table (const iterator overload).
|
||||
@ -961,7 +982,7 @@ TOML_NAMESPACE_START
|
||||
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
|
||||
iterator erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { map.erase(pos.raw_) };
|
||||
return { map_.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the key-value pairs in the range [first, last) from the table.
|
||||
@ -991,7 +1012,7 @@ TOML_NAMESPACE_START
|
||||
/// \returns Iterator to the first key-value pair immediately following the last removed key-value pair.
|
||||
iterator erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { map.erase(first.raw_, last.raw_) };
|
||||
return { map_.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
/// \brief Removes the value with the given key from the table.
|
||||
@ -1022,9 +1043,9 @@ TOML_NAMESPACE_START
|
||||
/// \returns True if any values with matching keys were found and erased.
|
||||
bool erase(std::string_view key) noexcept
|
||||
{
|
||||
if (auto it = map.find(key); it != map.end())
|
||||
if (auto it = map_.find(key); it != map_.end())
|
||||
{
|
||||
map.erase(it);
|
||||
map_.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1054,7 +1075,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
iterator find(std::string_view key) noexcept
|
||||
{
|
||||
return { map.find(key) };
|
||||
return { map_.find(key) };
|
||||
}
|
||||
|
||||
/// \brief Gets an iterator to the node at a specific key (const overload)
|
||||
@ -1065,14 +1086,14 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
const_iterator find(std::string_view key) const noexcept
|
||||
{
|
||||
return { map.find(key) };
|
||||
return { map_.find(key) };
|
||||
}
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
TOML_NODISCARD
|
||||
bool contains(std::string_view key) const noexcept
|
||||
{
|
||||
return do_contains(map, key);
|
||||
return do_contains(map_, key);
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -1147,7 +1168,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
node* get(std::string_view key) noexcept
|
||||
{
|
||||
return do_get(map, key);
|
||||
return do_get(map_, key);
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific key (const overload).
|
||||
@ -1158,7 +1179,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
const node* get(std::string_view key) const noexcept
|
||||
{
|
||||
return do_get(map, key);
|
||||
return do_get(map_, key);
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -1215,7 +1236,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
impl::wrap_node<ValueType>* get_as(std::string_view key) noexcept
|
||||
{
|
||||
return do_get_as<ValueType>(map, key);
|
||||
return do_get_as<ValueType>(map_, key);
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type (const overload).
|
||||
@ -1228,7 +1249,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
const impl::wrap_node<ValueType>* get_as(std::string_view key) const noexcept
|
||||
{
|
||||
return do_get_as<ValueType>(map, key);
|
||||
return do_get_as<ValueType>(map_, key);
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -1267,6 +1288,16 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
/// \cond
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
static bool equal(const table&, const table&) noexcept;
|
||||
|
||||
/// \endcond
|
||||
|
||||
public:
|
||||
/// \name Equality
|
||||
/// @{
|
||||
|
||||
@ -1276,7 +1307,11 @@ TOML_NAMESPACE_START
|
||||
/// \param rhs The RHS table.
|
||||
///
|
||||
/// \returns True if the tables contained the same keys and map.
|
||||
friend bool operator==(const table& lhs, const table& rhs) noexcept;
|
||||
TOML_NODISCARD
|
||||
friend bool operator==(const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
return equal(lhs, rhs);
|
||||
}
|
||||
|
||||
/// \brief Inequality operator.
|
||||
///
|
||||
@ -1284,52 +1319,54 @@ TOML_NAMESPACE_START
|
||||
/// \param rhs The RHS table.
|
||||
///
|
||||
/// \returns True if the tables did not contain the same keys and map.
|
||||
friend bool operator!=(const table& lhs, const table& rhs) noexcept;
|
||||
|
||||
/// \brief Prints the table out to a stream as formatted TOML.
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>&, const table&);
|
||||
// implemented in toml_default_formatter.h
|
||||
TOML_NODISCARD
|
||||
friend bool operator!=(const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
return !equal(lhs, rhs);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Prints the table out to a stream as formatted TOML.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const table& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
//# template <typename T>
|
||||
//# inline std::vector<T> node::select_exact() const noexcept
|
||||
//# {
|
||||
//# using namespace impl;
|
||||
//#
|
||||
//# static_assert(
|
||||
//# !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
//# "Retrieving values as wide-character strings with node::select_exact() is only "
|
||||
//# "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
//# );
|
||||
//#
|
||||
//# static_assert(
|
||||
//# (is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
//# TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::select_exact()")
|
||||
//# );
|
||||
//# }
|
||||
|
||||
// template <typename T>
|
||||
// inline std::vector<T> node::select_exact() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select_exact() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::select_exact()")
|
||||
// );
|
||||
//}
|
||||
|
||||
// template <typename T>
|
||||
// inline std::vector<T> node::select() const noexcept
|
||||
//{
|
||||
// using namespace impl;
|
||||
|
||||
// static_assert(
|
||||
// !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
// "Retrieving values as wide-character strings with node::select() is only "
|
||||
// "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
// );
|
||||
// static_assert(
|
||||
// (is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
// TOML_SA_VALUE_FUNC_MESSAGE("return type of node::select()")
|
||||
// );
|
||||
//}
|
||||
|
||||
#endif // !DOXYGEN
|
||||
//# template <typename T>
|
||||
//# inline std::vector<T> node::select() const noexcept
|
||||
//# {
|
||||
//# using namespace impl;
|
||||
//#
|
||||
//# static_assert(
|
||||
//# !is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
//# "Retrieving values as wide-character strings with node::select() is only "
|
||||
//# "supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
//# );
|
||||
//# static_assert(
|
||||
//# (is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) && !is_cvref<T>,
|
||||
//# TOML_SA_VALUE_FUNC_MESSAGE("return type of node::select()")
|
||||
//# );
|
||||
//# }
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
@ -2,37 +2,62 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "table.h"
|
||||
#include "node_view.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
TOML_ANON_NAMESPACE_START
|
||||
{
|
||||
#if !TOML_HEADER_ONLY
|
||||
using namespace toml;
|
||||
#endif
|
||||
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool table_is_homogeneous(T & map, node_type ntype, U & first_nonmatch) noexcept
|
||||
{
|
||||
using namespace toml;
|
||||
|
||||
if (map.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
{
|
||||
first_nonmatch = v.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
TOML_ANON_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table() noexcept
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
TOML_TABLE_CREATED;
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(const table& other) noexcept //
|
||||
: node(other),
|
||||
inline_{ other.inline_ }
|
||||
{
|
||||
for (auto&& [k, v] : other)
|
||||
map.emplace_hint(map.end(), k, impl::make_node(v));
|
||||
map_.emplace_hint(map_.end(), k, impl::make_node(v));
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
TOML_TABLE_CREATED;
|
||||
@ -42,7 +67,7 @@ TOML_NAMESPACE_START
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(table && other) noexcept //
|
||||
: node(std::move(other)),
|
||||
map{ std::move(other.map) },
|
||||
map_{ std::move(other.map_) },
|
||||
inline_{ other.inline_ }
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
@ -56,9 +81,9 @@ TOML_NAMESPACE_START
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(rhs);
|
||||
map.clear();
|
||||
map_.clear();
|
||||
for (auto&& [k, v] : rhs)
|
||||
map.emplace_hint(map.end(), k, impl::make_node(v));
|
||||
map_.emplace_hint(map_.end(), k, impl::make_node(v));
|
||||
inline_ = rhs.inline_;
|
||||
}
|
||||
return *this;
|
||||
@ -70,7 +95,7 @@ TOML_NAMESPACE_START
|
||||
if (&rhs != this)
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
map = std::move(rhs.map);
|
||||
map_ = std::move(rhs.map_);
|
||||
inline_ = rhs.inline_;
|
||||
}
|
||||
return *this;
|
||||
@ -83,20 +108,20 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
if (!pairs[i].value) // empty node_views
|
||||
continue;
|
||||
map.insert_or_assign(std::move(pairs[i].key), std::move(pairs[i].value));
|
||||
map_.insert_or_assign(std::move(pairs[i].key), std::move(pairs[i].value));
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype) const noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
if (map_.empty())
|
||||
return false;
|
||||
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
ntype = map_.cbegin()->second->type();
|
||||
|
||||
for (const auto& [k, v] : map)
|
||||
for (const auto& [k, v] : map_)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
@ -106,80 +131,27 @@ TOML_NAMESPACE_START
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace impl
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept
|
||||
{
|
||||
template <typename T, typename U>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
bool table_is_homogeneous(T& map, node_type ntype, U& first_nonmatch) noexcept
|
||||
{
|
||||
if (map.empty())
|
||||
{
|
||||
first_nonmatch = {};
|
||||
return false;
|
||||
}
|
||||
if (ntype == node_type::none)
|
||||
ntype = map.cbegin()->second->type();
|
||||
for (const auto& [k, v] : map)
|
||||
{
|
||||
(void)k;
|
||||
if (v->type() != ntype)
|
||||
{
|
||||
first_nonmatch = v.get();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return TOML_ANON_NAMESPACE::table_is_homogeneous(map_, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, toml::node * &first_nonmatch) noexcept
|
||||
bool table::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
return TOML_ANON_NAMESPACE::table_is_homogeneous(map_, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept
|
||||
{
|
||||
return impl::table_is_homogeneous(map, ntype, first_nonmatch);
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[](std::string_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[](std::string_view key) const noexcept
|
||||
{
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[](std::wstring_view key) noexcept
|
||||
{
|
||||
return node_view<node>{ this->get(key) };
|
||||
}
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[](std::wstring_view key) const noexcept
|
||||
{
|
||||
return node_view<const node>{ this->get(key) };
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator==(const table& lhs, const table& rhs) noexcept
|
||||
bool table::equal(const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
if (&lhs == &rhs)
|
||||
return true;
|
||||
if (lhs.map.size() != rhs.map.size())
|
||||
if (lhs.map_.size() != rhs.map_.size())
|
||||
return false;
|
||||
|
||||
for (auto l = lhs.map.begin(), r = rhs.map.begin(), e = lhs.map.end(); l != e; l++, r++)
|
||||
for (auto l = lhs.map_.begin(), r = rhs.map_.begin(), e = lhs.map_.end(); l != e; l++, r++)
|
||||
{
|
||||
if (l->first != r->first)
|
||||
return false;
|
||||
@ -198,14 +170,8 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator!=(const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
||||
/// \endcond
|
||||
|
@ -1,153 +0,0 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
#if TOML_HEADER_ONLY && !TOML_INTELLISENSE
|
||||
#error This header cannot not be included when TOML_HEADER_ONLY is enabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
TOML_ENABLE_WARNINGS;
|
||||
|
||||
#include "node_view.h"
|
||||
#include "default_formatter.h"
|
||||
#include "json_formatter.h"
|
||||
#if TOML_PARSER
|
||||
#include "parser.h"
|
||||
#endif
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
// internal implementation namespace
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
// formatters
|
||||
template class formatter<char>;
|
||||
|
||||
// print to stream machinery
|
||||
template void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
// public namespace
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
// value<>
|
||||
template class value<std::string>;
|
||||
template class value<int64_t>;
|
||||
template class value<double>;
|
||||
template class value<bool>;
|
||||
template class value<date>;
|
||||
template class value<time>;
|
||||
template class value<date_time>;
|
||||
|
||||
// node_view
|
||||
template class node_view<node>;
|
||||
template class node_view<const node>;
|
||||
|
||||
// formatters
|
||||
template class default_formatter<char>;
|
||||
template class json_formatter<char>;
|
||||
|
||||
// various ostream operators
|
||||
template std::ostream& operator<<(std::ostream&, const source_position&);
|
||||
template std::ostream& operator<<(std::ostream&, const source_region&);
|
||||
template std::ostream& operator<<(std::ostream&, const date&);
|
||||
template std::ostream& operator<<(std::ostream&, const time&);
|
||||
template std::ostream& operator<<(std::ostream&, const time_offset&);
|
||||
template std::ostream& operator<<(std::ostream&, const date_time&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<std::string>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<int64_t>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<double>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<bool>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<toml::date>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<toml::time>&);
|
||||
template std::ostream& operator<<(std::ostream&, const value<toml::date_time>&);
|
||||
template std::ostream& operator<<(std::ostream&, default_formatter<char>&);
|
||||
template std::ostream& operator<<(std::ostream&, default_formatter<char>&&);
|
||||
template std::ostream& operator<<(std::ostream&, json_formatter<char>&);
|
||||
template std::ostream& operator<<(std::ostream&, json_formatter<char>&&);
|
||||
template std::ostream& operator<<(std::ostream&, const table&);
|
||||
template std::ostream& operator<<(std::ostream&, const array&);
|
||||
template std::ostream& operator<<(std::ostream&, const node_view<node>&);
|
||||
template std::ostream& operator<<(std::ostream&, const node_view<const node>&);
|
||||
template std::ostream& operator<<(std::ostream&, node_type);
|
||||
|
||||
// node::value, node_view:::value etc
|
||||
#define TOML_INSTANTIATE(name, T) \
|
||||
template optional<T> node::name<T>() const noexcept; \
|
||||
template optional<T> node_view<node>::name<T>() const noexcept; \
|
||||
template optional<T> node_view<const node>::name<T>() const noexcept
|
||||
|
||||
TOML_INSTANTIATE(value_exact, std::string_view);
|
||||
TOML_INSTANTIATE(value_exact, std::string);
|
||||
TOML_INSTANTIATE(value_exact, const char*);
|
||||
TOML_INSTANTIATE(value_exact, int64_t);
|
||||
TOML_INSTANTIATE(value_exact, double);
|
||||
TOML_INSTANTIATE(value_exact, date);
|
||||
TOML_INSTANTIATE(value_exact, time);
|
||||
TOML_INSTANTIATE(value_exact, date_time);
|
||||
TOML_INSTANTIATE(value_exact, bool);
|
||||
TOML_INSTANTIATE(value, std::string_view);
|
||||
TOML_INSTANTIATE(value, std::string);
|
||||
TOML_INSTANTIATE(value, const char*);
|
||||
TOML_INSTANTIATE(value, signed char);
|
||||
TOML_INSTANTIATE(value, signed short);
|
||||
TOML_INSTANTIATE(value, signed int);
|
||||
TOML_INSTANTIATE(value, signed long);
|
||||
TOML_INSTANTIATE(value, signed long long);
|
||||
TOML_INSTANTIATE(value, unsigned char);
|
||||
TOML_INSTANTIATE(value, unsigned short);
|
||||
TOML_INSTANTIATE(value, unsigned int);
|
||||
TOML_INSTANTIATE(value, unsigned long);
|
||||
TOML_INSTANTIATE(value, unsigned long long);
|
||||
TOML_INSTANTIATE(value, double);
|
||||
TOML_INSTANTIATE(value, float);
|
||||
TOML_INSTANTIATE(value, date);
|
||||
TOML_INSTANTIATE(value, time);
|
||||
TOML_INSTANTIATE(value, date_time);
|
||||
TOML_INSTANTIATE(value, bool);
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_INSTANTIATE(value_exact, std::u8string_view);
|
||||
TOML_INSTANTIATE(value_exact, std::u8string);
|
||||
TOML_INSTANTIATE(value_exact, const char8_t*);
|
||||
TOML_INSTANTIATE(value, std::u8string_view);
|
||||
TOML_INSTANTIATE(value, std::u8string);
|
||||
TOML_INSTANTIATE(value, const char8_t*);
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_INSTANTIATE(value_exact, std::wstring);
|
||||
TOML_INSTANTIATE(value, std::wstring);
|
||||
#endif
|
||||
#undef TOML_INSTANTIATE
|
||||
|
||||
// parser instantiations
|
||||
#if TOML_PARSER
|
||||
|
||||
// parse error ostream
|
||||
template std::ostream& operator<<(std::ostream&, const parse_error&);
|
||||
|
||||
// parse() and parse_file()
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
|
||||
template parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template parse_result parse(std::istream&, std::string &&) TOML_MAY_THROW;
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
|
||||
#endif // TOML_PARSER
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
@ -1,400 +0,0 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
#include "utf8.h"
|
||||
#include "parse_error.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_ERROR_CHECK (void)0
|
||||
#define TOML_ERROR throw parse_error
|
||||
#else
|
||||
#define TOML_ERROR_CHECK \
|
||||
if (err) \
|
||||
return nullptr
|
||||
#define TOML_ERROR err.emplace
|
||||
#endif
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
template <typename T>
|
||||
class utf8_byte_stream;
|
||||
|
||||
inline constexpr auto utf8_byte_order_mark = "\xEF\xBB\xBF"sv;
|
||||
|
||||
template <typename Char>
|
||||
class TOML_API utf8_byte_stream<std::basic_string_view<Char>> final
|
||||
{
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
private:
|
||||
std::basic_string_view<Char> source;
|
||||
size_t position = {};
|
||||
|
||||
public:
|
||||
explicit constexpr utf8_byte_stream(std::basic_string_view<Char> sv) noexcept : source{ sv }
|
||||
{
|
||||
// trim trailing nulls
|
||||
const size_t initial_len = source.length();
|
||||
size_t actual_len = initial_len;
|
||||
for (size_t i = actual_len; i-- > 0_sz;)
|
||||
{
|
||||
if (source[i] != Char{}) // not '\0'
|
||||
{
|
||||
actual_len = i + 1_sz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (initial_len != actual_len)
|
||||
source = source.substr(0_sz, actual_len);
|
||||
|
||||
// skip bom
|
||||
if (actual_len >= 3_sz && memcmp(utf8_byte_order_mark.data(), source.data(), 3_sz) == 0)
|
||||
position += 3_sz;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool eof() const noexcept
|
||||
{
|
||||
return position >= source.length();
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool peek_eof() const noexcept
|
||||
{
|
||||
return eof();
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
constexpr unsigned int operator()() noexcept
|
||||
{
|
||||
if (position >= source.length())
|
||||
return 0xFFFFFFFFu;
|
||||
return static_cast<unsigned int>(static_cast<uint8_t>(source[position++]));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
class TOML_API utf8_byte_stream<std::basic_istream<Char>> final
|
||||
{
|
||||
static_assert(sizeof(Char) == 1_sz);
|
||||
|
||||
private:
|
||||
std::basic_istream<Char>* source;
|
||||
|
||||
public:
|
||||
explicit utf8_byte_stream(std::basic_istream<Char>& stream) : source{ &stream }
|
||||
{
|
||||
if (!source->good()) // eof, fail, bad
|
||||
return;
|
||||
|
||||
const auto initial_pos = source->tellg();
|
||||
Char bom[3];
|
||||
source->read(bom, 3);
|
||||
if (source->bad() || (source->gcount() == 3 && memcmp(utf8_byte_order_mark.data(), bom, 3_sz) == 0))
|
||||
return;
|
||||
|
||||
source->clear();
|
||||
source->seekg(initial_pos, std::basic_istream<Char>::beg);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
bool eof() const noexcept
|
||||
{
|
||||
return source->eof();
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
bool peek_eof() const
|
||||
{
|
||||
using stream_traits = typename std::remove_pointer_t<decltype(source)>::traits_type;
|
||||
return eof() || source->peek() == stream_traits::eof();
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
bool error() const noexcept
|
||||
{
|
||||
return !(*source);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
unsigned int operator()()
|
||||
{
|
||||
auto val = source->get();
|
||||
if (val == std::basic_istream<Char>::traits_type::eof())
|
||||
return 0xFFFFFFFFu;
|
||||
return static_cast<unsigned int>(val);
|
||||
}
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_LARGE_FILES, lf, sf);
|
||||
|
||||
struct utf8_codepoint final
|
||||
{
|
||||
char32_t value;
|
||||
char bytes[4];
|
||||
source_position position;
|
||||
|
||||
TOML_NODISCARD
|
||||
std::string_view as_view() const noexcept
|
||||
{
|
||||
return bytes[3] ? std::string_view{ bytes, 4_sz } : std::string_view{ bytes };
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(pure)
|
||||
constexpr operator char32_t&() noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(pure)
|
||||
constexpr operator const char32_t&() const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(pure)
|
||||
constexpr const char32_t& operator*() const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_trivial_v<utf8_codepoint>);
|
||||
static_assert(std::is_standard_layout_v<utf8_codepoint>);
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_LARGE_FILES
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
|
||||
struct TOML_ABSTRACT_BASE utf8_reader_interface
|
||||
{
|
||||
TOML_NODISCARD
|
||||
virtual const source_path_ptr& source_path() const noexcept = 0;
|
||||
|
||||
TOML_NODISCARD
|
||||
virtual const utf8_codepoint* read_next() = 0;
|
||||
|
||||
TOML_NODISCARD
|
||||
virtual bool peek_eof() const = 0;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
TOML_NODISCARD
|
||||
virtual optional<parse_error>&& error() noexcept = 0;
|
||||
|
||||
#endif
|
||||
|
||||
virtual ~utf8_reader_interface() noexcept = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TOML_EMPTY_BASES TOML_API utf8_reader final : public utf8_reader_interface
|
||||
{
|
||||
private:
|
||||
utf8_byte_stream<T> stream;
|
||||
utf8_decoder decoder;
|
||||
utf8_codepoint codepoints[2];
|
||||
size_t cp_idx = 1;
|
||||
uint8_t current_byte_count{};
|
||||
source_path_ptr source_path_;
|
||||
#if !TOML_EXCEPTIONS
|
||||
optional<parse_error> err;
|
||||
#endif
|
||||
|
||||
public:
|
||||
template <typename U, typename String = std::string_view>
|
||||
explicit utf8_reader(U&& source, String&& source_path = {}) noexcept(
|
||||
std::is_nothrow_constructible_v<utf8_byte_stream<T>, U&&>)
|
||||
: stream{ static_cast<U&&>(source) }
|
||||
{
|
||||
std::memset(codepoints, 0, sizeof(codepoints));
|
||||
codepoints[0].position = { 1, 1 };
|
||||
codepoints[1].position = { 1, 1 };
|
||||
|
||||
if (!source_path.empty())
|
||||
source_path_ = std::make_shared<const std::string>(static_cast<String&&>(source_path));
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return source_path_;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const utf8_codepoint* read_next() override
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
auto& prev = codepoints[(cp_idx - 1_sz) % 2_sz];
|
||||
|
||||
if (stream.eof())
|
||||
return nullptr;
|
||||
else if (stream.error())
|
||||
TOML_ERROR("An error occurred while reading from the underlying stream", prev.position, source_path_);
|
||||
else if (decoder.error())
|
||||
TOML_ERROR("Encountered invalid utf-8 sequence", prev.position, source_path_);
|
||||
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint8_t next_byte;
|
||||
{
|
||||
unsigned int next_byte_raw{ 0xFFFFFFFFu };
|
||||
if constexpr (noexcept(stream()) || !TOML_EXCEPTIONS)
|
||||
{
|
||||
next_byte_raw = stream();
|
||||
}
|
||||
#if TOML_EXCEPTIONS
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
next_byte_raw = stream();
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
throw parse_error{ exc.what(), prev.position, source_path_ };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw parse_error{ "An unspecified error occurred", prev.position, source_path_ };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (next_byte_raw >= 256u)
|
||||
{
|
||||
if (stream.eof())
|
||||
{
|
||||
if (decoder.needs_more_input())
|
||||
TOML_ERROR("Encountered EOF during incomplete utf-8 code point sequence",
|
||||
prev.position,
|
||||
source_path_);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
TOML_ERROR("An error occurred while reading from the underlying stream",
|
||||
prev.position,
|
||||
source_path_);
|
||||
}
|
||||
|
||||
TOML_ERROR_CHECK;
|
||||
next_byte = static_cast<uint8_t>(next_byte_raw);
|
||||
}
|
||||
|
||||
decoder(next_byte);
|
||||
if (decoder.error())
|
||||
TOML_ERROR("Encountered invalid utf-8 sequence", prev.position, source_path_);
|
||||
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
auto& current = codepoints[cp_idx % 2_sz];
|
||||
current.bytes[current_byte_count++] = static_cast<char>(next_byte);
|
||||
if (decoder.has_code_point())
|
||||
{
|
||||
// store codepoint
|
||||
current.value = decoder.codepoint;
|
||||
|
||||
// reset prev (will be the next 'current')
|
||||
std::memset(prev.bytes, 0, sizeof(prev.bytes));
|
||||
current_byte_count = {};
|
||||
if (is_line_break<false>(current.value))
|
||||
prev.position = { static_cast<source_index>(current.position.line + 1), 1 };
|
||||
else
|
||||
prev.position = { current.position.line,
|
||||
static_cast<source_index>(current.position.column + 1) };
|
||||
cp_idx++;
|
||||
return ¤t;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool peek_eof() const override
|
||||
{
|
||||
return stream.peek_eof();
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
TOML_NODISCARD
|
||||
optional<parse_error>&& error() noexcept override
|
||||
{
|
||||
return std::move(err);
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string_view) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string &&) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string &&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
class TOML_EMPTY_BASES TOML_API utf8_buffered_reader final : public utf8_reader_interface
|
||||
{
|
||||
public:
|
||||
static constexpr size_t max_history_length = 72;
|
||||
|
||||
private:
|
||||
static constexpr size_t history_buffer_size = max_history_length - 1; //'head' is stored in the reader
|
||||
utf8_reader_interface& reader;
|
||||
struct
|
||||
{
|
||||
utf8_codepoint buffer[history_buffer_size];
|
||||
size_t count, first;
|
||||
} history = {};
|
||||
const utf8_codepoint* head = {};
|
||||
size_t negative_offset = {};
|
||||
|
||||
public:
|
||||
explicit utf8_buffered_reader(utf8_reader_interface& reader_) noexcept;
|
||||
const source_path_ptr& source_path() const noexcept override;
|
||||
const utf8_codepoint* read_next() override;
|
||||
const utf8_codepoint* step_back(size_t count) noexcept;
|
||||
bool peek_eof() const override;
|
||||
#if !TOML_EXCEPTIONS
|
||||
optional<parse_error>&& error() noexcept override;
|
||||
#endif
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
@ -1,117 +0,0 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "utf8_streams.h"
|
||||
#include "header_start.h"
|
||||
/// \cond
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
#define TOML_ERROR_CHECK \
|
||||
if (reader.error()) \
|
||||
return nullptr
|
||||
#else
|
||||
#define TOML_ERROR_CHECK (void)0
|
||||
#endif
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
utf8_buffered_reader::utf8_buffered_reader(utf8_reader_interface & reader_) noexcept : reader{ reader_ }
|
||||
{}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const source_path_ptr& utf8_buffered_reader::source_path() const noexcept
|
||||
{
|
||||
return reader.source_path();
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const utf8_codepoint* utf8_buffered_reader::read_next()
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
|
||||
if (negative_offset)
|
||||
{
|
||||
negative_offset--;
|
||||
|
||||
// an entry negative offset of 1 just means "replay the current head"
|
||||
if (!negative_offset)
|
||||
return head;
|
||||
|
||||
// otherwise step back into the history buffer
|
||||
else
|
||||
return history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// first character read from stream
|
||||
if TOML_UNLIKELY(!history.count && !head)
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if TOML_UNLIKELY(history.count < history_buffer_size)
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
||||
head = reader.read_next();
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const utf8_codepoint* utf8_buffered_reader::step_back(size_t count) noexcept
|
||||
{
|
||||
TOML_ERROR_CHECK;
|
||||
TOML_ASSERT(history.count);
|
||||
TOML_ASSERT(negative_offset + count <= history.count);
|
||||
|
||||
negative_offset += count;
|
||||
|
||||
return negative_offset
|
||||
? history.buffer + ((history.first + history.count - negative_offset) % history_buffer_size)
|
||||
: head;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool utf8_buffered_reader::peek_eof() const
|
||||
{
|
||||
return reader.peek_eof();
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
optional<parse_error>&& utf8_buffered_reader::error() noexcept
|
||||
{
|
||||
return reader.error();
|
||||
}
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
|
||||
/// \endcond
|
||||
#include "header_end.h"
|
@ -70,9 +70,6 @@
|
||||
// clang-format on
|
||||
/// \endcond
|
||||
|
||||
TOML_DISABLE_ARITHMETIC_WARNINGS;
|
||||
TOML_DISABLE_INIT_WARNINGS;
|
||||
|
||||
/// \cond
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
@ -107,21 +104,22 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_NODISCARD
|
||||
static std::string make(T&& arg) noexcept
|
||||
{
|
||||
#if TOML_HAS_CHAR8
|
||||
#if TOML_HAS_CHAR8
|
||||
if constexpr (is_one_of<std::decay_t<T>, char8_t*, const char8_t*>)
|
||||
return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg)));
|
||||
else if constexpr (is_one_of<remove_cvref_t<T>, std::u8string, std::u8string_view>)
|
||||
return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg.data())),
|
||||
arg.length());
|
||||
#endif // TOML_HAS_CHAR8
|
||||
#endif // TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (is_wide_string<T>)
|
||||
return narrow(static_cast<T&&>(arg));
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
}
|
||||
};
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
template <>
|
||||
struct native_value_maker<std::string, char8_t*> : string_maker
|
||||
{};
|
||||
@ -134,8 +132,9 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <>
|
||||
struct native_value_maker<std::string, std::u8string_view> : string_maker
|
||||
{};
|
||||
#endif // TOML_HAS_CHAR8
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#endif // TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
template <>
|
||||
struct native_value_maker<std::string, wchar_t*> : string_maker
|
||||
{};
|
||||
@ -148,7 +147,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <>
|
||||
struct native_value_maker<std::string, std::wstring_view> : string_maker
|
||||
{};
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#endif // TOML_HAS_CHAR8 || TOML_WINDOWS_COMPAT
|
||||
|
||||
@ -199,16 +198,16 @@ TOML_NAMESPACE_START
|
||||
/// - double
|
||||
/// - bool
|
||||
template <typename ValueType>
|
||||
class TOML_API value final : public node
|
||||
class value final : public node
|
||||
{
|
||||
static_assert(impl::is_native<ValueType> && !impl::is_cvref<ValueType>,
|
||||
"A toml::value<> must model one of the native TOML value types:" TOML_SA_NATIVE_VALUE_TYPE_LIST);
|
||||
|
||||
private:
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
|
||||
/// \cond
|
||||
|
||||
friend class TOML_PARSER_TYPENAME;
|
||||
|
||||
template <typename T, typename U>
|
||||
TOML_NODISCARD
|
||||
TOML_ALWAYS_INLINE
|
||||
@ -302,7 +301,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
~value() noexcept override
|
||||
~value() noexcept
|
||||
{
|
||||
TOML_VALUE_DESTROYED;
|
||||
}
|
||||
@ -322,85 +321,73 @@ TOML_NAMESPACE_START
|
||||
/// - node_type::time
|
||||
/// - node_type::date_time
|
||||
TOML_NODISCARD
|
||||
node_type type() const noexcept override
|
||||
node_type type() const noexcept final
|
||||
{
|
||||
return impl::node_type_of<value_type>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_table() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_array() const noexcept override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_value() const noexcept override
|
||||
bool is_value() const noexcept final
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_string() const noexcept override
|
||||
bool is_string() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, std::string>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_integer() const noexcept override
|
||||
bool is_integer() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, int64_t>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_floating_point() const noexcept override
|
||||
bool is_floating_point() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, double>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_number() const noexcept override
|
||||
bool is_number() const noexcept final
|
||||
{
|
||||
return impl::is_one_of<value_type, int64_t, double>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_boolean() const noexcept override
|
||||
bool is_boolean() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, bool>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_date() const noexcept override
|
||||
bool is_date() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, date>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_time() const noexcept override
|
||||
bool is_time() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, time>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_date_time() const noexcept override
|
||||
bool is_date_time() const noexcept final
|
||||
{
|
||||
return std::is_same_v<value_type, date_time>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype) const noexcept override
|
||||
bool is_homogeneous(node_type ntype) const noexcept final
|
||||
{
|
||||
return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, toml::node*& first_nonmatch) noexcept override
|
||||
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
@ -411,7 +398,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
bool is_homogeneous(node_type ntype, const toml::node*& first_nonmatch) const noexcept override
|
||||
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final
|
||||
{
|
||||
if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
|
||||
{
|
||||
@ -445,85 +432,85 @@ TOML_NAMESPACE_START
|
||||
/// @{
|
||||
|
||||
TOML_NODISCARD
|
||||
value<std::string>* as_string() noexcept override
|
||||
value<std::string>* as_string() noexcept final
|
||||
{
|
||||
return as_value<std::string>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<int64_t>* as_integer() noexcept override
|
||||
value<int64_t>* as_integer() noexcept final
|
||||
{
|
||||
return as_value<int64_t>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<double>* as_floating_point() noexcept override
|
||||
value<double>* as_floating_point() noexcept final
|
||||
{
|
||||
return as_value<double>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<bool>* as_boolean() noexcept override
|
||||
value<bool>* as_boolean() noexcept final
|
||||
{
|
||||
return as_value<bool>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<date>* as_date() noexcept override
|
||||
value<date>* as_date() noexcept final
|
||||
{
|
||||
return as_value<date>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<time>* as_time() noexcept override
|
||||
value<time>* as_time() noexcept final
|
||||
{
|
||||
return as_value<time>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
value<date_time>* as_date_time() noexcept override
|
||||
value<date_time>* as_date_time() noexcept final
|
||||
{
|
||||
return as_value<date_time>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<std::string>* as_string() const noexcept override
|
||||
const value<std::string>* as_string() const noexcept final
|
||||
{
|
||||
return as_value<std::string>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<int64_t>* as_integer() const noexcept override
|
||||
const value<int64_t>* as_integer() const noexcept final
|
||||
{
|
||||
return as_value<int64_t>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<double>* as_floating_point() const noexcept override
|
||||
const value<double>* as_floating_point() const noexcept final
|
||||
{
|
||||
return as_value<double>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<bool>* as_boolean() const noexcept override
|
||||
const value<bool>* as_boolean() const noexcept final
|
||||
{
|
||||
return as_value<bool>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<date>* as_date() const noexcept override
|
||||
const value<date>* as_date() const noexcept final
|
||||
{
|
||||
return as_value<date>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<time>* as_time() const noexcept override
|
||||
const value<time>* as_time() const noexcept final
|
||||
{
|
||||
return as_value<time>(this);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
const value<date_time>* as_date_time() const noexcept override
|
||||
const value<date_time>* as_date_time() const noexcept final
|
||||
{
|
||||
return as_value<date_time>(this);
|
||||
}
|
||||
@ -618,11 +605,6 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Prints the value out to a stream as formatted TOML.
|
||||
template <typename Char, typename T>
|
||||
friend std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, const value<T>& rhs);
|
||||
// implemented in toml_default_formatter.h
|
||||
|
||||
/// \brief Value-assignment operator.
|
||||
value& operator=(value_arg rhs) noexcept
|
||||
{
|
||||
@ -822,22 +804,20 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Prints the value out to a stream as formatted TOML.
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const value& rhs)
|
||||
{
|
||||
impl::print_to_stream(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
|
||||
template <typename T>
|
||||
value(T) -> value<impl::native_type_of<impl::remove_cvref_t<T>>>;
|
||||
|
||||
#if !TOML_HEADER_ONLY
|
||||
extern template class TOML_API value<std::string>;
|
||||
extern template class TOML_API value<int64_t>;
|
||||
extern template class TOML_API value<double>;
|
||||
extern template class TOML_API value<bool>;
|
||||
extern template class TOML_API value<date>;
|
||||
extern template class TOML_API value<time>;
|
||||
extern template class TOML_API value<date_time>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
inline decltype(auto) node::get_value_exact() const noexcept
|
||||
@ -887,6 +867,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
inline optional<T> node::value_exact() const noexcept
|
||||
{
|
||||
using namespace impl;
|
||||
@ -909,6 +890,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
inline optional<T> node::value() const noexcept
|
||||
{
|
||||
using namespace impl;
|
||||
@ -1025,6 +1007,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
inline auto node::value_or(T && default_value) const noexcept
|
||||
{
|
||||
using namespace impl;
|
||||
@ -1055,39 +1038,47 @@ TOML_NAMESPACE_START
|
||||
std::decay_t<T>>;
|
||||
using traits = value_traits<value_type>;
|
||||
|
||||
// clang-format off
|
||||
|
||||
static_assert(
|
||||
traits::is_native || traits::can_represent_native || traits::can_partially_represent_native,
|
||||
"The default value type of node::value_or() must be one of:" TOML_SA_LIST_NEW
|
||||
"A native TOML value type" TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
"The default value type of node::value_or() must be one of:"
|
||||
TOML_SA_LIST_NEW "A native TOML value type"
|
||||
TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
|
||||
TOML_SA_LIST_NXT
|
||||
"A non-view type capable of losslessly representing a native TOML value type" TOML_SA_LIST_BEG
|
||||
"std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_NXT "A non-view type capable of losslessly representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "std::string"
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring"
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits" TOML_SA_LIST_SEP
|
||||
"any floating-point type >= 64 bits" TOML_SA_LIST_END
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "any signed integer type >= 64 bits"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 64 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT
|
||||
"A non-view type capable of (reasonably) representing a native TOML value type" TOML_SA_LIST_BEG
|
||||
"any other integer type" TOML_SA_LIST_SEP "any floating-point type >= 32 bits" TOML_SA_LIST_END
|
||||
TOML_SA_LIST_NXT "A non-view type capable of (reasonably) representing a native TOML value type"
|
||||
TOML_SA_LIST_BEG "any other integer type"
|
||||
TOML_SA_LIST_SEP "any floating-point type >= 32 bits"
|
||||
TOML_SA_LIST_END
|
||||
|
||||
TOML_SA_LIST_NXT "A compatible view type" TOML_SA_LIST_BEG "std::string_view"
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_SA_LIST_NXT "A compatible view type"
|
||||
TOML_SA_LIST_BEG "std::string_view"
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_SA_LIST_SEP "std::u8string_view"
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "std::wstring_view"
|
||||
#endif
|
||||
#endif
|
||||
TOML_SA_LIST_SEP "const char*"
|
||||
#if TOML_HAS_CHAR8
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_SA_LIST_SEP "const char8_t*"
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_SA_LIST_SEP "const wchar_t*"
|
||||
#endif
|
||||
TOML_SA_LIST_END);
|
||||
#endif
|
||||
TOML_SA_LIST_END
|
||||
);
|
||||
|
||||
// clang-format on
|
||||
|
||||
// prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
|
||||
if constexpr (traits::is_native || traits::can_represent_native || traits::can_partially_represent_native)
|
||||
@ -1107,11 +1098,20 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
}
|
||||
|
||||
#if !TOML_HEADER_ONLY
|
||||
#if TOML_EXTERN_TEMPLATES
|
||||
|
||||
extern template class TOML_API value<std::string>;
|
||||
extern template class TOML_API value<int64_t>;
|
||||
extern template class TOML_API value<double>;
|
||||
extern template class TOML_API value<bool>;
|
||||
extern template class TOML_API value<date>;
|
||||
extern template class TOML_API value<time>;
|
||||
extern template class TOML_API value<date_time>;
|
||||
|
||||
#define TOML_EXTERN(name, T) \
|
||||
extern template TOML_API \
|
||||
optional<T> node::name<T>() const noexcept
|
||||
|
||||
#define TOML_EXTERN(name, T) \
|
||||
extern template TOML_API \
|
||||
optional<T> node::name<T>() const noexcept
|
||||
TOML_EXTERN(value_exact, std::string_view);
|
||||
TOML_EXTERN(value_exact, std::string);
|
||||
TOML_EXTERN(value_exact, const char*);
|
||||
@ -1140,21 +1140,24 @@ TOML_NAMESPACE_START
|
||||
TOML_EXTERN(value, time);
|
||||
TOML_EXTERN(value, date_time);
|
||||
TOML_EXTERN(value, bool);
|
||||
#if TOML_HAS_CHAR8
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_EXTERN(value_exact, std::u8string_view);
|
||||
TOML_EXTERN(value_exact, std::u8string);
|
||||
TOML_EXTERN(value_exact, const char8_t*);
|
||||
TOML_EXTERN(value, std::u8string_view);
|
||||
TOML_EXTERN(value, std::u8string);
|
||||
TOML_EXTERN(value, const char8_t*);
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
#endif
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_EXTERN(value_exact, std::wstring);
|
||||
TOML_EXTERN(value, std::wstring);
|
||||
#endif
|
||||
#undef TOML_EXTERN
|
||||
#endif
|
||||
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
#undef TOML_EXTERN
|
||||
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
|
||||
/// \endcond
|
||||
}
|
||||
|
81
include/toml++/impl/value_impl.h
Normal file
81
include/toml++/impl/value_impl.h
Normal file
@ -0,0 +1,81 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
//# {{
|
||||
#include "preprocessor.h"
|
||||
#if !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#if TOML_EXTERN_TEMPLATES
|
||||
#include "value.h"
|
||||
#include "date_time.h"
|
||||
#include "header_start.h"
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
template class value<std::string>;
|
||||
template class value<int64_t>;
|
||||
template class value<double>;
|
||||
template class value<bool>;
|
||||
template class value<date>;
|
||||
template class value<time>;
|
||||
template class value<date_time>;
|
||||
|
||||
#define TOML_EXTERN(name, T) template optional<T> node::name<T>() const noexcept
|
||||
|
||||
TOML_EXTERN(value_exact, std::string_view);
|
||||
TOML_EXTERN(value_exact, std::string);
|
||||
TOML_EXTERN(value_exact, const char*);
|
||||
TOML_EXTERN(value_exact, int64_t);
|
||||
TOML_EXTERN(value_exact, double);
|
||||
TOML_EXTERN(value_exact, date);
|
||||
TOML_EXTERN(value_exact, time);
|
||||
TOML_EXTERN(value_exact, date_time);
|
||||
TOML_EXTERN(value_exact, bool);
|
||||
TOML_EXTERN(value, std::string_view);
|
||||
TOML_EXTERN(value, std::string);
|
||||
TOML_EXTERN(value, const char*);
|
||||
TOML_EXTERN(value, signed char);
|
||||
TOML_EXTERN(value, signed short);
|
||||
TOML_EXTERN(value, signed int);
|
||||
TOML_EXTERN(value, signed long);
|
||||
TOML_EXTERN(value, signed long long);
|
||||
TOML_EXTERN(value, unsigned char);
|
||||
TOML_EXTERN(value, unsigned short);
|
||||
TOML_EXTERN(value, unsigned int);
|
||||
TOML_EXTERN(value, unsigned long);
|
||||
TOML_EXTERN(value, unsigned long long);
|
||||
TOML_EXTERN(value, double);
|
||||
TOML_EXTERN(value, float);
|
||||
TOML_EXTERN(value, date);
|
||||
TOML_EXTERN(value, time);
|
||||
TOML_EXTERN(value, date_time);
|
||||
TOML_EXTERN(value, bool);
|
||||
|
||||
#if TOML_HAS_CHAR8
|
||||
TOML_EXTERN(value_exact, std::u8string_view);
|
||||
TOML_EXTERN(value_exact, std::u8string);
|
||||
TOML_EXTERN(value_exact, const char8_t*);
|
||||
TOML_EXTERN(value, std::u8string_view);
|
||||
TOML_EXTERN(value, std::u8string);
|
||||
TOML_EXTERN(value, const char8_t*);
|
||||
#endif
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
TOML_EXTERN(value_exact, std::wstring);
|
||||
TOML_EXTERN(value, std::wstring);
|
||||
#endif
|
||||
|
||||
#undef TOML_EXTERN
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#include "header_end.h"
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
/// \endcond
|
@ -2,11 +2,10 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TOML_LIB_MAJOR 2
|
||||
#define TOML_LIB_MINOR 6
|
||||
#define TOML_LIB_MAJOR 3
|
||||
#define TOML_LIB_MINOR 0
|
||||
#define TOML_LIB_PATCH 0
|
||||
|
||||
#define TOML_LANG_MAJOR 1
|
||||
|
@ -2,153 +2,161 @@
|
||||
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#ifndef TOMLPLUSPLUS_H
|
||||
#define TOMLPLUSPLUS_H
|
||||
|
||||
#ifndef INCLUDE_TOMLPLUSPLUS_H
|
||||
#define INCLUDE_TOMLPLUSPLUS_H
|
||||
#define INCLUDE_TOMLPLUSPLUS_H // old guard name used pre-v3
|
||||
|
||||
//# Note: most of these would be included transitively but
|
||||
//# they're listed explicitly here because this file
|
||||
//# is used as the source for generate_single_header.py.
|
||||
//# Note: these would be included transitively as with any normal C++ project but
|
||||
//# they're listed explicitly here because this file is used as the source for generate_single_header.py.
|
||||
|
||||
#include "impl/preprocessor.h"
|
||||
|
||||
//# {{
|
||||
TOML_PUSH_WARNINGS;
|
||||
TOML_DISABLE_SPAM_WARNINGS;
|
||||
#if TOML_MSVC
|
||||
#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#include "impl/common.h"
|
||||
#include "impl/date_time.h"
|
||||
#include "impl/std_new.h"
|
||||
#include "impl/std_string.h"
|
||||
#include "impl/std_optional.h"
|
||||
#include "impl/forward_declarations.h"
|
||||
#include "impl/print_to_stream.h"
|
||||
#include "impl/source_region.h"
|
||||
#include "impl/date_time.h"
|
||||
#include "impl/node.h"
|
||||
#include "impl/node_view.h"
|
||||
#include "impl/value.h"
|
||||
#include "impl/make_node.h"
|
||||
#include "impl/array.h"
|
||||
#include "impl/table.h"
|
||||
#include "impl/node_view.h"
|
||||
#include "impl/utf8.h"
|
||||
#if TOML_PARSER
|
||||
#include "impl/parse_error.h"
|
||||
#include "impl/parse_result.h"
|
||||
#include "impl/utf8_streams.h"
|
||||
#include "impl/parser.h"
|
||||
#endif // TOML_PARSER
|
||||
#include "impl/parse_error.h"
|
||||
#include "impl/parse_result.h"
|
||||
#include "impl/parser.h"
|
||||
#include "impl/formatter.h"
|
||||
#include "impl/default_formatter.h"
|
||||
#include "impl/json_formatter.h"
|
||||
|
||||
#if TOML_IMPLEMENTATION
|
||||
#include "impl/node_impl.h"
|
||||
#include "impl/array_impl.h"
|
||||
#include "impl/table_impl.h"
|
||||
#if TOML_PARSER
|
||||
#include "impl/utf8_streams_impl.h"
|
||||
#include "impl/parser_impl.h"
|
||||
#endif // TOML_PARSER
|
||||
#include "impl/default_formatter_impl.h"
|
||||
#include "impl/json_formatter_impl.h"
|
||||
#if !TOML_HEADER_ONLY
|
||||
#include "impl/template_instantiations.h"
|
||||
#endif // !TOML_HEADER_ONLY
|
||||
#endif // TOML_IMPLEMENTATION
|
||||
#include "impl/std_string_impl.h"
|
||||
#include "impl/print_to_stream_impl.h"
|
||||
#include "impl/node_impl.h"
|
||||
#include "impl/node_view_impl.h"
|
||||
#include "impl/value_impl.h"
|
||||
#include "impl/array_impl.h"
|
||||
#include "impl/table_impl.h"
|
||||
#include "impl/parser_impl.h"
|
||||
#include "impl/formatter_impl.h"
|
||||
#include "impl/default_formatter_impl.h"
|
||||
#include "impl/json_formatter_impl.h"
|
||||
#endif // TOML_IMPLEMENTATION
|
||||
|
||||
TOML_POP_WARNINGS; // TOML_DISABLE_SPAM_WARNINGS
|
||||
//# {{
|
||||
TOML_POP_WARNINGS;
|
||||
//# }}
|
||||
|
||||
// macro hygiene
|
||||
#if TOML_UNDEF_MACROS
|
||||
#undef TOML_ABI_NAMESPACE_BOOL
|
||||
#undef TOML_ABI_NAMESPACE_END
|
||||
#undef TOML_ABI_NAMESPACE_START
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_ABSTRACT_BASE
|
||||
#undef TOML_ALWAYS_INLINE
|
||||
#undef TOML_ANON_NAMESPACE
|
||||
#undef TOML_ANON_NAMESPACE_END
|
||||
#undef TOML_ANON_NAMESPACE_START
|
||||
#undef TOML_ARM
|
||||
#undef TOML_ASSERT
|
||||
#undef TOML_ASSUME
|
||||
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
|
||||
#undef TOML_ATTR
|
||||
#undef TOML_CLANG
|
||||
#undef TOML_COMPILER_EXCEPTIONS
|
||||
#undef TOML_CONCAT
|
||||
#undef TOML_CONCAT_1
|
||||
#undef TOML_CONSTEVAL
|
||||
#undef TOML_CONSTRAINED_TEMPLATE
|
||||
#undef TOML_CPP
|
||||
#undef TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
|
||||
#undef TOML_DISABLE_INIT_WARNINGS
|
||||
#undef TOML_DISABLE_SHADOW_WARNINGS
|
||||
#undef TOML_DISABLE_SPAM_WARNINGS
|
||||
#undef TOML_DISABLE_SUGGEST_WARNINGS
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
#undef TOML_DISABLE_WARNINGS
|
||||
#undef TOML_EMPTY_BASES
|
||||
#undef TOML_ENABLE_IF
|
||||
#undef TOML_ENABLE_WARNINGS
|
||||
#undef TOML_EVAL_BOOL_0
|
||||
#undef TOML_EVAL_BOOL_1
|
||||
#undef TOML_EXTERNAL_LINKAGE
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#undef TOML_FLOAT128
|
||||
#undef TOML_FLOAT16
|
||||
#undef TOML_FP16
|
||||
#undef TOML_GCC
|
||||
#undef TOML_HAS_ATTR
|
||||
#undef TOML_HAS_CHAR8
|
||||
#undef TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#undef TOML_HAS_INCLUDE
|
||||
#undef TOML_ICC
|
||||
#undef TOML_ICC_CL
|
||||
#undef TOML_IMPL_NAMESPACE_END
|
||||
#undef TOML_IMPL_NAMESPACE_START
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#undef TOML_INCLUDE_WINDOWS_H
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_INT128
|
||||
#undef TOML_INTELLISENSE
|
||||
#undef TOML_INTERNAL_LINKAGE
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_EFFECTIVE_VERSION
|
||||
#undef TOML_LANG_HIGHER_THAN
|
||||
#undef TOML_LANG_UNRELEASED
|
||||
#undef TOML_LAUNDER
|
||||
#undef TOML_LIFETIME_HOOKS
|
||||
#undef TOML_LIKELY
|
||||
#undef TOML_MAKE_FLAGS
|
||||
#undef TOML_MAKE_FLAGS_
|
||||
#undef TOML_MAKE_VERSION
|
||||
#undef TOML_MAY_THROW
|
||||
#undef TOML_MSVC
|
||||
#undef TOML_NAMESPACE
|
||||
#undef TOML_NAMESPACE_END
|
||||
#undef TOML_NAMESPACE_START
|
||||
#undef TOML_NEVER_INLINE
|
||||
#undef TOML_NODISCARD
|
||||
#undef TOML_NODISCARD_CTOR
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_POP_WARNINGS
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_REQUIRES
|
||||
#undef TOML_SA_LIST_BEG
|
||||
#undef TOML_SA_LIST_END
|
||||
#undef TOML_SA_LIST_NEW
|
||||
#undef TOML_SA_LIST_NXT
|
||||
#undef TOML_SA_LIST_SEP
|
||||
#undef TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
#undef TOML_SA_NEWLINE
|
||||
#undef TOML_SA_NODE_TYPE_LIST
|
||||
#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#undef TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_UINT128
|
||||
#undef TOML_UNLIKELY
|
||||
#undef TOML_UNREACHABLE
|
||||
#undef TOML_USING_ANON_NAMESPACE
|
||||
#undef TOML_ABI_NAMESPACE_BOOL
|
||||
#undef TOML_ABI_NAMESPACE_END
|
||||
#undef TOML_ABI_NAMESPACE_START
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_ABSTRACT_BASE
|
||||
#undef TOML_ALWAYS_INLINE
|
||||
#undef TOML_ANON_NAMESPACE
|
||||
#undef TOML_ANON_NAMESPACE_END
|
||||
#undef TOML_ANON_NAMESPACE_START
|
||||
#undef TOML_ARM
|
||||
#undef TOML_ASSERT
|
||||
#undef TOML_ASSUME
|
||||
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
|
||||
#undef TOML_ATTR
|
||||
#undef TOML_CLANG
|
||||
#undef TOML_COMPILER_EXCEPTIONS
|
||||
#undef TOML_CONCAT
|
||||
#undef TOML_CONCAT_1
|
||||
#undef TOML_CONSTEVAL
|
||||
#undef TOML_CONSTRAINED_TEMPLATE
|
||||
#undef TOML_CPP
|
||||
#undef TOML_DISABLE_ARITHMETIC_WARNINGS
|
||||
#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
|
||||
#undef TOML_DISABLE_INIT_WARNINGS
|
||||
#undef TOML_DISABLE_SHADOW_WARNINGS
|
||||
#undef TOML_DISABLE_SPAM_WARNINGS
|
||||
#undef TOML_DISABLE_SUGGEST_WARNINGS
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
#undef TOML_DISABLE_WARNINGS
|
||||
#undef TOML_EMPTY_BASES
|
||||
#undef TOML_ENABLE_IF
|
||||
#undef TOML_ENABLE_WARNINGS
|
||||
#undef TOML_EVAL_BOOL_0
|
||||
#undef TOML_EVAL_BOOL_1
|
||||
#undef TOML_EXTERNAL_LINKAGE
|
||||
#undef TOML_EXTERN_TEMPLATES
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#undef TOML_FLOAT128
|
||||
#undef TOML_FLOAT16
|
||||
#undef TOML_FP16
|
||||
#undef TOML_GCC
|
||||
#undef TOML_HAS_ATTR
|
||||
#undef TOML_HAS_CHAR8
|
||||
#undef TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#undef TOML_HAS_INCLUDE
|
||||
#undef TOML_ICC
|
||||
#undef TOML_ICC_CL
|
||||
#undef TOML_IMPL_NAMESPACE_END
|
||||
#undef TOML_IMPL_NAMESPACE_START
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#undef TOML_INCLUDE_WINDOWS_H
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_INT128
|
||||
#undef TOML_INTELLISENSE
|
||||
#undef TOML_INTERNAL_LINKAGE
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_EFFECTIVE_VERSION
|
||||
#undef TOML_LANG_HIGHER_THAN
|
||||
#undef TOML_LANG_UNRELEASED
|
||||
#undef TOML_LAUNDER
|
||||
#undef TOML_LIFETIME_HOOKS
|
||||
#undef TOML_LIKELY
|
||||
#undef TOML_MAKE_FLAGS
|
||||
#undef TOML_MAKE_FLAGS_
|
||||
#undef TOML_MAKE_VERSION
|
||||
#undef TOML_MAY_THROW
|
||||
#undef TOML_MSVC
|
||||
#undef TOML_NAMESPACE
|
||||
#undef TOML_NAMESPACE_END
|
||||
#undef TOML_NAMESPACE_START
|
||||
#undef TOML_NEVER_INLINE
|
||||
#undef TOML_NODISCARD
|
||||
#undef TOML_NODISCARD_CTOR
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_POP_WARNINGS
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_REQUIRES
|
||||
#undef TOML_SA_LIST_BEG
|
||||
#undef TOML_SA_LIST_END
|
||||
#undef TOML_SA_LIST_NEW
|
||||
#undef TOML_SA_LIST_NXT
|
||||
#undef TOML_SA_LIST_SEP
|
||||
#undef TOML_SA_NATIVE_VALUE_TYPE_LIST
|
||||
#undef TOML_SA_NEWLINE
|
||||
#undef TOML_SA_NODE_TYPE_LIST
|
||||
#undef TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
#undef TOML_SA_VALUE_EXACT_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_FUNC_MESSAGE
|
||||
#undef TOML_SA_VALUE_MESSAGE_CONST_CHAR8
|
||||
#undef TOML_SA_VALUE_MESSAGE_U8STRING_VIEW
|
||||
#undef TOML_SA_VALUE_MESSAGE_WSTRING
|
||||
#undef TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_UINT128
|
||||
#undef TOML_UNLIKELY
|
||||
#undef TOML_UNREACHABLE
|
||||
#undef TOML_USING_ANON_NAMESPACE
|
||||
#endif
|
||||
|
||||
#endif // INCLUDE_TOMLPLUSPLUS_H
|
||||
#endif // TOMLPLUSPLUS_H
|
||||
|
@ -1,7 +1,7 @@
|
||||
project(
|
||||
'tomlplusplus',
|
||||
'cpp',
|
||||
version: '2.6.0',
|
||||
version: '3.0.0',
|
||||
meson_version: '>=0.53.0',
|
||||
license: 'MIT',
|
||||
default_options: [ # https://mesonbuild.com/Builtin-options.html
|
||||
@ -62,7 +62,7 @@ if is_gcc or is_clang
|
||||
add_project_arguments(
|
||||
'-march=native',
|
||||
'-fvisibility=hidden',
|
||||
'-fvisibility-inlines-hidden',
|
||||
'-fvisility-inlines-hidden',
|
||||
language: 'cpp'
|
||||
)
|
||||
if is_release
|
||||
|
@ -37,32 +37,42 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\toml++\impl\array.h" />
|
||||
<ClInclude Include="include\toml++\impl\array_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\common.h" />
|
||||
<ClInclude Include="include\toml++\impl\date_time.h" />
|
||||
<ClInclude Include="include\toml++\impl\default_formatter.h" />
|
||||
<ClInclude Include="include\toml++\impl\default_formatter_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\formatter.h" />
|
||||
<ClInclude Include="include\toml++\impl\formatter_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\forward_declarations.h" />
|
||||
<ClInclude Include="include\toml++\impl\header_end.h" />
|
||||
<ClInclude Include="include\toml++\impl\header_start.h" />
|
||||
<ClInclude Include="include\toml++\impl\json_formatter.h" />
|
||||
<ClInclude Include="include\toml++\impl\json_formatter_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\make_node.h" />
|
||||
<ClInclude Include="include\toml++\impl\node.h" />
|
||||
<ClInclude Include="include\toml++\impl\node_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\node_view.h" />
|
||||
<ClInclude Include="include\toml++\impl\node_view_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\parse_error.h" />
|
||||
<ClInclude Include="include\toml++\impl\parse_result.h" />
|
||||
<ClInclude Include="include\toml++\impl\parser.h" />
|
||||
<ClInclude Include="include\toml++\impl\parser_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\preprocessor.h" />
|
||||
<ClInclude Include="include\toml++\impl\print_to_stream.h" />
|
||||
<ClInclude Include="include\toml++\impl\print_to_stream_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\source_region.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_except.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_map.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_new.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_optional.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_string.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_vector.h" />
|
||||
<ClInclude Include="include\toml++\impl\table.h" />
|
||||
<ClInclude Include="include\toml++\impl\table_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\template_instantiations.h" />
|
||||
<ClInclude Include="include\toml++\impl\utf8.h" />
|
||||
<ClInclude Include="include\toml++\impl\utf8_streams.h" />
|
||||
<ClInclude Include="include\toml++\impl\utf8_streams_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\value.h" />
|
||||
<ClInclude Include="include\toml++\impl\value_impl.h" />
|
||||
<ClInclude Include="include\toml++\impl\version.h" />
|
||||
<ClInclude Include="include\toml++\impl\std_string_impl.h" />
|
||||
<ClInclude Include="include\toml++\toml.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -10,9 +10,6 @@
|
||||
<ClInclude Include="include\toml++\impl\array_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\common.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\date_time.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
@ -64,18 +61,9 @@
|
||||
<ClInclude Include="include\toml++\impl\table_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\template_instantiations.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\utf8.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\utf8_streams.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\utf8_streams_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\value.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
@ -88,6 +76,48 @@
|
||||
<ClInclude Include="include\toml++\impl\header_end.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\source_region.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_optional.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_vector.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_map.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\make_node.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\forward_declarations.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_except.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_string.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_new.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\std_string_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\print_to_stream_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\formatter_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\node_view_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\toml++\impl\value_impl.h">
|
||||
<Filter>include\impl</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="toml++.props" />
|
||||
|
@ -181,6 +181,7 @@ def main():
|
||||
if m:
|
||||
defines[m.group(1)] = defined
|
||||
ignore_list = ( # macros that are meant to stay public (user configs etc)
|
||||
r'TOMLPLUSPLUS_H',
|
||||
r'INCLUDE_TOMLPLUSPLUS_H',
|
||||
r'TOML_ALL_INLINE',
|
||||
r'TOML_API',
|
||||
@ -190,7 +191,6 @@ def main():
|
||||
r'TOML_LANG_MAJOR',
|
||||
r'TOML_LANG_MINOR',
|
||||
r'TOML_LANG_PATCH',
|
||||
r'TOML_LARGE_FILES',
|
||||
r'TOML_LIB_MAJOR',
|
||||
r'TOML_LIB_MINOR',
|
||||
r'TOML_LIB_PATCH',
|
||||
|
Loading…
Reference in New Issue
Block a user