mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
fixed printing of inf and nan
also: - fixed parser not handling floats with leading '.' characters - added `TOML_PARSER` configuration option - added `TOML_LIB_SINGLE_HEADER` indicator - moved parse_error and the utf8 stream machinery to separate headers - updated catch2
This commit is contained in:
parent
104b2741d1
commit
682436aa2e
@ -109,6 +109,7 @@ won't need to mess with these at all, but if you do, set them before including t
|
||||
| `TOML_IMPLEMENTATION` | define | undefined | Define this to enable compilation of the library's implementation. Meaningless if `TOML_ALL_INLINE` 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. |
|
||||
| `TOML_SMALL_INT_TYPE` | type name | undefined | If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. |
|
||||
| `TOML_UNDEF_MACROS` | boolean | `1` | `#undefs` the library's internal macros at the end of the header. |
|
||||
|
@ -352,7 +352,7 @@ PREDEFINED = DOXYGEN=1 \
|
||||
TOML_NODISCARD_CTOR= \
|
||||
TOML_ALL_INLINE=0 \
|
||||
TOML_IMPLEMENTATION=0 \
|
||||
TOML_FUNC_EXTERNAL_LINKAGE= \
|
||||
TOML_EXTERNAL_LINKAGE= \
|
||||
TOML_API= \
|
||||
__cpp_lib_char8_t=201811L
|
||||
EXPAND_AS_DEFINED =
|
||||
|
2
extern/Catch2
vendored
2
extern/Catch2
vendored
@ -1 +1 @@
|
||||
Subproject commit 87b5bf77bc98030bdbca52bff65ee24fc6483d3b
|
||||
Subproject commit d399a308d04b885433396f4198c0cda999f28d77
|
@ -18,26 +18,31 @@
|
||||
#include "toml_node_view.h"
|
||||
#include "toml_utf8_generated.h"
|
||||
#include "toml_utf8.h"
|
||||
#include "toml_parser.h"
|
||||
#include "toml_formatter.h"
|
||||
#include "toml_default_formatter.h"
|
||||
#include "toml_json_formatter.h"
|
||||
|
||||
#if TOML_PARSER
|
||||
#include "toml_parse_error.h"
|
||||
#include "toml_utf8_streams.h"
|
||||
#include "toml_parser.h"
|
||||
#endif // TOML_PARSER
|
||||
#if TOML_IMPLEMENTATION
|
||||
|
||||
#include "toml_instantiations.hpp"
|
||||
#include "toml_node.hpp"
|
||||
#include "toml_array.hpp"
|
||||
#include "toml_table.hpp"
|
||||
#include "toml_parser.hpp"
|
||||
#include "toml_default_formatter.hpp"
|
||||
|
||||
#endif
|
||||
#include "toml_node.hpp"
|
||||
#include "toml_array.hpp"
|
||||
#include "toml_table.hpp"
|
||||
#include "toml_default_formatter.hpp"
|
||||
#if TOML_PARSER
|
||||
#include "toml_parser.hpp"
|
||||
#endif // TOML_PARSER
|
||||
#if !TOML_ALL_INLINE
|
||||
#include "toml_instantiations.hpp"
|
||||
#endif // !TOML_ALL_INLINE
|
||||
#endif // TOML_IMPLEMENTATION
|
||||
|
||||
// macro hygiene
|
||||
#if TOML_UNDEF_MACROS
|
||||
#undef TOML_INTEGER_CHARCONV
|
||||
#undef TOML_FLOATING_POINT_CHARCONV
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#undef TOML_GNU_ATTR
|
||||
#undef TOML_PUSH_WARNINGS
|
||||
#undef TOML_DISABLE_SWITCH_WARNINGS
|
||||
@ -71,7 +76,9 @@
|
||||
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
|
||||
#undef TOML_ALL_INLINE
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#undef TOML_FUNC_EXTERNAL_LINKAGE
|
||||
#undef TOML_EXTERNAL_LINKAGE
|
||||
#undef TOML_INTERNAL_LINKAGE
|
||||
#undef TOML_INTERNAL_NAMESPACE
|
||||
#undef TOML_COMPILER_EXCEPTIONS
|
||||
#undef TOML_LAUNDER
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
@ -432,6 +439,9 @@
|
||||
/// <strong>Step 2: Define `TOML_IMPLEMENTATION` before including `toml++` in one specific translation unit</strong>
|
||||
///
|
||||
/// \cpp
|
||||
///
|
||||
/// Additionally, if all you need to do is serialize some code-generated TOML and don't actually need the parser at all,
|
||||
/// you can `#define TOML_PARSER 0`.
|
||||
/// // some_code_file.cpp
|
||||
///
|
||||
/// #define TOML_IMPLEMENTATION
|
||||
|
@ -159,10 +159,11 @@ namespace toml::impl
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_ALWAYS_INLINE
|
||||
auto make_node(T&& val) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<remove_cvref_t<T>>;
|
||||
using type = unwrapped<remove_cvref_t<T>>;
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
static_assert(
|
||||
|
@ -2,9 +2,9 @@
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
//# {{
|
||||
#pragma once
|
||||
#include "toml_array.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::preinsertion_resize(size_t idx, size_t count) noexcept
|
||||
{
|
||||
const auto new_size = values.size() + count;
|
||||
@ -25,16 +25,16 @@ namespace toml
|
||||
}
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array() noexcept = default;
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::array(array&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
values{ std::move(other.values) }
|
||||
{}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::operator= (array&& rhs) noexcept
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
@ -42,66 +42,66 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE node_type array::type() const noexcept { return node_type::array; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool array::is_table() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool array::is_array() const noexcept { return true; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool array::is_value() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array* array::as_array() noexcept { return this; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const array* array::as_array() const noexcept { return this; }
|
||||
TOML_EXTERNAL_LINKAGE node_type array::type() const noexcept { return node_type::array; }
|
||||
TOML_EXTERNAL_LINKAGE bool array::is_table() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool array::is_array() const noexcept { return true; }
|
||||
TOML_EXTERNAL_LINKAGE bool array::is_value() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE array* array::as_array() noexcept { return this; }
|
||||
TOML_EXTERNAL_LINKAGE const array* array::as_array() const noexcept { return this; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE node& array::operator[] (size_t index) noexcept { return *values[index]; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const node& array::operator[] (size_t index) const noexcept { return *values[index]; }
|
||||
TOML_EXTERNAL_LINKAGE node& array::operator[] (size_t index) noexcept { return *values[index]; }
|
||||
TOML_EXTERNAL_LINKAGE const node& array::operator[] (size_t index) const noexcept { return *values[index]; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE node& array::front() noexcept { return *values.front(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const node& array::front() const noexcept { return *values.front(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE node& array::back() noexcept { return *values.back(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const node& array::back() const noexcept { return *values.back(); }
|
||||
TOML_EXTERNAL_LINKAGE node& array::front() noexcept { return *values.front(); }
|
||||
TOML_EXTERNAL_LINKAGE const node& array::front() const noexcept { return *values.front(); }
|
||||
TOML_EXTERNAL_LINKAGE node& array::back() noexcept { return *values.back(); }
|
||||
TOML_EXTERNAL_LINKAGE const node& array::back() const noexcept { return *values.back(); }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::iterator array::begin() noexcept { return { values.begin() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::const_iterator array::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::const_iterator array::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::iterator array::begin() noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::const_iterator array::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::const_iterator array::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::iterator array::end() noexcept { return { values.end() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::const_iterator array::end() const noexcept { return { values.end() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array::const_iterator array::cend() const noexcept { return { values.cend() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::iterator array::end() noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::const_iterator array::end() const noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE array::const_iterator array::cend() const noexcept { return { values.cend() }; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool array::empty() const noexcept { return values.empty(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE size_t array::size() const noexcept { return values.size(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE void array::reserve(size_t new_capacity) { values.reserve(new_capacity); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE void array::clear() noexcept { values.clear(); }
|
||||
TOML_EXTERNAL_LINKAGE bool array::empty() const noexcept { return values.empty(); }
|
||||
TOML_EXTERNAL_LINKAGE size_t array::size() const noexcept { return values.size(); }
|
||||
TOML_EXTERNAL_LINKAGE void array::reserve(size_t new_capacity) { values.reserve(new_capacity); }
|
||||
TOML_EXTERNAL_LINKAGE void array::clear() noexcept { values.clear(); }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::iterator array::erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array::iterator array::erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { values.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::pop_back() noexcept
|
||||
{
|
||||
values.pop_back();
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node* array::get(size_t index) noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const node* array::get(size_t index) const noexcept
|
||||
{
|
||||
return index < values.size() ? values[index].get() : nullptr;
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator == (const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
if (&lhs == &rhs)
|
||||
@ -127,13 +127,13 @@ namespace toml
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator != (const array& lhs, const array& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
size_t array::total_leaf_count() const noexcept
|
||||
{
|
||||
size_t leaves{};
|
||||
@ -145,7 +145,7 @@ namespace toml
|
||||
return leaves;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::flatten_child(array&& child, size_t& dest_index) noexcept
|
||||
{
|
||||
for (size_t i = 0, e = child.size(); i < e; i++)
|
||||
@ -162,7 +162,7 @@ namespace toml
|
||||
}
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void array::flatten()
|
||||
{
|
||||
if (values.empty())
|
||||
|
@ -9,42 +9,36 @@
|
||||
|
||||
#ifdef TOML_CONFIG_HEADER
|
||||
#include TOML_CONFIG_HEADER
|
||||
#undef TOML_CONFIG_HEADER
|
||||
#endif
|
||||
|
||||
#if !defined(TOML_ALL_INLINE) || (defined(TOML_ALL_INLINE) && TOML_ALL_INLINE)
|
||||
#undef TOML_ALL_INLINE
|
||||
#define TOML_ALL_INLINE 1
|
||||
#endif
|
||||
|
||||
#if defined(TOML_IMPLEMENTATION) || TOML_ALL_INLINE || defined(__INTELLISENSE__)
|
||||
#undef TOML_IMPLEMENTATION
|
||||
#define TOML_IMPLEMENTATION 1
|
||||
#else
|
||||
#define TOML_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_API
|
||||
#define TOML_API
|
||||
#endif
|
||||
|
||||
#ifndef TOML_CHAR_8_STRINGS
|
||||
#define TOML_CHAR_8_STRINGS 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNRELEASED_FEATURES
|
||||
#define TOML_UNRELEASED_FEATURES 1
|
||||
#endif
|
||||
|
||||
#ifndef TOML_LARGE_FILES
|
||||
#define TOML_LARGE_FILES 0
|
||||
#endif
|
||||
|
||||
#ifndef TOML_UNDEF_MACROS
|
||||
#define TOML_UNDEF_MACROS 1
|
||||
#endif
|
||||
|
||||
//TOML_ASSERT
|
||||
#ifndef TOML_PARSER
|
||||
#define TOML_PARSER 1
|
||||
#endif
|
||||
// TOML_ASSERT
|
||||
|
||||
////////// COMPILER & ENVIRONMENT STUFF
|
||||
|
||||
@ -62,7 +56,7 @@
|
||||
#define TOML_POP_WARNINGS _Pragma("clang diagnostic pop")
|
||||
#define TOML_ASSUME(cond) __builtin_assume(cond)
|
||||
#define TOML_UNREACHABLE __builtin_unreachable()
|
||||
#define TOML_GNU_ATTR(attr) __attribute__((attr))
|
||||
#define TOML_GNU_ATTR(...) __attribute__((__VA_ARGS__))
|
||||
#if defined(_MSC_VER) // msvc compat mode
|
||||
#ifdef __has_declspec_attribute
|
||||
#if __has_declspec_attribute(novtable)
|
||||
@ -93,8 +87,8 @@
|
||||
#endif
|
||||
|
||||
//floating-point from_chars and to_chars are not implemented in any version of clang as of 1/1/2020
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 0
|
||||
#ifndef TOML_FLOAT_CHARCONV
|
||||
#define TOML_FLOAT_CHARCONV 0
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(__ICL))
|
||||
@ -132,7 +126,7 @@
|
||||
_Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
|
||||
#define TOML_POP_WARNINGS _Pragma("GCC diagnostic pop")
|
||||
#define TOML_GNU_ATTR(attr) __attribute__((attr))
|
||||
#define TOML_GNU_ATTR(...) __attribute__((__VA_ARGS__))
|
||||
#define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline
|
||||
#define TOML_NEVER_INLINE __attribute__((__noinline__))
|
||||
#define TOML_UNREACHABLE __builtin_unreachable()
|
||||
@ -150,8 +144,8 @@
|
||||
#define TOML_UNLIKELY
|
||||
|
||||
// floating-point from_chars and to_chars are not implemented in any version of gcc as of 1/1/2020
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 0
|
||||
#ifndef TOML_FLOAT_CHARCONV
|
||||
#define TOML_FLOAT_CHARCONV 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -160,9 +154,9 @@
|
||||
#define TOML_CPP_VERSION __cplusplus
|
||||
#endif
|
||||
#if TOML_CPP_VERSION < 201103L
|
||||
#error toml++ requires C++17 or higher. For a TOML parser supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml
|
||||
#error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml
|
||||
#elif TOML_CPP_VERSION < 201703L
|
||||
#error toml++ requires C++17 or higher. For a TOML parser supporting C++11 see https://github.com/skystrife/cpptoml
|
||||
#error toml++ requires C++17 or higher. For a TOML library supporting C++11 see https://github.com/skystrife/cpptoml
|
||||
#elif TOML_CPP_VERSION >= 202600L
|
||||
#define TOML_CPP 26
|
||||
#elif TOML_CPP_VERSION >= 202300L
|
||||
@ -194,17 +188,17 @@
|
||||
#ifndef TOML_DISABLE_INIT_WARNINGS
|
||||
#define TOML_DISABLE_INIT_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_INTEGER_CHARCONV
|
||||
#define TOML_INTEGER_CHARCONV 1
|
||||
#ifndef TOML_INT_CHARCONV
|
||||
#define TOML_INT_CHARCONV 1
|
||||
#endif
|
||||
#ifndef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_FLOATING_POINT_CHARCONV 1
|
||||
#ifndef TOML_FLOAT_CHARCONV
|
||||
#define TOML_FLOAT_CHARCONV 1
|
||||
#endif
|
||||
#if (TOML_INTEGER_CHARCONV || TOML_FLOATING_POINT_CHARCONV) && !__has_include(<charconv>)
|
||||
#undef TOML_INTEGER_CHARCONV
|
||||
#undef TOML_FLOATING_POINT_CHARCONV
|
||||
#define TOML_INTEGER_CHARCONV 0
|
||||
#define TOML_FLOATING_POINT_CHARCONV 0
|
||||
#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !__has_include(<charconv>)
|
||||
#undef TOML_INT_CHARCONV
|
||||
#undef TOML_FLOAT_CHARCONV
|
||||
#define TOML_INT_CHARCONV 0
|
||||
#define TOML_FLOAT_CHARCONV 0
|
||||
#endif
|
||||
#ifndef TOML_PUSH_WARNINGS
|
||||
#define TOML_PUSH_WARNINGS
|
||||
@ -219,7 +213,7 @@
|
||||
#define TOML_POP_WARNINGS
|
||||
#endif
|
||||
#ifndef TOML_GNU_ATTR
|
||||
#define TOML_GNU_ATTR(attr)
|
||||
#define TOML_GNU_ATTR(...)
|
||||
#endif
|
||||
#ifndef TOML_INTERFACE
|
||||
#define TOML_INTERFACE
|
||||
@ -280,12 +274,19 @@
|
||||
__VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); }
|
||||
#endif
|
||||
#if TOML_ALL_INLINE
|
||||
#define TOML_FUNC_EXTERNAL_LINKAGE inline
|
||||
#define TOML_EXTERNAL_LINKAGE inline
|
||||
#define TOML_INTERNAL_LINKAGE inline
|
||||
#define TOML_INTERNAL_NAMESPACE toml::impl
|
||||
#else
|
||||
#define TOML_FUNC_EXTERNAL_LINKAGE
|
||||
#define TOML_EXTERNAL_LINKAGE
|
||||
#define TOML_INTERNAL_LINKAGE static
|
||||
#define TOML_INTERNAL_NAMESPACE
|
||||
#endif
|
||||
|
||||
#include "toml_version.h"
|
||||
//#{{
|
||||
#define TOML_LIB_SINGLE_HEADER 0
|
||||
//#}}
|
||||
|
||||
#define TOML_MAKE_VERSION(maj, min, rev) \
|
||||
((maj) * 1000 + (min) * 25 + (rev))
|
||||
@ -326,9 +327,6 @@ TOML_DISABLE_ALL_WARNINGS
|
||||
#ifndef TOML_OPTIONAL_TYPE
|
||||
#include <optional>
|
||||
#endif
|
||||
#if TOML_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
#ifndef TOML_ASSERT
|
||||
#ifdef NDEBUG
|
||||
#define TOML_ASSERT(expr) (void)0
|
||||
@ -373,7 +371,9 @@ namespace toml
|
||||
using size_t = std::size_t;
|
||||
using ptrdiff_t = std::ptrdiff_t;
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
TOML_CONSTEVAL size_t operator"" _sz(unsigned long long n) noexcept
|
||||
{
|
||||
return static_cast<size_t>(n);
|
||||
@ -601,109 +601,7 @@ namespace toml
|
||||
source_path_ptr path;
|
||||
};
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_noex {
|
||||
#endif
|
||||
|
||||
/// \brief An error thrown/returned 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
|
||||
{
|
||||
private:
|
||||
std::string description_;
|
||||
source_region source_;
|
||||
|
||||
public:
|
||||
|
||||
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 } }
|
||||
{}
|
||||
|
||||
|
||||
/// \brief Returns a textual description of the error.
|
||||
[[nodiscard]]
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
/// \brief Returns the region of the source document responsible for the error.
|
||||
[[nodiscard]]
|
||||
const source_region& source() const noexcept
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_ex {
|
||||
#endif
|
||||
|
||||
class parse_error final
|
||||
: public std::runtime_error
|
||||
{
|
||||
private:
|
||||
source_region source_;
|
||||
|
||||
public:
|
||||
|
||||
TOML_NODISCARD_CTOR TOML_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, source_region&& src) noexcept
|
||||
: std::runtime_error{ desc },
|
||||
source_{ std::move(src) }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR TOML_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, const source_region& src) noexcept
|
||||
: parse_error{ desc, source_region{ src } }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR TOML_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, const source_position& position, const source_path_ptr& path = {}) noexcept
|
||||
: parse_error{ desc, source_region{ position, position, path } }
|
||||
{}
|
||||
|
||||
[[nodiscard]]
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
return std::string_view{ what() };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_region& source() const noexcept
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS
|
||||
} //end abi namespace for TOML_LARGE_FILES
|
||||
#endif
|
||||
}
|
||||
@ -725,7 +623,9 @@ namespace toml::impl
|
||||
inline constexpr bool is_one_of = is_one_of_<T, U...>::value;
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr std::underlying_type_t<T> unbox_enum(T val) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<T>>(val);
|
||||
@ -976,7 +876,7 @@ namespace toml
|
||||
/// Element [3] is: boolean
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, node_type rhs)
|
||||
{
|
||||
using underlying_t = std::underlying_type_t<node_type>;
|
||||
|
@ -85,7 +85,7 @@ namespace toml
|
||||
/// 1987-03-16
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
@ -178,7 +178,7 @@ namespace toml
|
||||
/// 10:20:34.5
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
@ -285,7 +285,7 @@ namespace toml
|
||||
/// -02:30
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const time_offset& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
@ -422,7 +422,7 @@ namespace toml
|
||||
/// 1987-03-16T10:20:34Z
|
||||
/// \eout
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const date_time& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs, lhs);
|
||||
|
@ -372,7 +372,7 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML.
|
||||
template <typename T, typename U>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
@ -384,21 +384,21 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, default_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const table& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const array& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
|
@ -2,9 +2,9 @@
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
//# {{
|
||||
#pragma once
|
||||
#include "toml_default_formatter.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
@ -16,7 +16,7 @@ namespace toml::impl
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
toml::string default_formatter_make_key_segment(const toml::string& str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
@ -63,7 +63,7 @@ namespace toml::impl
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
size_t default_formatter_inline_columns(const node& node) noexcept
|
||||
{
|
||||
switch (node.type())
|
||||
@ -138,7 +138,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool default_formatter_forces_multiline(const node& node, size_t starting_column_bias) noexcept
|
||||
{
|
||||
return (default_formatter_inline_columns(node) + starting_column_bias) > 120_sz;
|
||||
|
@ -2,16 +2,16 @@
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
//# {{
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
#if TOML_ALL_INLINE
|
||||
#error This header cannot not be included when TOML_ALL_INLINE is enabled.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#include <ostream>
|
||||
@ -48,7 +48,6 @@ namespace toml
|
||||
// various ostream operators
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const source_position&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const source_region&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const date&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const time&);
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
@ -77,23 +76,29 @@ namespace toml
|
||||
template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
|
||||
// parse() and parse_file()
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#if TOML_EXCEPTIONS
|
||||
inline namespace abi_parse_ex {
|
||||
#else
|
||||
inline namespace abi_parse_noex {
|
||||
#endif
|
||||
#endif
|
||||
template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS
|
||||
#endif
|
||||
}
|
||||
// parser machinery
|
||||
#if TOML_PARSER
|
||||
|
||||
#endif // !TOML_ALL_INLINE
|
||||
// parse error ostream
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
|
||||
// parse() and parse_file()
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#if TOML_EXCEPTIONS
|
||||
inline namespace abi_parse_ex {
|
||||
#else
|
||||
inline namespace abi_parse_noex {
|
||||
#endif
|
||||
#endif
|
||||
template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#endif // TOML_PARSER
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON.
|
||||
template <typename T, typename U>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>& rhs)
|
||||
{
|
||||
rhs.attach(lhs);
|
||||
@ -173,7 +173,7 @@ namespace toml
|
||||
|
||||
/// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
|
||||
template <typename T, typename U>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<T>& operator << (std::basic_ostream<T>& lhs, json_formatter<U>&& rhs)
|
||||
{
|
||||
return lhs << rhs; //as lvalue
|
||||
|
@ -4,13 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
#include "toml_node.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
namespace toml
|
||||
{
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node::node(node && other) noexcept
|
||||
: source_{ std::move(other.source_) }
|
||||
{
|
||||
@ -18,7 +20,7 @@ namespace toml
|
||||
other.source_.end = {};
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node & node::operator= (node && rhs) noexcept
|
||||
{
|
||||
source_ = std::move(rhs.source_);
|
||||
@ -27,36 +29,36 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_string() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_integer() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_floating_point() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_number() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_boolean() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_date() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_time() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_date_time() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool node::is_array_of_tables() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_string() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_integer() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_floating_point() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_number() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_boolean() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_date() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_time() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_date_time() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool node::is_array_of_tables() const noexcept { return false; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table* node::as_table() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE array* node::as_array() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<string>* node::as_string() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<int64_t>* node::as_integer() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<double>* node::as_floating_point() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<bool>* node::as_boolean() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<date>* node::as_date() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<time>* node::as_time() noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE value<date_time>* node::as_date_time() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE table* node::as_table() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE array* node::as_array() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<string>* node::as_string() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<int64_t>* node::as_integer() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<double>* node::as_floating_point() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<bool>* node::as_boolean() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<date>* node::as_date() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<time>* node::as_time() noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE value<date_time>* node::as_date_time() noexcept { return nullptr; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const table* node::as_table() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const array* node::as_array() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<string>* node::as_string() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<int64_t>* node::as_integer() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<double>* node::as_floating_point() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<bool>* node::as_boolean() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<date>* node::as_date() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<time>* node::as_time() const noexcept { return nullptr; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const value<date_time>* node::as_date_time() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const table* node::as_table() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const array* node::as_array() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<string>* node::as_string() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<int64_t>* node::as_integer() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<double>* node::as_floating_point() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<bool>* node::as_boolean() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<date>* node::as_date() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<time>* node::as_time() const noexcept { return nullptr; }
|
||||
TOML_EXTERNAL_LINKAGE const value<date_time>* node::as_date_time() const noexcept { return nullptr; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const source_region& node::source() const noexcept { return source_; }
|
||||
TOML_EXTERNAL_LINKAGE const source_region& node::source() const noexcept { return source_; }
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,7 @@ namespace toml
|
||||
|
||||
/// \brief Prints the viewed node out to a stream.
|
||||
template <typename Char, typename T>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const node_view<T>& nv)
|
||||
{
|
||||
if (nv.node_)
|
||||
|
173
include/toml++/toml_parse_error.h
Normal file
173
include/toml++/toml_parse_error.h
Normal file
@ -0,0 +1,173 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
//# {{
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#if TOML_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#if TOML_LARGE_FILES
|
||||
inline namespace abi_lf {
|
||||
#else
|
||||
inline namespace abi_sf {
|
||||
#endif
|
||||
#if TOML_EXCEPTIONS
|
||||
inline namespace abi_ex {
|
||||
#else
|
||||
inline namespace abi_noex {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(DOXYGEN) || !TOML_EXCEPTIONS
|
||||
|
||||
/// \brief An error thrown/returned 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
|
||||
{
|
||||
private:
|
||||
std::string description_;
|
||||
source_region source_;
|
||||
|
||||
public:
|
||||
|
||||
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 } }
|
||||
{}
|
||||
|
||||
|
||||
/// \brief Returns a textual description of the error.
|
||||
[[nodiscard]]
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
/// \brief Returns the region of the source document responsible for the error.
|
||||
[[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_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, source_region&& src) noexcept
|
||||
: std::runtime_error{ desc },
|
||||
source_{ std::move(src) }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, const source_region& src) noexcept
|
||||
: parse_error{ desc, source_region{ src } }
|
||||
{}
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_GNU_ATTR(nonnull)
|
||||
parse_error(const char* desc, const source_position& position, const source_path_ptr& path = {}) noexcept
|
||||
: parse_error{ desc, source_region{ position, position, path } }
|
||||
{}
|
||||
|
||||
[[nodiscard]]
|
||||
std::string_view description() const noexcept
|
||||
{
|
||||
return std::string_view{ what() };
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_region& source() const noexcept
|
||||
{
|
||||
return source_;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS
|
||||
} //end abi namespace for TOML_LARGE_FILES
|
||||
#endif
|
||||
|
||||
/// \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 << std::endl;
|
||||
/// }
|
||||
/// \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>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
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 !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS
|
@ -3,8 +3,14 @@
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
//# {{
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
#include "toml_table.h"
|
||||
#include "toml_utf8.h"
|
||||
#include "toml_utf8_streams.h"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
@ -410,7 +416,7 @@ namespace toml
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::basic_istream<Char>& doc, std::string_view source_path = {}) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
@ -444,7 +450,7 @@ namespace toml
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::basic_istream<Char>& doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
@ -476,7 +482,7 @@ namespace toml
|
||||
/// does not transitively include it for you).
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse_file(std::basic_string_view<Char> file_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
|
@ -2,25 +2,152 @@
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
//# {{
|
||||
#pragma once
|
||||
#include "toml_parser.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
//# }}
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#include <cmath>
|
||||
#if TOML_INTEGER_CHARCONV || TOML_FLOATING_POINT_CHARCONV
|
||||
#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
|
||||
#include <charconv>
|
||||
#endif
|
||||
#if !TOML_INTEGER_CHARCONV || !TOML_FLOATING_POINT_CHARCONV
|
||||
#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV
|
||||
#include <sstream>
|
||||
#endif
|
||||
#if !TOML_ALL_INLINE
|
||||
using namespace std::string_view_literals;
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
namespace TOML_INTERNAL_NAMESPACE
|
||||
{
|
||||
template <uint64_t> struct parse_integer_traits;
|
||||
template <> struct parse_integer_traits<2> final
|
||||
{
|
||||
static constexpr auto qualifier = "binary"sv;
|
||||
static constexpr auto is_digit = ::toml::impl::is_binary_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 63;
|
||||
static constexpr char32_t prefix_codepoint = U'b';
|
||||
static constexpr char prefix = 'b';
|
||||
};
|
||||
template <> struct parse_integer_traits<8> final
|
||||
{
|
||||
static constexpr auto qualifier = "octal"sv;
|
||||
static constexpr auto is_digit = ::toml::impl::is_octal_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 21; // strlen("777777777777777777777")
|
||||
static constexpr char32_t prefix_codepoint = U'o';
|
||||
static constexpr char prefix = 'o';
|
||||
};
|
||||
template <> struct parse_integer_traits<10> final
|
||||
{
|
||||
static constexpr auto qualifier = "decimal"sv;
|
||||
static constexpr auto is_digit = ::toml::impl::is_decimal_digit;
|
||||
static constexpr auto is_signed = true;
|
||||
static constexpr auto buffer_length = 19; //strlen("9223372036854775807")
|
||||
};
|
||||
template <> struct parse_integer_traits<16> final
|
||||
{
|
||||
static constexpr auto qualifier = "hexadecimal"sv;
|
||||
static constexpr auto is_digit = ::toml::impl::is_hexadecimal_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 16; //strlen("7FFFFFFFFFFFFFFF")
|
||||
static constexpr char32_t prefix_codepoint = U'x';
|
||||
static constexpr char prefix = 'x';
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TOML_INTERNAL_LINKAGE
|
||||
TOML_GNU_ATTR(nonnull)
|
||||
void concatenate(char*& write_pos, char* buf_end, const T& arg) noexcept
|
||||
{
|
||||
using namespace ::toml;
|
||||
using namespace ::toml::impl;
|
||||
|
||||
static_assert(!is_one_of<std::decay_t<T>, const char*, char*>);
|
||||
|
||||
if (write_pos >= buf_end)
|
||||
return;
|
||||
const auto max_chars = static_cast<size_t>(buf_end - write_pos);
|
||||
|
||||
using arg_t = remove_cvref_t<T>;
|
||||
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
|
||||
{
|
||||
const auto len = max_chars < arg.length() ? max_chars : arg.length();
|
||||
std::memcpy(write_pos, arg.data(), len);
|
||||
write_pos += len;
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, char>)
|
||||
{
|
||||
*write_pos++ = arg;
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
|
||||
{
|
||||
string_view cp_view;
|
||||
if (arg.value <= U'\x1F') TOML_UNLIKELY
|
||||
cp_view = low_character_escape_table[arg.value];
|
||||
else if (arg.value == U'\x7F') TOML_UNLIKELY
|
||||
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
|
||||
else
|
||||
cp_view = arg.template as_view<string_char>();
|
||||
|
||||
if (cp_view.length() <= max_chars)
|
||||
concatenate(write_pos, buf_end, cp_view);
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, bool>)
|
||||
{
|
||||
concatenate(write_pos, buf_end, arg ? "true"sv : "false"sv);
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, node_type>)
|
||||
{
|
||||
concatenate(
|
||||
write_pos,
|
||||
buf_end,
|
||||
impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(arg)]
|
||||
);
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<arg_t>)
|
||||
{
|
||||
#if TOML_FLOAT_CHARCONV
|
||||
{
|
||||
const auto result = std::to_chars(write_pos, buf_end, arg);
|
||||
write_pos = result.ptr;
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
|
||||
ss << arg;
|
||||
concatenate(write_pos, buf_end, std::move(ss).str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_integral_v<arg_t>)
|
||||
{
|
||||
#if TOML_INT_CHARCONV
|
||||
{
|
||||
const auto result = std::to_chars(write_pos, buf_end, arg);
|
||||
write_pos = result.ptr;
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
using cast_type = std::conditional_t<std::is_signed_v<arg_t>, int64_t, uint64_t>;
|
||||
ss << static_cast<cast_type>(arg);
|
||||
concatenate(write_pos, buf_end, std::move(ss).str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
@ -37,41 +164,11 @@ namespace toml::impl
|
||||
#define TOML_NORETURN [[noreturn]]
|
||||
#endif
|
||||
|
||||
template <uint64_t> struct parse_integer_traits;
|
||||
template <> struct parse_integer_traits<2> final
|
||||
{
|
||||
static constexpr auto qualifier = "binary"sv;
|
||||
static constexpr auto is_digit = is_binary_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 63;
|
||||
static constexpr char32_t prefix_codepoint = U'b';
|
||||
static constexpr char prefix = 'b';
|
||||
};
|
||||
template <> struct parse_integer_traits<8> final
|
||||
{
|
||||
static constexpr auto qualifier = "octal"sv;
|
||||
static constexpr auto is_digit = is_octal_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 21; // strlen("777777777777777777777")
|
||||
static constexpr char32_t prefix_codepoint = U'o';
|
||||
static constexpr char prefix = 'o';
|
||||
};
|
||||
template <> struct parse_integer_traits<10> final
|
||||
{
|
||||
static constexpr auto qualifier = "decimal"sv;
|
||||
static constexpr auto is_digit = is_decimal_digit;
|
||||
static constexpr auto is_signed = true;
|
||||
static constexpr auto buffer_length = 19; //strlen("9223372036854775807")
|
||||
};
|
||||
template <> struct parse_integer_traits<16> final
|
||||
{
|
||||
static constexpr auto qualifier = "hexadecimal"sv;
|
||||
static constexpr auto is_digit = is_hexadecimal_digit;
|
||||
static constexpr auto is_signed = false;
|
||||
static constexpr auto buffer_length = 16; //strlen("7FFFFFFFFFFFFFFF")
|
||||
static constexpr char32_t prefix_codepoint = U'x';
|
||||
static constexpr char prefix = 'x';
|
||||
};
|
||||
#ifdef NDEBUG
|
||||
#define TOML_NOT_EOF TOML_ASSUME(cp != nullptr)
|
||||
#else
|
||||
#define TOML_NOT_EOF TOML_ASSERT(cp != nullptr)
|
||||
#endif
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#if TOML_EXCEPTIONS
|
||||
@ -80,11 +177,6 @@ namespace toml::impl
|
||||
inline namespace abi_impl_noex {
|
||||
#endif
|
||||
#endif
|
||||
#ifdef NDEBUG
|
||||
#define TOML_NOT_EOF TOML_ASSUME(cp != nullptr)
|
||||
#else
|
||||
#define TOML_NOT_EOF TOML_ASSERT(cp != nullptr)
|
||||
#endif
|
||||
|
||||
class parser final
|
||||
{
|
||||
@ -110,88 +202,6 @@ namespace toml::impl
|
||||
return { prev_pos.line, static_cast<source_index>(prev_pos.column + fallback_offset) };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NEVER_INLINE
|
||||
static void abort_with_error_concatenate(char*& write_pos, char* buf_end, const T& arg) noexcept
|
||||
{
|
||||
static_assert(!is_one_of<std::decay_t<T>, const char*, char*>);
|
||||
|
||||
if (write_pos >= buf_end)
|
||||
return;
|
||||
const auto max_chars = static_cast<size_t>(buf_end - write_pos);
|
||||
|
||||
using arg_t = remove_cvref_t<T>;
|
||||
if constexpr (std::is_same_v<arg_t, std::string_view> || std::is_same_v<arg_t, std::string>)
|
||||
{
|
||||
const auto len = max_chars < arg.length() ? max_chars : arg.length();
|
||||
std::memcpy(write_pos, arg.data(), len);
|
||||
write_pos += len;
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, char>)
|
||||
{
|
||||
*write_pos++ = arg;
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
|
||||
{
|
||||
toml::string_view cp_view;
|
||||
if (arg.value <= U'\x1F') TOML_UNLIKELY
|
||||
cp_view = low_character_escape_table[arg.value];
|
||||
else if (arg.value == U'\x7F') TOML_UNLIKELY
|
||||
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
|
||||
else
|
||||
cp_view = arg.template as_view<string_char>();
|
||||
|
||||
if (cp_view.length() <= max_chars)
|
||||
abort_with_error_concatenate(write_pos, buf_end, cp_view);
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, bool>)
|
||||
{
|
||||
abort_with_error_concatenate(write_pos, buf_end, arg ? "true"sv : "false"sv);
|
||||
}
|
||||
else if constexpr (std::is_same_v<arg_t, node_type>)
|
||||
{
|
||||
abort_with_error_concatenate(
|
||||
write_pos,
|
||||
buf_end,
|
||||
impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(arg)]
|
||||
);
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<arg_t>)
|
||||
{
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
{
|
||||
const auto result = std::to_chars(write_pos, buf_end, arg);
|
||||
write_pos = result.ptr;
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(std::numeric_limits<arg_t>::digits10 + 1);
|
||||
ss << arg;
|
||||
abort_with_error_concatenate(write_pos, buf_end, std::move(ss).str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_integral_v<arg_t>)
|
||||
{
|
||||
#if TOML_INTEGER_CHARCONV
|
||||
{
|
||||
const auto result = std::to_chars(write_pos, buf_end, arg);
|
||||
write_pos = result.ptr;
|
||||
}
|
||||
#else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
using cast_type = std::conditional_t<std::is_signed_v<arg_t>, int64_t, uint64_t>;
|
||||
ss << static_cast<cast_type>(arg);
|
||||
abort_with_error_concatenate(write_pos, buf_end, std::move(ss).str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
TOML_NORETURN
|
||||
TOML_NEVER_INLINE
|
||||
@ -207,7 +217,7 @@ namespace toml::impl
|
||||
char buf[buf_size];
|
||||
auto write_pos = buf;
|
||||
const auto max_write_pos = buf + (buf_size - 1_sz); //allow for null terminator
|
||||
(abort_with_error_concatenate(write_pos, max_write_pos, args), ...);
|
||||
(concatenate(write_pos, max_write_pos, args), ...);
|
||||
*write_pos = '\0';
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ERROR(buf, current_position(1), reader.source_path());
|
||||
@ -959,7 +969,7 @@ namespace toml::impl
|
||||
{
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_NOT_EOF;
|
||||
TOML_ASSERT(is_match(*cp, U'+', U'-') || is_decimal_digit(*cp));
|
||||
TOML_ASSERT(is_match(*cp, U'+', U'-', U'.') || is_decimal_digit(*cp));
|
||||
|
||||
const auto eof_check = [this]() TOML_MAY_THROW
|
||||
{
|
||||
@ -1091,7 +1101,7 @@ namespace toml::impl
|
||||
|
||||
// convert to double
|
||||
double result;
|
||||
#if TOML_FLOATING_POINT_CHARCONV
|
||||
#if TOML_FLOAT_CHARCONV
|
||||
{
|
||||
auto fc_result = std::from_chars(chars, chars + length, result);
|
||||
switch (fc_result.ec)
|
||||
@ -1999,16 +2009,8 @@ namespace toml::impl
|
||||
// starting with value types that can be detected
|
||||
// unambiguously from just one character.
|
||||
|
||||
// strings
|
||||
if (is_string_delimiter(*cp))
|
||||
val = std::make_unique<value<string>>(parse_string());
|
||||
|
||||
// bools
|
||||
else if (is_match(*cp, U't', U'f', U'T', U'F'))
|
||||
val = std::make_unique<value<bool>>(parse_bool());
|
||||
|
||||
// arrays
|
||||
else if (*cp == U'[')
|
||||
if (*cp == U'[')
|
||||
{
|
||||
val = parse_array();
|
||||
if constexpr (!TOML_LANG_AT_LEAST(1, 0, 0)) // toml/issues/665 (heterogeneous arrays)
|
||||
@ -2026,6 +2028,18 @@ namespace toml::impl
|
||||
else if (*cp == U'{')
|
||||
val = parse_inline_table();
|
||||
|
||||
// floats beginning with '.'
|
||||
else if (*cp == U'.')
|
||||
val = std::make_unique<value<double>>(parse_float());
|
||||
|
||||
// strings
|
||||
else if (is_string_delimiter(*cp))
|
||||
val = std::make_unique<value<string>>(parse_string());
|
||||
|
||||
// bools
|
||||
else if (is_match(*cp, U't', U'f', U'T', U'F'))
|
||||
val = std::make_unique<value<bool>>(parse_bool());
|
||||
|
||||
// inf or nan
|
||||
else if (is_match(*cp, U'i', U'n', U'I', U'N'))
|
||||
val = std::make_unique<value<double>>(parse_inf_or_nan());
|
||||
@ -2062,13 +2076,25 @@ namespace toml::impl
|
||||
// Q: "why not make these real values in the enum??"
|
||||
// A: because the visual studio debugger stops treating them as a set of flags if you add
|
||||
// non-pow2 values, making them much harder to debug.
|
||||
#define toml_signs_msk (has_plus | has_minus)
|
||||
#define toml_bzero_msk (begins_zero | has_digits)
|
||||
#define toml_bdigit_msk (begins_digit | has_digits)
|
||||
#define signs_msk (has_plus | has_minus)
|
||||
#define bzero_msk (begins_zero | has_digits)
|
||||
#define bdigit_msk (begins_digit | has_digits)
|
||||
};
|
||||
value_traits traits = has_nothing;
|
||||
const auto has_trait = [&](auto t) noexcept { return (traits & t) != has_nothing; };
|
||||
const auto has_any = [&](auto t) noexcept { return (traits & t) != has_nothing; };
|
||||
const auto has_none = [&](auto t) noexcept { return (traits & t) == has_nothing; };
|
||||
const auto add_trait = [&](auto t) noexcept { traits = static_cast<value_traits>(traits | t); };
|
||||
|
||||
// examine the first character to get the 'begins with' traits
|
||||
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
||||
if (is_decimal_digit(*cp))
|
||||
add_trait(*cp == U'0' ? begins_zero : begins_digit);
|
||||
else if (is_match(*cp, U'+', U'-'))
|
||||
add_trait(begins_sign);
|
||||
else
|
||||
break;
|
||||
|
||||
// scan the rest of the value to determine the remaining traits
|
||||
char32_t chars[utf8_buffered_reader::max_history_length];
|
||||
size_t char_count = {}, advance_count = {};
|
||||
bool eof_while_scanning = false;
|
||||
@ -2089,32 +2115,34 @@ namespace toml::impl
|
||||
{
|
||||
case U'B': [[fallthrough]];
|
||||
case U'b':
|
||||
if (chars[0] == U'0' && char_count == 2_sz)
|
||||
if (char_count == 2_sz && has_any(begins_zero))
|
||||
add_trait(has_b);
|
||||
break;
|
||||
|
||||
case U'E': [[fallthrough]];
|
||||
case U'e':
|
||||
if (char_count > 1_sz && !has_trait(has_b | has_o | has_p | has_x))
|
||||
if (char_count > 1_sz
|
||||
&& has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon)
|
||||
&& (has_none(has_plus | has_minus) || has_any(begins_sign)))
|
||||
add_trait(has_e);
|
||||
break;
|
||||
|
||||
case U'O': [[fallthrough]];
|
||||
case U'o':
|
||||
if (chars[0] == U'0' && char_count == 2_sz)
|
||||
if (char_count == 2_sz && has_any(begins_zero))
|
||||
add_trait(has_o);
|
||||
break;
|
||||
|
||||
case U'P': [[fallthrough]];
|
||||
case U'p':
|
||||
if (has_trait(has_x))
|
||||
if (has_any(has_x))
|
||||
add_trait(has_p);
|
||||
break;
|
||||
|
||||
case U'X': [[fallthrough]];
|
||||
case U'x':
|
||||
if ((chars[0] == U'0' && char_count == 2_sz)
|
||||
|| (is_match(chars[0], U'-', U'+') && chars[1] == U'0' && char_count == 3_sz))
|
||||
if ((char_count == 2_sz && has_any(begins_zero))
|
||||
|| (char_count == 3_sz && has_any(begins_sign) && chars[1] == U'0'))
|
||||
add_trait(has_x);
|
||||
break;
|
||||
|
||||
@ -2130,6 +2158,7 @@ namespace toml::impl
|
||||
add_trait(has_digits);
|
||||
}
|
||||
}
|
||||
|
||||
advance();
|
||||
advance_count++;
|
||||
TOML_ERROR_CHECK();
|
||||
@ -2140,7 +2169,7 @@ namespace toml::impl
|
||||
|
||||
// force further scanning if this could have been a date-time with a space instead of a T
|
||||
if (char_count == 10_sz
|
||||
&& traits == (has_digits | has_minus)
|
||||
&& traits == (bdigit_msk | has_minus)
|
||||
&& chars[4] == U'-'
|
||||
&& chars[7] == U'-'
|
||||
&& cp
|
||||
@ -2190,7 +2219,7 @@ namespace toml::impl
|
||||
// the only valid value type is an integer.
|
||||
if (char_count == 1_sz)
|
||||
{
|
||||
if (traits == has_digits)
|
||||
if (has_any(begins_zero | begins_digit))
|
||||
{
|
||||
val = std::make_unique<value<int64_t>>(static_cast<int64_t>(chars[0] - U'0'));
|
||||
advance(); //skip the digit
|
||||
@ -2207,50 +2236,26 @@ namespace toml::impl
|
||||
|
||||
// now things that can be identified from two or more characters
|
||||
TOML_ERROR_CHECK({});
|
||||
TOML_ASSERT(char_count >= 2_sz);
|
||||
TOML_ASSUME(char_count >= 2_sz);
|
||||
|
||||
// slightly deeper trait invariant resolution.
|
||||
// some 'fuzzy matching' is done here where there's no ambiguity, since that allows the specific
|
||||
// do some 'fuzzy matching' where there's no ambiguity, since that allows the specific
|
||||
// typed parse functions to take over and show better diagnostics if there's an issue
|
||||
// (as opposed to the fallback "could not determine type" message)
|
||||
if (is_decimal_digit(chars[0]))
|
||||
{
|
||||
if (chars[0] == U'0')
|
||||
{
|
||||
// hex integers and floats
|
||||
if (has_trait(has_x))
|
||||
{
|
||||
if (has_trait(has_p))
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
else
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<16>());
|
||||
}
|
||||
|
||||
// octal integers
|
||||
else if (has_trait(has_o))
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<8>());
|
||||
|
||||
// binary integers
|
||||
else if (has_trait(has_b))
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<2>());
|
||||
|
||||
else
|
||||
add_trait(begins_zero);
|
||||
}
|
||||
else
|
||||
add_trait(begins_digit);
|
||||
|
||||
if (!val)
|
||||
{
|
||||
// simple floats (e.g. 1.0, 1e1)
|
||||
if (is_match(chars[1], U'.', U'e', U'E'))
|
||||
val = std::make_unique<value<double>>(parse_float());
|
||||
}
|
||||
}
|
||||
else if (is_match(chars[0], U'+', U'-'))
|
||||
if (has_any(has_p))
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
else if (has_any(has_x))
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<16>());
|
||||
else if (has_any(has_o))
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<8>());
|
||||
else if (has_any(has_b))
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<2>());
|
||||
else if (has_any(has_e)
|
||||
|| (has_any(begins_zero | begins_digit) && chars[1] == U'.'))
|
||||
val = std::make_unique<value<double>>(parse_float());
|
||||
else if (has_any(begins_sign))
|
||||
{
|
||||
// single-digit signed integers
|
||||
if (char_count == 2_sz && has_trait(has_digits))
|
||||
if (char_count == 2_sz && has_any(has_digits))
|
||||
{
|
||||
val = std::make_unique<value<int64_t>>(
|
||||
static_cast<int64_t>(chars[1] - U'0')
|
||||
@ -2261,24 +2266,13 @@ namespace toml::impl
|
||||
break;
|
||||
}
|
||||
|
||||
// simple signed floats (e.g. +1.0, -1e1)
|
||||
else if (is_decimal_digit(chars[1]) && is_match(chars[2], U'.', U'e', U'E'))
|
||||
// simple signed floats (e.g. +1.0)
|
||||
if (is_decimal_digit(chars[1]) && chars[2] == U'.')
|
||||
val = std::make_unique<value<double>>(parse_float());
|
||||
|
||||
// signed hexfloats (e.g. +1.0, -1e1)
|
||||
// (hex integers cannot be signed in TOML)
|
||||
else if (has_trait(has_x))
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
|
||||
// signed infinity or nan
|
||||
else if (is_match(chars[1], U'i', U'n', U'I', U'N'))
|
||||
{
|
||||
val = std::make_unique<value<double>>(parse_inf_or_nan());
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
add_trait(begins_sign);
|
||||
}
|
||||
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -2293,13 +2287,13 @@ namespace toml::impl
|
||||
{
|
||||
//=================== binary integers
|
||||
// 0b10
|
||||
case toml_bzero_msk | has_b:
|
||||
case bzero_msk | has_b:
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<2>());
|
||||
break;
|
||||
|
||||
//=================== octal integers
|
||||
// 0o10
|
||||
case toml_bzero_msk | has_o:
|
||||
case bzero_msk | has_o:
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<8>());
|
||||
break;
|
||||
|
||||
@ -2308,8 +2302,8 @@ namespace toml::impl
|
||||
// 10
|
||||
// +10
|
||||
// -10
|
||||
case toml_bzero_msk: [[fallthrough]];
|
||||
case toml_bdigit_msk: [[fallthrough]];
|
||||
case bzero_msk: [[fallthrough]];
|
||||
case bdigit_msk: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_minus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_plus:
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<10>());
|
||||
@ -2317,7 +2311,7 @@ namespace toml::impl
|
||||
|
||||
//=================== hexadecimal integers
|
||||
// 0x10
|
||||
case toml_bzero_msk | has_x:
|
||||
case bzero_msk | has_x:
|
||||
val = std::make_unique<value<int64_t>>(parse_integer<16>());
|
||||
break;
|
||||
|
||||
@ -2329,13 +2323,13 @@ namespace toml::impl
|
||||
// 0.0e1
|
||||
// 0.0e-1
|
||||
// 0.0e+1
|
||||
case toml_bzero_msk | has_e: [[fallthrough]];
|
||||
case toml_bzero_msk | has_e | has_minus: [[fallthrough]];
|
||||
case toml_bzero_msk | has_e | has_plus: [[fallthrough]];
|
||||
case toml_bzero_msk | has_dot: [[fallthrough]];
|
||||
case toml_bzero_msk | has_dot | has_e: [[fallthrough]];
|
||||
case toml_bzero_msk | has_dot | has_e | has_minus: [[fallthrough]];
|
||||
case toml_bzero_msk | has_dot | has_e | has_plus: [[fallthrough]];
|
||||
case bzero_msk | has_e: [[fallthrough]];
|
||||
case bzero_msk | has_e | has_minus: [[fallthrough]];
|
||||
case bzero_msk | has_e | has_plus: [[fallthrough]];
|
||||
case bzero_msk | has_dot: [[fallthrough]];
|
||||
case bzero_msk | has_dot | has_e: [[fallthrough]];
|
||||
case bzero_msk | has_dot | has_e | has_minus: [[fallthrough]];
|
||||
case bzero_msk | has_dot | has_e | has_plus: [[fallthrough]];
|
||||
// 1e1
|
||||
// 1e-1
|
||||
// 1e+1
|
||||
@ -2343,13 +2337,13 @@ namespace toml::impl
|
||||
// 1.0e1
|
||||
// 1.0e-1
|
||||
// 1.0e+1
|
||||
case toml_bdigit_msk | has_e: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_e | has_minus: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_e | has_plus: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_dot: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_dot | has_e: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_dot | has_e | has_minus: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_dot | has_e | has_plus: [[fallthrough]];
|
||||
case bdigit_msk | has_e: [[fallthrough]];
|
||||
case bdigit_msk | has_e | has_minus: [[fallthrough]];
|
||||
case bdigit_msk | has_e | has_plus: [[fallthrough]];
|
||||
case bdigit_msk | has_dot: [[fallthrough]];
|
||||
case bdigit_msk | has_dot | has_e: [[fallthrough]];
|
||||
case bdigit_msk | has_dot | has_e | has_minus: [[fallthrough]];
|
||||
case bdigit_msk | has_dot | has_e | has_plus: [[fallthrough]];
|
||||
// +1e1
|
||||
// +1.0
|
||||
// +1.0e1
|
||||
@ -2359,7 +2353,7 @@ namespace toml::impl
|
||||
case begins_sign | has_digits | has_e | has_plus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_plus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_e | has_plus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_e | toml_signs_msk: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_e | signs_msk: [[fallthrough]];
|
||||
// -1e1
|
||||
// -1e+1
|
||||
// +1e-1
|
||||
@ -2367,7 +2361,7 @@ namespace toml::impl
|
||||
// -1.0e1
|
||||
// -1.0e-1
|
||||
case begins_sign | has_digits | has_e | has_minus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_e | toml_signs_msk: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_e | signs_msk: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_minus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_dot | has_e | has_minus:
|
||||
val = std::make_unique<value<double>>(parse_float());
|
||||
@ -2377,9 +2371,9 @@ namespace toml::impl
|
||||
// 0x10p0
|
||||
// 0x10p-0
|
||||
// 0x10p+0
|
||||
case toml_bzero_msk | has_x | has_p: [[fallthrough]];
|
||||
case toml_bzero_msk | has_x | has_p | has_minus: [[fallthrough]];
|
||||
case toml_bzero_msk | has_x | has_p | has_plus: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_p: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_p | has_minus: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_p | has_plus: [[fallthrough]];
|
||||
// -0x10p0
|
||||
// -0x10p-0
|
||||
// +0x10p0
|
||||
@ -2388,13 +2382,13 @@ namespace toml::impl
|
||||
// +0x10p-0
|
||||
case begins_sign | has_digits | has_x | has_p | has_minus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_x | has_p | has_plus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_x | has_p | toml_signs_msk: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_x | has_p | signs_msk: [[fallthrough]];
|
||||
// 0x10.1p0
|
||||
// 0x10.1p-0
|
||||
// 0x10.1p+0
|
||||
case toml_bzero_msk | has_x | has_dot | has_p: [[fallthrough]];
|
||||
case toml_bzero_msk | has_x | has_dot | has_p | has_minus: [[fallthrough]];
|
||||
case toml_bzero_msk | has_x | has_dot | has_p | has_plus: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_dot | has_p: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_dot | has_p | has_minus: [[fallthrough]];
|
||||
case bzero_msk | has_x | has_dot | has_p | has_plus: [[fallthrough]];
|
||||
// -0x10.1p0
|
||||
// -0x10.1p-0
|
||||
// +0x10.1p0
|
||||
@ -2403,7 +2397,7 @@ namespace toml::impl
|
||||
// +0x10.1p-0
|
||||
case begins_sign | has_digits | has_x | has_dot | has_p | has_minus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_x | has_dot | has_p | has_plus: [[fallthrough]];
|
||||
case begins_sign | has_digits | has_x | has_dot | has_p | toml_signs_msk:
|
||||
case begins_sign | has_digits | has_x | has_dot | has_p | signs_msk:
|
||||
val = std::make_unique<value<double>>(parse_hex_float());
|
||||
break;
|
||||
|
||||
@ -2411,17 +2405,17 @@ namespace toml::impl
|
||||
// HH:MM
|
||||
// HH:MM:SS
|
||||
// HH:MM:SS.FFFFFF
|
||||
case toml_bzero_msk | has_colon: [[fallthrough]];
|
||||
case toml_bzero_msk | has_colon | has_dot: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_colon: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_colon | has_dot:
|
||||
case bzero_msk | has_colon: [[fallthrough]];
|
||||
case bzero_msk | has_colon | has_dot: [[fallthrough]];
|
||||
case bdigit_msk | has_colon: [[fallthrough]];
|
||||
case bdigit_msk | has_colon | has_dot:
|
||||
val = std::make_unique<value<time>>(parse_time());
|
||||
break;
|
||||
|
||||
//=================== local dates
|
||||
// YYYY-MM-DD
|
||||
case toml_bzero_msk | has_minus: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_minus:
|
||||
case bzero_msk | has_minus: [[fallthrough]];
|
||||
case bdigit_msk | has_minus:
|
||||
val = std::make_unique<value<date>>(parse_date());
|
||||
break;
|
||||
|
||||
@ -2438,37 +2432,37 @@ namespace toml::impl
|
||||
// YYYY-MM-DD HH:MM:SS
|
||||
// YYYY-MM-DD HH:MM:SS-HH:MM
|
||||
// YYYY-MM-DD HH:MM:SS+HH:MM
|
||||
case toml_bzero_msk | has_minus | has_colon | has_t: [[fallthrough]];
|
||||
case toml_bzero_msk | toml_signs_msk | has_colon | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_minus | has_colon | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | toml_signs_msk | has_colon | has_t: [[fallthrough]];
|
||||
case bzero_msk | has_minus | has_colon | has_t: [[fallthrough]];
|
||||
case bzero_msk | signs_msk | has_colon | has_t: [[fallthrough]];
|
||||
case bdigit_msk | has_minus | has_colon | has_t: [[fallthrough]];
|
||||
case bdigit_msk | signs_msk | has_colon | has_t: [[fallthrough]];
|
||||
// YYYY-MM-DDTHH:MM:SS.FFFFFF
|
||||
// YYYY-MM-DDTHH:MM:SS.FFFFFF-HH:MM
|
||||
// YYYY-MM-DDTHH:MM:SS.FFFFFF+HH:MM
|
||||
// YYYY-MM-DD HH:MM:SS.FFFFFF
|
||||
// YYYY-MM-DD HH:MM:SS.FFFFFF-HH:MM
|
||||
// YYYY-MM-DD HH:MM:SS.FFFFFF+HH:MM
|
||||
case toml_bzero_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case toml_bzero_msk | toml_signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | toml_signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case bzero_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case bzero_msk | signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case bdigit_msk | has_minus | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
case bdigit_msk | signs_msk | has_colon | has_dot | has_t: [[fallthrough]];
|
||||
// YYYY-MM-DDTHH:MMZ
|
||||
// YYYY-MM-DD HH:MMZ
|
||||
// YYYY-MM-DDTHH:MM:SSZ
|
||||
// YYYY-MM-DD HH:MM:SSZ
|
||||
// YYYY-MM-DDTHH:MM:SS.FFFFFFZ
|
||||
// YYYY-MM-DD HH:MM:SS.FFFFFFZ
|
||||
case toml_bzero_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
|
||||
case toml_bzero_msk | has_minus | has_colon | has_dot | has_z | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
|
||||
case toml_bdigit_msk | has_minus | has_colon | has_dot | has_z | has_t:
|
||||
case bzero_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
|
||||
case bzero_msk | has_minus | has_colon | has_dot | has_z | has_t: [[fallthrough]];
|
||||
case bdigit_msk | has_minus | has_colon | has_z | has_t: [[fallthrough]];
|
||||
case bdigit_msk | has_minus | has_colon | has_dot | has_z | has_t:
|
||||
val = std::make_unique<value<date_time>>(parse_date_time());
|
||||
break;
|
||||
}
|
||||
|
||||
#undef toml_signs_msk
|
||||
#undef toml_bzero_msk
|
||||
#undef toml_bdigit_msk
|
||||
#undef signs_msk
|
||||
#undef bzero_msk
|
||||
#undef bdigit_msk
|
||||
}
|
||||
while (false);
|
||||
|
||||
@ -3028,7 +3022,7 @@ namespace toml::impl
|
||||
TOML_POP_WARNINGS
|
||||
};
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::unique_ptr<toml::array> parser::parse_array() TOML_MAY_THROW
|
||||
{
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -3111,7 +3105,7 @@ namespace toml::impl
|
||||
return arr;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::unique_ptr<toml::table> parser::parse_inline_table() TOML_MAY_THROW
|
||||
{
|
||||
TOML_ERROR_CHECK({});
|
||||
@ -3230,13 +3224,8 @@ namespace toml::impl
|
||||
return tab;
|
||||
}
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
#undef TOML_NORETURN
|
||||
#undef TOML_NOT_EOF
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result do_parse(utf8_reader_interface&& reader) TOML_MAY_THROW
|
||||
{
|
||||
return impl::parser{ std::move(reader) };
|
||||
@ -3245,6 +3234,11 @@ namespace toml::impl
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
#undef TOML_NORETURN
|
||||
#undef TOML_NOT_EOF
|
||||
}
|
||||
|
||||
namespace toml
|
||||
@ -3258,14 +3252,14 @@ namespace toml
|
||||
#endif
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::string_view doc, std::string_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, source_path });
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
@ -3274,14 +3268,14 @@ namespace toml
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::u8string_view doc, std::string_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, source_path });
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
@ -3304,7 +3298,7 @@ namespace toml
|
||||
#endif
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result operator"" _toml(const char* str, size_t len) TOML_MAY_THROW
|
||||
{
|
||||
return parse(std::string_view{ str, len });
|
||||
@ -3313,7 +3307,7 @@ namespace toml
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result operator"" _toml(const char8_t* str, size_t len) TOML_MAY_THROW
|
||||
{
|
||||
return parse(std::u8string_view{ str, len });
|
||||
|
@ -4,16 +4,16 @@
|
||||
|
||||
#pragma once
|
||||
#include "toml_date_time.h"
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#if TOML_INTEGER_CHARCONV || TOML_FLOATING_POINT_CHARCONV
|
||||
#include <cmath>
|
||||
#if TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV
|
||||
#include <charconv>
|
||||
#endif
|
||||
#if !TOML_INTEGER_CHARCONV || !TOML_FLOATING_POINT_CHARCONV
|
||||
#if !TOML_INT_CHARCONV || !TOML_FLOAT_CHARCONV
|
||||
#include <sstream>
|
||||
#endif
|
||||
#if !TOML_INTEGER_CHARCONV
|
||||
#if !TOML_INT_CHARCONV
|
||||
#include <iomanip>
|
||||
#endif
|
||||
TOML_POP_WARNINGS
|
||||
@ -59,7 +59,8 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_GNU_ATTR(nonnull) TOML_ALWAYS_INLINE
|
||||
TOML_GNU_ATTR(nonnull)
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
@ -77,7 +78,8 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
TOML_GNU_ATTR(nonnull) TOML_ALWAYS_INLINE
|
||||
TOML_GNU_ATTR(nonnull)
|
||||
TOML_ALWAYS_INLINE
|
||||
void print_to_stream(const char8_t* str, size_t len, std::basic_ostream<Char>& stream)
|
||||
{
|
||||
static_assert(sizeof(Char) == 1);
|
||||
@ -106,7 +108,7 @@ namespace toml::impl
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
#if TOML_INTEGER_CHARCONV
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
@ -146,7 +148,7 @@ namespace toml::impl
|
||||
#undef TOML_P2S_OVERLOAD
|
||||
|
||||
template <typename T, typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void print_floating_point_to_stream(T val, std::basic_ostream<Char>& stream, bool hexfloat = false)
|
||||
{
|
||||
static_assert(
|
||||
@ -154,39 +156,55 @@ namespace toml::impl
|
||||
"The stream's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
static constexpr auto needs_decimal_point = [](auto&& s) noexcept
|
||||
switch (std::fpclassify(val))
|
||||
{
|
||||
for (auto c : s)
|
||||
if (c == '.' || c == 'E' || c == 'e')
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
case FP_INFINITE:
|
||||
if (val < T{})
|
||||
print_to_stream('-', stream);
|
||||
print_to_stream("inf"sv, stream);
|
||||
return;
|
||||
|
||||
#if TOML_FLOATING_POINT_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);
|
||||
case FP_NAN:
|
||||
print_to_stream("nan"sv, stream);
|
||||
return;
|
||||
|
||||
default:
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
@ -220,7 +238,7 @@ namespace toml::impl
|
||||
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_INTEGER_CHARCONV
|
||||
#if TOML_INT_CHARCONV
|
||||
|
||||
char buf[charconv_buffer_length<T>];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
|
||||
@ -364,7 +382,7 @@ namespace toml
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_position& rhs)
|
||||
{
|
||||
static_assert(
|
||||
@ -399,7 +417,7 @@ namespace toml
|
||||
///
|
||||
/// \returns The input stream.
|
||||
template <typename Char>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const source_region& rhs)
|
||||
{
|
||||
static_assert(
|
||||
@ -416,44 +434,8 @@ namespace toml
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// \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 << std::endl;
|
||||
/// }
|
||||
/// \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>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const parse_error& rhs)
|
||||
{
|
||||
impl::print_to_stream(rhs.description(), lhs);
|
||||
impl::print_to_stream("\n\t(error occurred at "sv, lhs);
|
||||
lhs << rhs.source();
|
||||
impl::print_to_stream(")"sv, lhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_position&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const source_region&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
#endif
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
//# {{
|
||||
#pragma once
|
||||
#include "toml_table.h"
|
||||
#include "toml_node_view.h"
|
||||
//# {{
|
||||
#if !defined(TOML_IMPLEMENTATION) || !TOML_IMPLEMENTATION
|
||||
#error This is an implementation-only header.
|
||||
#endif
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(impl::table_init_pair* pairs, size_t count) noexcept
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
@ -25,17 +25,17 @@ namespace toml
|
||||
}
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table() noexcept {}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::table(table&& other) noexcept
|
||||
: node{ std::move(other) },
|
||||
values{ std::move(other.values) },
|
||||
inline_{ other.inline_ }
|
||||
{}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::operator = (table&& rhs) noexcept
|
||||
{
|
||||
node::operator=(std::move(rhs));
|
||||
@ -44,57 +44,57 @@ namespace toml
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE node_type table::type() const noexcept { return node_type::table; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool table::is_table() const noexcept { return true; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool table::is_array() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool table::is_value() const noexcept { return false; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table* table::as_table() noexcept { return this; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE const table* table::as_table() const noexcept { return this; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool table::is_inline() const noexcept { return inline_; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE void table::is_inline(bool val) noexcept { inline_ = val; }
|
||||
TOML_EXTERNAL_LINKAGE node_type table::type() const noexcept { return node_type::table; }
|
||||
TOML_EXTERNAL_LINKAGE bool table::is_table() const noexcept { return true; }
|
||||
TOML_EXTERNAL_LINKAGE bool table::is_array() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE bool table::is_value() const noexcept { return false; }
|
||||
TOML_EXTERNAL_LINKAGE table* table::as_table() noexcept { return this; }
|
||||
TOML_EXTERNAL_LINKAGE const table* table::as_table() const noexcept { return this; }
|
||||
TOML_EXTERNAL_LINKAGE bool table::is_inline() const noexcept { return inline_; }
|
||||
TOML_EXTERNAL_LINKAGE void table::is_inline(bool val) noexcept { inline_ = val; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (string_view key) noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
}
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[] (string_view key) const noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::iterator table::begin() noexcept { return { values.begin() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::const_iterator table::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::const_iterator table::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::begin() noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::begin() const noexcept { return { values.begin() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cbegin() const noexcept { return { values.cbegin() }; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::iterator table::end() noexcept { return { values.end() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::const_iterator table::end() const noexcept { return { values.end() }; }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE table::const_iterator table::cend() const noexcept { return { values.cend() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::iterator table::end() noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::end() const noexcept { return { values.end() }; }
|
||||
TOML_EXTERNAL_LINKAGE table::const_iterator table::cend() const noexcept { return { values.cend() }; }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE bool table::empty() const noexcept { return values.empty(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE size_t table::size() const noexcept { return values.size(); }
|
||||
TOML_FUNC_EXTERNAL_LINKAGE void table::clear() noexcept { values.clear(); }
|
||||
TOML_EXTERNAL_LINKAGE bool table::empty() const noexcept { return values.empty(); }
|
||||
TOML_EXTERNAL_LINKAGE size_t table::size() const noexcept { return values.size(); }
|
||||
TOML_EXTERNAL_LINKAGE void table::clear() noexcept { values.clear(); }
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(const_iterator pos) noexcept
|
||||
{
|
||||
return { values.erase(pos.raw_) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::erase(const_iterator first, const_iterator last) noexcept
|
||||
{
|
||||
return { values.erase(first.raw_, last.raw_) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::erase(string_view key) noexcept
|
||||
{
|
||||
if (auto it = values.find(key); it != values.end())
|
||||
@ -105,38 +105,38 @@ namespace toml
|
||||
return false;
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node* table::get(string_view key) noexcept
|
||||
{
|
||||
return do_get(values, key);
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const node* table::get(string_view key) const noexcept
|
||||
{
|
||||
return do_get(values, key);
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::find(string_view key) noexcept
|
||||
{
|
||||
return { values.find(key) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::const_iterator table::find(string_view key) const noexcept
|
||||
{
|
||||
return { values.find(key) };
|
||||
}
|
||||
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::contains(string_view key) const noexcept
|
||||
{
|
||||
return do_contains(values, key);
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator == (const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
if (&lhs == &rhs)
|
||||
@ -166,7 +166,7 @@ namespace toml
|
||||
}
|
||||
|
||||
TOML_API
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator != (const table& lhs, const table& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
|
@ -10,20 +10,25 @@
|
||||
namespace toml::impl
|
||||
{
|
||||
template <typename... T>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_match(char32_t codepoint, T... vals) noexcept
|
||||
{
|
||||
static_assert((std::is_same_v<char32_t, T> && ...));
|
||||
return ((codepoint == vals) || ...);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'\t' || codepoint == U' ';
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_unicode_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
// see: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -39,13 +44,16 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_whitespace(codepoint) || is_unicode_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = IncludeCarriageReturn ? U'\r' : U'\f';
|
||||
@ -53,6 +61,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_unicode_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
// see https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -66,43 +75,55 @@ namespace toml::impl
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_unicode_line_break(codepoint);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_string_delimiter(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_ascii_letter(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'z')
|
||||
|| (codepoint >= U'A' && codepoint <= U'Z');
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_binary_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'0' || codepoint == U'1';
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_octal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'7');
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_decimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'9');
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_hexadecimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'f')
|
||||
@ -111,7 +132,9 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr uint32_t hex_to_dec(char codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 'A'
|
||||
@ -120,7 +143,9 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr uint32_t hex_to_dec(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= U'A'
|
||||
@ -130,6 +155,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_bare_key_start_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_letter(codepoint)
|
||||
@ -145,6 +171,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_bare_key_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_bare_key_start_character(codepoint)
|
||||
@ -155,6 +182,7 @@ namespace toml::impl
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_value_terminator(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break(codepoint)
|
||||
@ -168,7 +196,9 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_nontab_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u0008'
|
||||
@ -176,7 +206,9 @@ namespace toml::impl
|
||||
|| codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_unicode_surrogate(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 0xD800u && codepoint <= 0xDFFF;
|
||||
@ -184,10 +216,6 @@ namespace toml::impl
|
||||
|
||||
struct utf8_decoder final
|
||||
{
|
||||
//# This decoder is based on the 'Flexible and Economical UTF-8 Decoder'
|
||||
//# Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
//# See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
uint_least32_t state{};
|
||||
char32_t codepoint{};
|
||||
|
||||
@ -242,429 +270,5 @@ namespace toml::impl
|
||||
state = state_table[state + uint_least32_t{ 256u } + type];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class utf8_byte_stream;
|
||||
|
||||
template <typename Char>
|
||||
class 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 }
|
||||
{
|
||||
if (source.length() >= 3_sz
|
||||
&& static_cast<uint8_t>(source[0]) == static_cast<uint8_t>(0xEFu)
|
||||
&& static_cast<uint8_t>(source[1]) == static_cast<uint8_t>(0xBBu)
|
||||
&& static_cast<uint8_t>(source[2]) == static_cast<uint8_t>(0xBFu))
|
||||
{
|
||||
position += 3_sz;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool eof() const noexcept
|
||||
{
|
||||
return position >= source.length();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr optional<uint8_t> operator() () noexcept
|
||||
{
|
||||
if (position >= source.length())
|
||||
return {};
|
||||
return static_cast<uint8_t>(source[position++]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
class 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)
|
||||
{
|
||||
static constexpr uint8_t bom[] {
|
||||
0xEF,
|
||||
0xBB,
|
||||
0xBF
|
||||
};
|
||||
|
||||
using stream_traits = typename std::remove_pointer_t<decltype(source)>::traits_type;
|
||||
const auto initial_pos = source->tellg();
|
||||
size_t bom_pos{};
|
||||
auto bom_char = source->get();
|
||||
while (*source && bom_char != stream_traits::eof() && bom_char == bom[bom_pos])
|
||||
{
|
||||
bom_pos++;
|
||||
bom_char = source->get();
|
||||
}
|
||||
if (!(*source) || bom_pos < 3_sz)
|
||||
source->seekg(initial_pos);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool eof() const noexcept
|
||||
{
|
||||
return source->eof();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool error() const noexcept
|
||||
{
|
||||
return !(*source);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
optional<uint8_t> operator() ()
|
||||
{
|
||||
auto val = source->get();
|
||||
if (val == std::basic_istream<Char>::traits_type::eof())
|
||||
return {};
|
||||
return static_cast<uint8_t>(val);
|
||||
}
|
||||
};
|
||||
|
||||
struct utf8_codepoint final
|
||||
{
|
||||
char32_t value;
|
||||
string_char bytes[4];
|
||||
source_position position;
|
||||
|
||||
template <typename Char = string_char>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
std::basic_string_view<Char> as_view() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The string view's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
return bytes[3]
|
||||
? std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes), 4_sz }
|
||||
: std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes) };
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr operator char32_t& () noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr operator const char32_t& () const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_trivial_v<utf8_codepoint>);
|
||||
static_assert(std::is_standard_layout_v<utf8_codepoint>);
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_ERROR_CHECK (void)0
|
||||
#define TOML_ERROR throw parse_error
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_impl_ex {
|
||||
#endif
|
||||
#else
|
||||
#define TOML_ERROR_CHECK if (err) return nullptr
|
||||
#define TOML_ERROR err.emplace
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_impl_noex {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
struct TOML_INTERFACE utf8_reader_interface
|
||||
{
|
||||
[[nodiscard]]
|
||||
virtual const source_path_ptr& source_path() const noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual const utf8_codepoint* read_next() = 0;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
virtual optional<parse_error>&& error() noexcept = 0;
|
||||
|
||||
#endif
|
||||
|
||||
virtual ~utf8_reader_interface() noexcept = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TOML_EMPTY_BASES 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{ std::forward<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>(std::forward<String>(source_path));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return source_path_;
|
||||
}
|
||||
|
||||
[[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)
|
||||
{
|
||||
optional<uint8_t> nextByte;
|
||||
if constexpr (noexcept(stream()) || !TOML_EXCEPTIONS)
|
||||
{
|
||||
nextByte = stream();
|
||||
}
|
||||
#if TOML_EXCEPTIONS
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
nextByte = 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 (!nextByte)
|
||||
{
|
||||
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;
|
||||
|
||||
decoder(*nextByte);
|
||||
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<string_char>(*nextByte);
|
||||
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;
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[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_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<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&&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
#define TOML_ERROR_CHECK if (reader.error()) return nullptr
|
||||
#endif
|
||||
|
||||
class TOML_EMPTY_BASES utf8_buffered_reader final
|
||||
: public utf8_reader_interface
|
||||
{
|
||||
public:
|
||||
static constexpr size_t max_history_length = 64;
|
||||
|
||||
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
|
||||
: reader{ reader_ }
|
||||
{}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return reader.source_path();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* read_next() override
|
||||
{
|
||||
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 (!history.count && !head) TOML_UNLIKELY
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if (history.count < history_buffer_size) TOML_UNLIKELY
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
||||
head = reader.read_next();
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* 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;
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
optional<parse_error>&& error() noexcept override
|
||||
{
|
||||
return reader.error();
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS / !TOML_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ namespace toml::impl
|
||||
{
|
||||
//# Returns true if a codepoint belongs to any of these categories: Ll, Lm, Lo, Lt, Lu
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_unicode_letter(char32_t codepoint) noexcept
|
||||
{
|
||||
if (codepoint < U'\u00AA' || codepoint > U'\U00031349')
|
||||
@ -466,6 +467,7 @@ namespace toml::impl
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories: Nd, Nl
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_unicode_number(char32_t codepoint) noexcept
|
||||
{
|
||||
if (codepoint < U'\u0660' || codepoint > U'\U0001FBF9')
|
||||
@ -569,6 +571,7 @@ namespace toml::impl
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories: Mn, Mc
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_unicode_combining_mark(char32_t codepoint) noexcept
|
||||
{
|
||||
if (codepoint < U'\u0300' || codepoint > U'\U000E01EF')
|
||||
|
452
include/toml++/toml_utf8_streams.h
Normal file
452
include/toml++/toml_utf8_streams.h
Normal file
@ -0,0 +1,452 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
|
||||
#pragma once
|
||||
#include "toml_common.h"
|
||||
//# {{
|
||||
#if !TOML_PARSER
|
||||
#error This header cannot not be included when TOML_PARSER is disabled.
|
||||
#endif
|
||||
//# }}
|
||||
#include "toml_utf8.h"
|
||||
#include "toml_parse_error.h"
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
template <typename T>
|
||||
class utf8_byte_stream;
|
||||
|
||||
template <typename Char>
|
||||
class 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 }
|
||||
{
|
||||
if (source.length() >= 3_sz
|
||||
&& static_cast<uint8_t>(source[0]) == static_cast<uint8_t>(0xEFu)
|
||||
&& static_cast<uint8_t>(source[1]) == static_cast<uint8_t>(0xBBu)
|
||||
&& static_cast<uint8_t>(source[2]) == static_cast<uint8_t>(0xBFu))
|
||||
{
|
||||
position += 3_sz;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool eof() const noexcept
|
||||
{
|
||||
return position >= source.length();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr optional<uint8_t> operator() () noexcept
|
||||
{
|
||||
if (position >= source.length())
|
||||
return {};
|
||||
return static_cast<uint8_t>(source[position++]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
class 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)
|
||||
{
|
||||
static constexpr uint8_t bom[] {
|
||||
0xEF,
|
||||
0xBB,
|
||||
0xBF
|
||||
};
|
||||
|
||||
using stream_traits = typename std::remove_pointer_t<decltype(source)>::traits_type;
|
||||
const auto initial_pos = source->tellg();
|
||||
size_t bom_pos{};
|
||||
auto bom_char = source->get();
|
||||
while (*source && bom_char != stream_traits::eof() && bom_char == bom[bom_pos])
|
||||
{
|
||||
bom_pos++;
|
||||
bom_char = source->get();
|
||||
}
|
||||
if (!(*source) || bom_pos < 3_sz)
|
||||
source->seekg(initial_pos);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
bool eof() const noexcept
|
||||
{
|
||||
return source->eof();
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
bool error() const noexcept
|
||||
{
|
||||
return !(*source);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
optional<uint8_t> operator() ()
|
||||
{
|
||||
auto val = source->get();
|
||||
if (val == std::basic_istream<Char>::traits_type::eof())
|
||||
return {};
|
||||
return static_cast<uint8_t>(val);
|
||||
}
|
||||
};
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
#if TOML_LARGE_FILES
|
||||
inline namespace abi_impl_lf {
|
||||
#else
|
||||
inline namespace abi_impl_lf {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct utf8_codepoint final
|
||||
{
|
||||
char32_t value;
|
||||
string_char bytes[4];
|
||||
source_position position;
|
||||
|
||||
template <typename Char = string_char>
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
std::basic_string_view<Char> as_view() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The string view's underlying character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
return bytes[3]
|
||||
? std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes), 4_sz }
|
||||
: std::basic_string_view<Char>{ reinterpret_cast<const Char*>(bytes) };
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr operator char32_t& () noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
constexpr operator const char32_t& () const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_trivial_v<utf8_codepoint>);
|
||||
static_assert(std::is_standard_layout_v<utf8_codepoint>);
|
||||
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_LARGE_FILES
|
||||
#endif
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_ERROR_CHECK (void)0
|
||||
#define TOML_ERROR throw parse_error
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_impl_ex {
|
||||
#endif
|
||||
#else
|
||||
#define TOML_ERROR_CHECK if (err) return nullptr
|
||||
#define TOML_ERROR err.emplace
|
||||
#if TOML_ABI_NAMESPACES
|
||||
inline namespace abi_impl_noex {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
struct TOML_INTERFACE utf8_reader_interface
|
||||
{
|
||||
[[nodiscard]]
|
||||
virtual const source_path_ptr& source_path() const noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual const utf8_codepoint* read_next() = 0;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
virtual optional<parse_error>&& error() noexcept = 0;
|
||||
|
||||
#endif
|
||||
|
||||
virtual ~utf8_reader_interface() noexcept = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TOML_EMPTY_BASES 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{ std::forward<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>(std::forward<String>(source_path));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return source_path_;
|
||||
}
|
||||
|
||||
[[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)
|
||||
{
|
||||
optional<uint8_t> nextByte;
|
||||
if constexpr (noexcept(stream()) || !TOML_EXCEPTIONS)
|
||||
{
|
||||
nextByte = stream();
|
||||
}
|
||||
#if TOML_EXCEPTIONS
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
nextByte = 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 (!nextByte)
|
||||
{
|
||||
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;
|
||||
|
||||
decoder(*nextByte);
|
||||
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<string_char>(*nextByte);
|
||||
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;
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[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_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<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&&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
#undef TOML_ERROR_CHECK
|
||||
#define TOML_ERROR_CHECK if (reader.error()) return nullptr
|
||||
#endif
|
||||
|
||||
class TOML_EMPTY_BASES utf8_buffered_reader final
|
||||
: public utf8_reader_interface
|
||||
{
|
||||
public:
|
||||
static constexpr size_t max_history_length = 64;
|
||||
|
||||
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
|
||||
: reader{ reader_ }
|
||||
{}
|
||||
|
||||
[[nodiscard]]
|
||||
const source_path_ptr& source_path() const noexcept override
|
||||
{
|
||||
return reader.source_path();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* read_next() override
|
||||
{
|
||||
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 (!history.count && !head) TOML_UNLIKELY
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if (history.count < history_buffer_size) TOML_UNLIKELY
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
||||
head = reader.read_next();
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const utf8_codepoint* 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;
|
||||
}
|
||||
|
||||
#if !TOML_EXCEPTIONS
|
||||
|
||||
[[nodiscard]]
|
||||
optional<parse_error>&& error() noexcept override
|
||||
{
|
||||
return reader.error();
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#undef TOML_ERROR_CHECK
|
||||
#undef TOML_ERROR
|
||||
#if TOML_ABI_NAMESPACES
|
||||
} //end abi namespace for TOML_EXCEPTIONS / !TOML_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
TOML_POP_WARNINGS
|
||||
}
|
@ -346,7 +346,7 @@ namespace toml
|
||||
|
||||
/// \brief Prints the value out to a stream.
|
||||
template <typename Char, typename T>
|
||||
TOML_FUNC_EXTERNAL_LINKAGE
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
// this is the same behaviour as default_formatter, but it's so simple that there's
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#define TOML_LIB_MAJOR 1
|
||||
#define TOML_LIB_MINOR 2
|
||||
#define TOML_LIB_PATCH 1
|
||||
#define TOML_LIB_PATCH 2
|
||||
|
||||
#define TOML_LANG_MAJOR 1
|
||||
#define TOML_LANG_MINOR 0
|
||||
|
@ -51,7 +51,7 @@ class Preprocessor:
|
||||
|
||||
self.processed_includes.append(incl)
|
||||
text = read_all_text_from_file(path.join(get_script_folder(), '..', 'include', 'toml++', incl))
|
||||
text = re.sub(r'//[#|]\s*[{][{].*?//[#|]\s*[}][}]', '', text, 0, re.I | re.S)
|
||||
text = re.sub(r'//[#!]\s*[{][{].*?//[#!]\s*[}][}]', '', text, 0, re.I | re.S)
|
||||
text = re.sub(r'^\s*#\s*pragma\s+once\s*$', '', text, 0, re.I | re.M)
|
||||
text = re.sub(r'^\s*//\s*clang-format\s+(?:off|on)\s*$', '', text, 0, re.I | re.M)
|
||||
|
||||
@ -63,10 +63,11 @@ class Preprocessor:
|
||||
header_text = '↓ ' + raw_incl
|
||||
lpad = 28 + ((25 * (self.header_indent % 4)) - int((len(header_text) + 4) / 2))
|
||||
self.header_indent += 1
|
||||
return '\n{}\n#pragma region {}\n\n{}\n\n#pragma endregion {}\n{}'.format(
|
||||
make_divider(header_text, lpad), '', text, '', make_divider('↑ ' + raw_incl, lpad))
|
||||
else:
|
||||
return text
|
||||
text = '{}\n#pragma region {}\n\n{}\n\n#pragma endregion {}\n{}'.format(
|
||||
make_divider(header_text, lpad), '', text, '', make_divider('↑ ' + raw_incl, lpad)
|
||||
)
|
||||
|
||||
return '\n\n' + text + '\n\n' # will get merged later
|
||||
|
||||
def __call__(self, file):
|
||||
self.processed_includes = []
|
||||
@ -82,9 +83,9 @@ def main():
|
||||
source_text = Preprocessor()('toml.h')
|
||||
source_text = re.sub('\r\n', '\n', source_text, 0, re.I | re.M) # convert windows newlines
|
||||
source_text = re.sub('(?:(?:\n|^)[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comment blocks
|
||||
source_text = re.sub('(?:///[<].*?)\n', '\n', source_text, 0, re.I | re.M) # remove inline doxy briefs
|
||||
source_text = re.sub('\n(?:[ \t]*\n[ \t]*)+\n', '\n\n', source_text, 0, re.I | re.M) # remove double newlines
|
||||
source_text = re.sub('(?://[/#!<].*?)\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comments
|
||||
source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M) # remove trailing whitespace
|
||||
source_text = re.sub('\n(?:[ \t]*\n[ \t]*)+\n', '\n\n', source_text, 0, re.I | re.M) # remove double newlines
|
||||
return_type_pattern \
|
||||
= r'(?:' \
|
||||
+ r'(?:\[\[nodiscard\]\]\s*)?' \
|
||||
@ -163,6 +164,7 @@ v0.5.0: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#endif
|
||||
#define TOML_LIB_SINGLE_HEADER 1
|
||||
''', file=output_file)
|
||||
print(source_text, file=output_file)
|
||||
print('''
|
||||
|
@ -503,6 +503,7 @@ def emit_function(name, categories, file, codepoints):
|
||||
|
||||
print('\n\t//# Returns true if a codepoint belongs to any of these categories: {}'.format(', '.join(categories)), file=file)
|
||||
print('\t[[nodiscard]]', file=file)
|
||||
print('\tTOML_GNU_ATTR(const)', file=file)
|
||||
print('\tconstexpr bool {}(char32_t codepoint) noexcept\n\t{{'.format(name), file=file)
|
||||
root_chunk.print(file)
|
||||
print('\t}', file=file)
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#define CATCH_CONFIG_CONSOLE_WIDTH 120
|
||||
#define CATCH_CONFIG_CPP11_TO_STRING
|
||||
#define CATCH_CONFIG_DISABLE_MATCHERS
|
||||
|
||||
//windows.h config
|
||||
#ifdef _WIN32
|
||||
|
@ -34,9 +34,14 @@ TEST_CASE("values - printing")
|
||||
CHECK(print_value(10000.0f) == "10000.0");
|
||||
CHECK(print_value(10000.0) == "10000.0");
|
||||
|
||||
CHECK(print_value(std::numeric_limits<double>::infinity()) == "inf");
|
||||
CHECK(print_value(-std::numeric_limits<double>::infinity()) == "-inf");
|
||||
CHECK(print_value(std::numeric_limits<double>::quiet_NaN()) == "nan");
|
||||
|
||||
// only integers for large values;
|
||||
// large floats might get output as scientific notation and that's fine
|
||||
CHECK(print_value(10000000000) == "10000000000");
|
||||
CHECK(print_value(100000000000000) == "100000000000000");
|
||||
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,12 @@ flt8 = 224_617.445_991_228
|
||||
|
||||
//value tests
|
||||
parse_expected_value( FILE_LINE_ARGS, "1e1"sv, 1e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1e-1"sv, 1e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1e+1"sv, 1e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1e-1"sv, 1e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0"sv, 1.0);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0e1"sv, 1.0e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0e-1"sv, 1.0e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0e+1"sv, 1.0e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0e-1"sv, 1.0e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1e1"sv, +1e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1.0"sv, +1.0);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1.0e1"sv, +1.0e1);
|
||||
@ -67,7 +67,30 @@ flt8 = 224_617.445_991_228
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.0"sv, -1.0);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.0e1"sv, -1.0e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.0e-1"sv, -1.0e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.0"sv, 1.0);
|
||||
parse_expected_value( FILE_LINE_ARGS, ".1"sv, .1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+.1"sv, +.1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-.1"sv, -.1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1."sv, 1.);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1."sv, +1.);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1."sv, -1.);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.e1"sv, 1.e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.e+1"sv, 1.e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "1.e-1"sv, 1.e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1.e1"sv, +1.e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1.e+1"sv, +1.e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+1.e-1"sv, +1.e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.e1"sv, -1.e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.e+1"sv, -1.e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-1.e-1"sv, -1.e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, ".1e1"sv, .1e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, ".1e+1"sv, .1e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, ".1e-1"sv, .1e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+.1e1"sv, +.1e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+.1e+1"sv, +.1e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "+.1e-1"sv, +.1e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-.1e1"sv, -.1e1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-.1e+1"sv, -.1e+1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "-.1e-1"sv, -.1e-1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "0.1"sv, 0.1);
|
||||
parse_expected_value( FILE_LINE_ARGS, "0.001"sv, 0.001);
|
||||
parse_expected_value( FILE_LINE_ARGS, "0.100"sv, 0.100);
|
||||
@ -173,4 +196,37 @@ sf6 = -nan # valid, actual encoding is implementation specific
|
||||
CHECK(std::isnan(tbl[S("sf6")].as<double>()->get()));
|
||||
}
|
||||
);
|
||||
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = NaN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = Nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = NAN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = +NaN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = +Nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = +NAN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = -NaN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = -Nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = -NAN "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = 1.nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = 1,nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = .nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = ,nan "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = nan.1 "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = nan,1 "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = nan. "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = nan, "sv));
|
||||
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = Inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = INF "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = +Inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = +INF "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = -Inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = -INF "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = 1.inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = 1,inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = .inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = ,inf "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = inf.1 "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = inf,1 "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = inf. "sv));
|
||||
parsing_should_fail(FILE_LINE_ARGS, S(" val = inf, "sv));
|
||||
}
|
||||
|
@ -9,13 +9,12 @@
|
||||
|
||||
<!-- Adapter Specific sections -->
|
||||
<Catch2Adapter>
|
||||
<DebugBreak>on</DebugBreak><!-- Introduced in v1.1.0 -->
|
||||
<DiscoverCommandLine>--verbosity high --list-test-names-only</DiscoverCommandLine>
|
||||
<DiscoverCommandLine>--verbosity high --list-tests *</DiscoverCommandLine>
|
||||
<DiscoverTimeout>500</DiscoverTimeout><!-- Milliseconds -->
|
||||
<FilenameFilter>(?i:test)</FilenameFilter>
|
||||
<Logging>debug</Logging>
|
||||
<WorkingDirectoryRoot>Solution</WorkingDirectoryRoot>
|
||||
<WorkingDirectory>..\tests\</WorkingDirectory>
|
||||
<MessageFormat>AdditionalInfo</MessageFormat>
|
||||
</Catch2Adapter>
|
||||
|
||||
</RunSettings>
|
||||
|
@ -70,11 +70,13 @@
|
||||
<ClInclude Include="..\include\toml++\toml_parser.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_node_view.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_parser.hpp" />
|
||||
<ClInclude Include="..\include\toml++\toml_parse_error.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_print_to_stream.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_table.hpp" />
|
||||
<ClInclude Include="..\include\toml++\toml_utf8_generated.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_table.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_utf8.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_utf8_streams.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_value.h" />
|
||||
<ClInclude Include="..\include\toml++\toml_instantiations.hpp" />
|
||||
<ClInclude Include="..\include\toml++\toml_version.h" />
|
||||
|
@ -70,6 +70,12 @@
|
||||
<ClInclude Include="..\include\toml++\toml_parser.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\toml++\toml_utf8_streams.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\toml++\toml_parse_error.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" />
|
||||
|
Loading…
Reference in New Issue
Block a user