added formatter indentation flags (closes #120)

also:
- minor refactoring (esp. GNU attributes)
- added documentation about formatters being free to ignore flags where necessary
This commit is contained in:
Mark Gillard 2021-10-27 16:03:05 +03:00
parent bd9944a31a
commit 18dfcf2314
18 changed files with 616 additions and 350 deletions

View File

@ -156,12 +156,16 @@ StatementMacros:
- TOML_ALWAYS_INLINE - TOML_ALWAYS_INLINE
- TOML_API - TOML_API
- TOML_ATTR - TOML_ATTR
- TOML_CONST_GETTER
- TOML_CONST_INLINE_GETTER
- TOML_EXTERNAL_LINKAGE - TOML_EXTERNAL_LINKAGE
- TOML_INTERNAL_LINKAGE - TOML_INTERNAL_LINKAGE
- TOML_MEMBER_ATTR - TOML_MEMBER_ATTR
- TOML_NEVER_INLINE - TOML_NEVER_INLINE
- TOML_NODISCARD - TOML_NODISCARD
- TOML_NODISCARD_CTOR - TOML_NODISCARD_CTOR
- TOML_PURE_GETTER
- TOML_PURE_INLINE_GETTER
- TOML_RETURNS_BY_THROWING - TOML_RETURNS_BY_THROWING
TabWidth: 4 TabWidth: 4
TypenameMacros: TypenameMacros:

View File

@ -1,24 +1,28 @@
#define TOML_API
#define TOML_ATTR(...)
#define TOML_ALWAYS_INLINE inline
#define TOML_NEVER_INLINE
#define TOML_TRIVIAL_ABI
#define TOML_ABSTRACT_BASE
#define TOML_EMPTY_BASES
#define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__>
#define TOML_LIKELY(...) (__VA_ARGS__)
#define TOML_UNLIKELY(...) (__VA_ARGS__)
#define TOML_NODISCARD
#define TOML_NODISCARD_CTOR
#define TOML_RETURNS_BY_THROWING
#define TOML_EXTERN_NOEXCEPT(...)
#define TOML_EXTERNAL_LINKAGE
#define TOML_INTERNAL_LINKAGE static
#define TOML_ANON_NAMESPACE_START namespace
#define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true) #define TOML_ABI_NAMESPACE_BOOL(...) static_assert(true)
#define TOML_ABI_NAMESPACE_END static_assert(true) #define TOML_ABI_NAMESPACE_END static_assert(true)
#define TOML_NAMESPACE_START namespace toml #define TOML_ABSTRACT_BASE
#define TOML_NAMESPACE_END static_assert(true) #define TOML_ALWAYS_INLINE inline
#define TOML_IMPL_NAMESPACE_START namespace toml::impl #define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ANON_NAMESPACE_START namespace
#define TOML_API
#define TOML_ATTR(...)
#define TOML_CONST_GETTER
#define TOML_CONST_INLINE_GETTER inline
#define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__>
#define TOML_EMPTY_BASES
#define TOML_EXTERN_NOEXCEPT(...)
#define TOML_EXTERNAL_LINKAGE
#define TOML_IMPL_NAMESPACE_END static_assert(true) #define TOML_IMPL_NAMESPACE_END static_assert(true)
#define TOML_IMPL_NAMESPACE_START namespace toml::impl
#define TOML_INTERNAL_LINKAGE static
#define TOML_LIKELY(...) (__VA_ARGS__)
#define TOML_NAMESPACE_END static_assert(true)
#define TOML_NAMESPACE_START namespace toml
#define TOML_NEVER_INLINE
#define TOML_NODISCARD
#define TOML_NODISCARD_CTOR
#define TOML_PURE_GETTER
#define TOML_PURE_INLINE_GETTER inline
#define TOML_RETURNS_BY_THROWING
#define TOML_TRIVIAL_ABI
#define TOML_UNLIKELY(...) (__VA_ARGS__)

View File

@ -81,13 +81,17 @@ TOML_NAMESPACE_START
TOML_API TOML_API
void print(); void print();
static constexpr format_flags mandatory_flags = format_flags::none;
static constexpr format_flags ignored_flags = format_flags::none;
/// \endcond /// \endcond
public: public:
/// \brief The default flags for a default_formatter. /// \brief The default flags for a default_formatter.
static constexpr format_flags default_flags = format_flags::allow_literal_strings static constexpr format_flags default_flags = format_flags::allow_literal_strings //
| format_flags::allow_multi_line_strings | format_flags::allow_multi_line_strings //
| format_flags::allow_value_format_flags; | format_flags::allow_value_format_flags //
| format_flags::indentation;
/// \brief Constructs a default formatter and binds it to a TOML object. /// \brief Constructs a default formatter and binds it to a TOML object.
/// ///
@ -95,7 +99,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags. /// \param flags Format option flags.
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags } : base{ source, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS) #if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
@ -124,7 +128,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags. /// \param flags Format option flags.
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags } : base{ result, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#endif #endif

View File

@ -260,7 +260,8 @@ TOML_NAMESPACE_START
{ {
if (original_indent < 0) if (original_indent < 0)
base::indent(0); base::indent(0);
base::increase_indent(); if (base::indent_array_elements())
base::increase_indent();
} }
else else
impl::print_to_stream(base::stream(), ' '); impl::print_to_stream(base::stream(), ' ');
@ -380,7 +381,8 @@ TOML_NAMESPACE_START
if (!skip_self) if (!skip_self)
{ {
print_pending_table_separator(); print_pending_table_separator();
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), "["sv); impl::print_to_stream(base::stream(), "["sv);
print_key_path(); print_key_path();
@ -391,7 +393,7 @@ TOML_NAMESPACE_START
print(child_tbl); print(child_tbl);
key_path_.pop_back(); key_path_.pop_back();
if (!skip_self) if (!skip_self && base::indent_sub_tables())
base::decrease_indent(); base::decrease_indent();
} }
@ -402,7 +404,8 @@ TOML_NAMESPACE_START
continue; continue;
auto& arr = *reinterpret_cast<const array*>(&v); auto& arr = *reinterpret_cast<const array*>(&v);
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
key_path_.push_back(make_key_segment(k)); key_path_.push_back(make_key_segment(k));
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
@ -417,7 +420,8 @@ TOML_NAMESPACE_START
} }
key_path_.pop_back(); key_path_.pop_back();
base::decrease_indent(); if (base::indent_sub_tables())
base::decrease_indent();
} }
} }

View File

@ -16,32 +16,30 @@ TOML_IMPL_NAMESPACE_START
private: private:
const toml::node* source_; const toml::node* source_;
std::ostream* stream_ = {}; std::ostream* stream_ = {};
format_flags flags_; format_flags flags_; //
int indent_; int indent_; // these are set in attach()
bool naked_newline_; bool naked_newline_; //
#if TOML_PARSER && !TOML_EXCEPTIONS #if TOML_PARSER && !TOML_EXCEPTIONS
const parse_result* result_ = {}; const parse_result* result_ = {};
#endif #endif
protected: protected:
TOML_NODISCARD static constexpr size_t indent_columns = 4;
TOML_ALWAYS_INLINE static constexpr std::string_view indent_string = " "sv;
TOML_PURE_INLINE_GETTER
const toml::node& source() const noexcept const toml::node& source() const noexcept
{ {
return *source_; return *source_;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
std::ostream& stream() const noexcept std::ostream& stream() const noexcept
{ {
return *stream_; return *stream_;
} }
static constexpr size_t indent_columns = 4; TOML_PURE_INLINE_GETTER
static constexpr std::string_view indent_string = " "sv;
TOML_NODISCARD
int indent() const noexcept int indent() const noexcept
{ {
return indent_; return indent_;
@ -62,31 +60,43 @@ TOML_IMPL_NAMESPACE_START
indent_--; indent_--;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool indent_array_elements() const noexcept
{
return !!(flags_ & format_flags::indent_array_elements);
}
TOML_PURE_INLINE_GETTER
bool indent_sub_tables() const noexcept
{
return !!(flags_ & format_flags::indent_sub_tables);
}
TOML_PURE_INLINE_GETTER
bool quote_dates_and_times() const noexcept bool quote_dates_and_times() const noexcept
{ {
return !!(flags_ & format_flags::quote_dates_and_times); return !!(flags_ & format_flags::quote_dates_and_times);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool literal_strings_allowed() const noexcept bool literal_strings_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_literal_strings); return !!(flags_ & format_flags::allow_literal_strings);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool multi_line_strings_allowed() const noexcept bool multi_line_strings_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_multi_line_strings); return !!(flags_ & format_flags::allow_multi_line_strings);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool value_format_flags_allowed() const noexcept bool value_format_flags_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_value_format_flags); return !!(flags_ & format_flags::allow_value_format_flags);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool naked_newline() const noexcept bool naked_newline() const noexcept
{ {
return naked_newline_; return naked_newline_;

View File

@ -213,18 +213,29 @@ TOML_IMPL_NAMESPACE_START
} }
} }
TOML_EXTERNAL_LINKAGE
bool formatter::dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS)
{
#if TOML_PARSER && !TOML_EXCEPTIONS #if TOML_PARSER && !TOML_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
bool formatter::dump_failed_parse_result() noexcept(false)
{
if (result_ && !(*result_)) if (result_ && !(*result_))
{ {
stream() << result_->error(); stream() << result_->error();
return true; return true;
} }
#endif
return false; return false;
} }
#else
TOML_EXTERNAL_LINKAGE
TOML_ATTR(const)
bool formatter::dump_failed_parse_result() noexcept(true)
{
return false;
}
#endif
} }
TOML_IMPL_NAMESPACE_END; TOML_IMPL_NAMESPACE_END;

View File

@ -267,7 +267,7 @@ TOML_NAMESPACE_START // abi namespace
} }
/// \brief Metadata associated with TOML values. /// \brief Metadata associated with TOML values.
enum class value_flags : uint8_t enum class value_flags : uint16_t
{ {
/// \brief None. /// \brief None.
none, none,
@ -284,7 +284,10 @@ TOML_NAMESPACE_START // abi namespace
TOML_MAKE_FLAGS(value_flags); TOML_MAKE_FLAGS(value_flags);
/// \brief Format flags for modifying how TOML data is printed to streams. /// \brief Format flags for modifying how TOML data is printed to streams.
enum class format_flags : uint8_t ///
/// \note Formatters may disregard/override any of these flags according to the requirements of their
/// output target (e.g. #toml::json_formatter JSON always apply quotes to dates and times).
enum class format_flags : uint64_t
{ {
/// \brief None. /// \brief None.
none, none,
@ -300,6 +303,15 @@ TOML_NAMESPACE_START // abi namespace
/// \brief Values with special format flags will be formatted accordingly. /// \brief Values with special format flags will be formatted accordingly.
allow_value_format_flags = 8, allow_value_format_flags = 8,
/// \brief Apply indentation to tables nested within other tables/arrays.
indent_sub_tables = 16,
/// \brief Apply indentation to array elements when the array is forced to wrap over multiple lines.
indent_array_elements = 32,
/// \brief Combination mask of all indentation-enabling flags.
indentation = indent_sub_tables | indent_array_elements,
}; };
TOML_MAKE_FLAGS(format_flags); TOML_MAKE_FLAGS(format_flags);

View File

@ -55,11 +55,16 @@ TOML_NAMESPACE_START
TOML_API TOML_API
void print(); void print();
static constexpr format_flags mandatory_flags = format_flags::quote_dates_and_times;
static constexpr format_flags ignored_flags =
format_flags::allow_literal_strings | format_flags::allow_multi_line_strings;
/// \endcond /// \endcond
public: public:
/// \brief The default flags for a json_formatter. /// \brief The default flags for a json_formatter.
static constexpr format_flags default_flags = format_flags::quote_dates_and_times; static constexpr format_flags default_flags = format_flags::quote_dates_and_times //
| format_flags::indentation;
/// \brief Constructs a JSON formatter and binds it to a TOML object. /// \brief Constructs a JSON formatter and binds it to a TOML object.
/// ///
@ -67,7 +72,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags. /// \param flags Format option flags.
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags } : base{ source, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS) #if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
@ -98,7 +103,7 @@ TOML_NAMESPACE_START
/// \param flags Format option flags. /// \param flags Format option flags.
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags } : base{ result, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#endif #endif

View File

@ -27,7 +27,8 @@ TOML_NAMESPACE_START
else else
{ {
impl::print_to_stream(base::stream(), '{'); impl::print_to_stream(base::stream(), '{');
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
bool first = false; bool first = false;
for (auto&& [k, v] : tbl) for (auto&& [k, v] : tbl)
{ {
@ -49,7 +50,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type); default: base::print_value(v, type);
} }
} }
base::decrease_indent(); if (base::indent_sub_tables())
base::decrease_indent();
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), '}'); impl::print_to_stream(base::stream(), '}');
@ -65,7 +67,8 @@ TOML_NAMESPACE_START
else else
{ {
impl::print_to_stream(base::stream(), '['); impl::print_to_stream(base::stream(), '[');
base::increase_indent(); if (base::indent_array_elements())
base::increase_indent();
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0u) if (i > 0u)
@ -83,7 +86,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type); default: base::print_value(v, type);
} }
} }
base::decrease_indent(); if (base::indent_array_elements())
base::decrease_indent();
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), ']'); impl::print_to_stream(base::stream(), ']');

View File

@ -27,8 +27,7 @@ TOML_NAMESPACE_START
decltype(auto) get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>); decltype(auto) get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
template <typename T, typename N> template <typename T, typename N>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
static decltype(auto) do_ref(N&& n) noexcept static decltype(auto) do_ref(N&& n) noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -59,27 +58,21 @@ TOML_NAMESPACE_START
node& operator=(node&&) noexcept; node& operator=(node&&) noexcept;
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
impl::wrap_node<T>& ref_cast() & noexcept impl::wrap_node<T>& ref_cast() & noexcept
{ {
return *reinterpret_cast<impl::wrap_node<T>*>(this); return *reinterpret_cast<impl::wrap_node<T>*>(this);
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
impl::wrap_node<T>&& ref_cast() && noexcept impl::wrap_node<T>&& ref_cast() && noexcept
{ {
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this)); return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
const impl::wrap_node<T>& ref_cast() const& noexcept const impl::wrap_node<T>& ref_cast() const& noexcept
{ {
return *reinterpret_cast<const impl::wrap_node<T>*>(this); return *reinterpret_cast<const impl::wrap_node<T>*>(this);
@ -102,84 +95,84 @@ TOML_NAMESPACE_START
virtual node_type type() const noexcept = 0; virtual node_type type() const noexcept = 0;
/// \brief Returns true if this node is a table. /// \brief Returns true if this node is a table.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_table() const noexcept virtual bool is_table() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is an array. /// \brief Returns true if this node is an array.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_array() const noexcept virtual bool is_array() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a value. /// \brief Returns true if this node is a value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_value() const noexcept virtual bool is_value() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a string value. /// \brief Returns true if this node is a string value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_string() const noexcept virtual bool is_string() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is an integer value. /// \brief Returns true if this node is an integer value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_integer() const noexcept virtual bool is_integer() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is an floating-point value. /// \brief Returns true if this node is an floating-point value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_floating_point() const noexcept virtual bool is_floating_point() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is an integer or floating-point value. /// \brief Returns true if this node is an integer or floating-point value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_number() const noexcept virtual bool is_number() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a boolean value. /// \brief Returns true if this node is a boolean value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_boolean() const noexcept virtual bool is_boolean() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a local date value. /// \brief Returns true if this node is a local date value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_date() const noexcept virtual bool is_date() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a local time value. /// \brief Returns true if this node is a local time value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_time() const noexcept virtual bool is_time() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is a date-time value. /// \brief Returns true if this node is a date-time value.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_date_time() const noexcept virtual bool is_date_time() const noexcept
{ {
return false; return false;
} }
/// \brief Returns true if this node is an array containing only tables. /// \brief Returns true if this node is an array containing only tables.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_array_of_tables() const noexcept virtual bool is_array_of_tables() const noexcept
{ {
return false; return false;
@ -191,8 +184,7 @@ TOML_NAMESPACE_START
/// ///
/// \returns Returns true if this node is an instance of the specified type. /// \returns Returns true if this node is an instance of the specified type.
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
bool is() const noexcept bool is() const noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -315,8 +307,7 @@ TOML_NAMESPACE_START
/// ///
/// \remarks Always returns `false` for empty tables and arrays. /// \remarks Always returns `false` for empty tables and arrays.
template <typename ElemType = void> template <typename ElemType = void>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
bool is_homogeneous() const noexcept bool is_homogeneous() const noexcept
{ {
using type = impl::unwrap_node<ElemType>; using type = impl::unwrap_node<ElemType>;
@ -334,117 +325,117 @@ TOML_NAMESPACE_START
/// @{ /// @{
/// \brief Returns a pointer to the node as a toml::table, if it is one. /// \brief Returns a pointer to the node as a toml::table, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual table* as_table() noexcept virtual table* as_table() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::array, if it is one. /// \brief Returns a pointer to the node as a toml::array, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual array* as_array() noexcept virtual array* as_array() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<string>, if it is one. /// \brief Returns a pointer to the node as a toml::value<string>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<std::string>* as_string() noexcept virtual toml::value<std::string>* as_string() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<int64_t>, if it is one. /// \brief Returns a pointer to the node as a toml::value<int64_t>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<int64_t>* as_integer() noexcept virtual toml::value<int64_t>* as_integer() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<double>, if it is one. /// \brief Returns a pointer to the node as a toml::value<double>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<double>* as_floating_point() noexcept virtual toml::value<double>* as_floating_point() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<bool>, if it is one. /// \brief Returns a pointer to the node as a toml::value<bool>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<bool>* as_boolean() noexcept virtual toml::value<bool>* as_boolean() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<date>, if it is one. /// \brief Returns a pointer to the node as a toml::value<date>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<date>* as_date() noexcept virtual toml::value<date>* as_date() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<time>, if it is one. /// \brief Returns a pointer to the node as a toml::value<time>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<time>* as_time() noexcept virtual toml::value<time>* as_time() noexcept
{ {
return nullptr; return nullptr;
} }
/// \brief Returns a pointer to the node as a toml::value<date_time>, if it is one. /// \brief Returns a pointer to the node as a toml::value<date_time>, if it is one.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<date_time>* as_date_time() noexcept virtual toml::value<date_time>* as_date_time() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const table* as_table() const noexcept virtual const table* as_table() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const array* as_array() const noexcept virtual const array* as_array() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<std::string>* as_string() const noexcept virtual const toml::value<std::string>* as_string() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<int64_t>* as_integer() const noexcept virtual const toml::value<int64_t>* as_integer() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<double>* as_floating_point() const noexcept virtual const toml::value<double>* as_floating_point() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<bool>* as_boolean() const noexcept virtual const toml::value<bool>* as_boolean() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<date>* as_date() const noexcept virtual const toml::value<date>* as_date() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<time>* as_time() const noexcept virtual const toml::value<time>* as_time() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<date_time>* as_date_time() const noexcept virtual const toml::value<date_time>* as_date_time() const noexcept
{ {
return nullptr; return nullptr;
@ -472,8 +463,7 @@ TOML_NAMESPACE_START
/// ///
/// \returns A pointer to the node as the given type, or nullptr if it was a different type. /// \returns A pointer to the node as the given type, or nullptr if it was a different type.
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
impl::wrap_node<T>* as() noexcept impl::wrap_node<T>* as() noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -502,8 +492,7 @@ TOML_NAMESPACE_START
/// \brief Gets a pointer to the node as a more specific node type (const overload). /// \brief Gets a pointer to the node as a more specific node type (const overload).
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
const impl::wrap_node<T>* as() const noexcept const impl::wrap_node<T>* as() const noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -730,8 +719,7 @@ TOML_NAMESPACE_START
/// ///
/// \returns A reference to the underlying data. /// \returns A reference to the underlying data.
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
impl::unwrap_node<T>& ref() & noexcept impl::unwrap_node<T>& ref() & noexcept
{ {
return do_ref<T>(*this); return do_ref<T>(*this);
@ -739,8 +727,7 @@ TOML_NAMESPACE_START
/// \brief Gets a raw reference to a value node's underlying data (rvalue overload). /// \brief Gets a raw reference to a value node's underlying data (rvalue overload).
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
impl::unwrap_node<T>&& ref() && noexcept impl::unwrap_node<T>&& ref() && noexcept
{ {
return do_ref<T>(std::move(*this)); return do_ref<T>(std::move(*this));
@ -748,8 +735,7 @@ TOML_NAMESPACE_START
/// \brief Gets a raw reference to a value node's underlying data (const lvalue overload). /// \brief Gets a raw reference to a value node's underlying data (const lvalue overload).
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
const impl::unwrap_node<T>& ref() const& noexcept const impl::unwrap_node<T>& ref() const& noexcept
{ {
return do_ref<T>(*this); return do_ref<T>(*this);
@ -761,7 +747,7 @@ TOML_NAMESPACE_START
/// @{ /// @{
/// \brief Returns the source region responsible for generating this node during parsing. /// \brief Returns the source region responsible for generating this node during parsing.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
const source_region& source() const noexcept const source_region& source() const noexcept
{ {
return source_; return source_;

View File

@ -96,25 +96,25 @@ TOML_NAMESPACE_START
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
node_view(const node_view&) noexcept = default; node_view(const node_view&) noexcept = default;
/// \brief Copy-assignment operator.
node_view& operator=(const node_view&) & noexcept = default;
/// \brief Move constructor. /// \brief Move constructor.
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
node_view(node_view&&) noexcept = default; node_view(node_view&&) noexcept = default;
/// \brief Copy-assignment operator.
node_view& operator=(const node_view&) & noexcept = default;
/// \brief Move-assignment operator. /// \brief Move-assignment operator.
node_view& operator=(node_view&&) & noexcept = default; node_view& operator=(node_view&&) & noexcept = default;
/// \brief Returns true if the view references a node. /// \brief Returns true if the view references a node.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
explicit operator bool() const noexcept explicit operator bool() const noexcept
{ {
return node_ != nullptr; return node_ != nullptr;
} }
/// \brief Returns the node that's being referenced by the view. /// \brief Returns the node that's being referenced by the view.
TOML_NODISCARD TOML_PURE_INLINE_GETTER
viewed_type* node() const noexcept viewed_type* node() const noexcept
{ {
return node_; return node_;
@ -124,91 +124,91 @@ TOML_NAMESPACE_START
/// @{ /// @{
/// \brief Returns the type identifier for the viewed node. /// \brief Returns the type identifier for the viewed node.
TOML_NODISCARD TOML_PURE_GETTER
node_type type() const noexcept node_type type() const noexcept
{ {
return node_ ? node_->type() : node_type::none; return node_ ? node_->type() : node_type::none;
} }
/// \brief Returns true if the viewed node is a toml::table. /// \brief Returns true if the viewed node is a toml::table.
TOML_NODISCARD TOML_PURE_GETTER
bool is_table() const noexcept bool is_table() const noexcept
{ {
return node_ && node_->is_table(); return node_ && node_->is_table();
} }
/// \brief Returns true if the viewed node is a toml::array. /// \brief Returns true if the viewed node is a toml::array.
TOML_NODISCARD TOML_PURE_GETTER
bool is_array() const noexcept bool is_array() const noexcept
{ {
return node_ && node_->is_array(); return node_ && node_->is_array();
} }
/// \brief Returns true if the viewed node is a toml::value<>. /// \brief Returns true if the viewed node is a toml::value<>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_value() const noexcept bool is_value() const noexcept
{ {
return node_ && node_->is_value(); return node_ && node_->is_value();
} }
/// \brief Returns true if the viewed node is a toml::value<string>. /// \brief Returns true if the viewed node is a toml::value<string>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_string() const noexcept bool is_string() const noexcept
{ {
return node_ && node_->is_string(); return node_ && node_->is_string();
} }
/// \brief Returns true if the viewed node is a toml::value<int64_t>. /// \brief Returns true if the viewed node is a toml::value<int64_t>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_integer() const noexcept bool is_integer() const noexcept
{ {
return node_ && node_->is_integer(); return node_ && node_->is_integer();
} }
/// \brief Returns true if the viewed node is a toml::value<double>. /// \brief Returns true if the viewed node is a toml::value<double>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_floating_point() const noexcept bool is_floating_point() const noexcept
{ {
return node_ && node_->is_floating_point(); return node_ && node_->is_floating_point();
} }
/// \brief Returns true if the viewed node is a toml::value<int64_t> or toml::value<double>. /// \brief Returns true if the viewed node is a toml::value<int64_t> or toml::value<double>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_number() const noexcept bool is_number() const noexcept
{ {
return node_ && node_->is_number(); return node_ && node_->is_number();
} }
/// \brief Returns true if the viewed node is a toml::value<bool>. /// \brief Returns true if the viewed node is a toml::value<bool>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_boolean() const noexcept bool is_boolean() const noexcept
{ {
return node_ && node_->is_boolean(); return node_ && node_->is_boolean();
} }
/// \brief Returns true if the viewed node is a toml::value<date>. /// \brief Returns true if the viewed node is a toml::value<date>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_date() const noexcept bool is_date() const noexcept
{ {
return node_ && node_->is_date(); return node_ && node_->is_date();
} }
/// \brief Returns true if the viewed node is a toml::value<time>. /// \brief Returns true if the viewed node is a toml::value<time>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_time() const noexcept bool is_time() const noexcept
{ {
return node_ && node_->is_time(); return node_ && node_->is_time();
} }
/// \brief Returns true if the viewed node is a toml::value<date_time>. /// \brief Returns true if the viewed node is a toml::value<date_time>.
TOML_NODISCARD TOML_PURE_GETTER
bool is_date_time() const noexcept bool is_date_time() const noexcept
{ {
return node_ && node_->is_date_time(); return node_ && node_->is_date_time();
} }
/// \brief Returns true if the viewed node is a toml::array that contains only tables. /// \brief Returns true if the viewed node is a toml::array that contains only tables.
TOML_NODISCARD TOML_PURE_GETTER
bool is_array_of_tables() const noexcept bool is_array_of_tables() const noexcept
{ {
return node_ && node_->is_array_of_tables(); return node_ && node_->is_array_of_tables();
@ -222,7 +222,7 @@ TOML_NAMESPACE_START
/// ///
/// \see toml::node::is() /// \see toml::node::is()
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
bool is() const noexcept bool is() const noexcept
{ {
return node_ ? node_->template is<T>() : false; return node_ ? node_->template is<T>() : false;
@ -327,7 +327,7 @@ TOML_NAMESPACE_START
/// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is /// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
/// an empty table or array. /// an empty table or array.
template <typename ElemType = void> template <typename ElemType = void>
TOML_NODISCARD TOML_PURE_GETTER
bool is_homogeneous() const noexcept bool is_homogeneous() const noexcept
{ {
return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false; return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false;
@ -338,69 +338,6 @@ TOML_NAMESPACE_START
/// \name Type casts /// \name Type casts
/// @{ /// @{
/// \brief Returns a pointer to the viewed node as a toml::table, if it is one.
TOML_NODISCARD
auto as_table() const noexcept
{
return as<table>();
}
/// \brief Returns a pointer to the viewed node as a toml::array, if it is one.
TOML_NODISCARD
auto as_array() const noexcept
{
return as<array>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<string>, if it is one.
TOML_NODISCARD
auto as_string() const noexcept
{
return as<std::string>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<int64_t>, if it is one.
TOML_NODISCARD
auto as_integer() const noexcept
{
return as<int64_t>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<double>, if it is one.
TOML_NODISCARD
auto as_floating_point() const noexcept
{
return as<double>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<bool>, if it is one.
TOML_NODISCARD
auto as_boolean() const noexcept
{
return as<bool>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<date>, if it is one.
TOML_NODISCARD
auto as_date() const noexcept
{
return as<date>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<time>, if it is one.
TOML_NODISCARD
auto as_time() const noexcept
{
return as<time>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
TOML_NODISCARD
auto as_date_time() const noexcept
{
return as<date_time>();
}
/// \brief Gets a pointer to the viewed node as a more specific node type. /// \brief Gets a pointer to the viewed node as a more specific node type.
/// ///
/// \tparam T The node type or TOML value type to cast to. /// \tparam T The node type or TOML value type to cast to.
@ -409,12 +346,75 @@ TOML_NAMESPACE_START
/// ///
/// \see toml::node::as() /// \see toml::node::as()
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
auto as() const noexcept auto as() const noexcept
{ {
return node_ ? node_->template as<T>() : nullptr; return node_ ? node_->template as<T>() : nullptr;
} }
/// \brief Returns a pointer to the viewed node as a toml::table, if it is one.
TOML_PURE_GETTER
auto as_table() const noexcept
{
return as<table>();
}
/// \brief Returns a pointer to the viewed node as a toml::array, if it is one.
TOML_PURE_GETTER
auto as_array() const noexcept
{
return as<array>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<string>, if it is one.
TOML_PURE_GETTER
auto as_string() const noexcept
{
return as<std::string>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<int64_t>, if it is one.
TOML_PURE_GETTER
auto as_integer() const noexcept
{
return as<int64_t>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<double>, if it is one.
TOML_PURE_GETTER
auto as_floating_point() const noexcept
{
return as<double>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<bool>, if it is one.
TOML_PURE_GETTER
auto as_boolean() const noexcept
{
return as<bool>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<date>, if it is one.
TOML_PURE_GETTER
auto as_date() const noexcept
{
return as<date>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<time>, if it is one.
TOML_PURE_GETTER
auto as_time() const noexcept
{
return as<time>();
}
/// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
TOML_PURE_GETTER
auto as_date_time() const noexcept
{
return as<date_time>();
}
/// @} /// @}
/// \name Value retrieval /// \name Value retrieval
@ -547,7 +547,7 @@ TOML_NAMESPACE_START
/// ///
/// \returns A reference to the underlying data. /// \returns A reference to the underlying data.
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
decltype(auto) ref() const noexcept decltype(auto) ref() const noexcept
{ {
TOML_ASSERT(node_ && "toml::node_view::ref() called on a node_view that did not reference a node"); TOML_ASSERT(node_ && "toml::node_view::ref() called on a node_view that did not reference a node");

View File

@ -279,6 +279,11 @@
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
static_assert(true) static_assert(true)
#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \
static_assert(true)
#define TOML_DISABLE_SPAM_WARNINGS \ #define TOML_DISABLE_SPAM_WARNINGS \
_Pragma("GCC diagnostic ignored \"-Wpadded\"") \ _Pragma("GCC diagnostic ignored \"-Wpadded\"") \
_Pragma("GCC diagnostic ignored \"-Wcast-align\"") \ _Pragma("GCC diagnostic ignored \"-Wcast-align\"") \
@ -289,8 +294,6 @@
_Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \
static_assert(true) static_assert(true)
#define TOML_POP_WARNINGS \ #define TOML_POP_WARNINGS \
@ -305,6 +308,7 @@
TOML_DISABLE_SWITCH_WARNINGS; \ TOML_DISABLE_SWITCH_WARNINGS; \
TOML_DISABLE_ARITHMETIC_WARNINGS; \ TOML_DISABLE_ARITHMETIC_WARNINGS; \
TOML_DISABLE_SPAM_WARNINGS; \ TOML_DISABLE_SPAM_WARNINGS; \
TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \
static_assert(true) static_assert(true)
@ -496,6 +500,9 @@
#ifndef TOML_DISABLE_SWITCH_WARNINGS #ifndef TOML_DISABLE_SWITCH_WARNINGS
#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true)
#endif #endif
#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true)
#endif
#ifndef TOML_DISABLE_SPAM_WARNINGS #ifndef TOML_DISABLE_SPAM_WARNINGS
#define TOML_DISABLE_SPAM_WARNINGS static_assert(true) #define TOML_DISABLE_SPAM_WARNINGS static_assert(true)
#endif #endif
@ -650,6 +657,24 @@
#define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__) #define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__)
#endif #endif
#define TOML_PURE_GETTER \
TOML_NODISCARD \
TOML_ATTR(pure)
#define TOML_PURE_INLINE_GETTER \
TOML_NODISCARD \
TOML_ALWAYS_INLINE \
TOML_ATTR(pure)
#define TOML_CONST_GETTER \
TOML_NODISCARD \
TOML_ATTR(const)
#define TOML_CONST_INLINE_GETTER \
TOML_NODISCARD \
TOML_ALWAYS_INLINE \
TOML_ATTR(const)
//====================================================================================================================== //======================================================================================================================
// SFINAE // SFINAE
//====================================================================================================================== //======================================================================================================================

View File

@ -78,12 +78,14 @@ TOML_POP_WARNINGS;
#undef TOML_COMPILER_EXCEPTIONS #undef TOML_COMPILER_EXCEPTIONS
#undef TOML_CONCAT #undef TOML_CONCAT
#undef TOML_CONCAT_1 #undef TOML_CONCAT_1
#undef TOML_CONST_GETTER
#undef TOML_CONST_INLINE_GETTER
#undef TOML_CONSTRAINED_TEMPLATE #undef TOML_CONSTRAINED_TEMPLATE
#undef TOML_CPP #undef TOML_CPP
#undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_ARITHMETIC_WARNINGS
#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS #undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
#undef TOML_DISABLE_SPAM_WARNINGS #undef TOML_DISABLE_SPAM_WARNINGS
#undef TOML_DISABLE_SUGGEST_WARNINGS #undef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
#undef TOML_DISABLE_SWITCH_WARNINGS #undef TOML_DISABLE_SWITCH_WARNINGS
#undef TOML_DISABLE_WARNINGS #undef TOML_DISABLE_WARNINGS
#undef TOML_EMPTY_BASES #undef TOML_EMPTY_BASES
@ -91,9 +93,9 @@ TOML_POP_WARNINGS;
#undef TOML_ENABLE_WARNINGS #undef TOML_ENABLE_WARNINGS
#undef TOML_EVAL_BOOL_0 #undef TOML_EVAL_BOOL_0
#undef TOML_EVAL_BOOL_1 #undef TOML_EVAL_BOOL_1
#undef TOML_EXTERNAL_LINKAGE
#undef TOML_EXTERN_NOEXCEPT #undef TOML_EXTERN_NOEXCEPT
#undef TOML_EXTERN_TEMPLATES #undef TOML_EXTERN_TEMPLATES
#undef TOML_EXTERNAL_LINKAGE
#undef TOML_FLOAT_CHARCONV #undef TOML_FLOAT_CHARCONV
#undef TOML_FLOAT128 #undef TOML_FLOAT128
#undef TOML_FLOAT16 #undef TOML_FLOAT16
@ -132,6 +134,8 @@ TOML_POP_WARNINGS;
#undef TOML_NODISCARD_CTOR #undef TOML_NODISCARD_CTOR
#undef TOML_PARSER_TYPENAME #undef TOML_PARSER_TYPENAME
#undef TOML_POP_WARNINGS #undef TOML_POP_WARNINGS
#undef TOML_PURE_GETTER
#undef TOML_PURE_INLINE_GETTER
#undef TOML_PUSH_WARNINGS #undef TOML_PUSH_WARNINGS
#undef TOML_REQUIRES #undef TOML_REQUIRES
#undef TOML_SA_LIST_BEG #undef TOML_SA_LIST_BEG

View File

@ -358,13 +358,15 @@ TEST_CASE("tables - insertion and erasure")
#endif // TOML_WINDOWS_COMPAT #endif // TOML_WINDOWS_COMPAT
} }
TEST_CASE("tables - printing") TEST_CASE("tables - default_formatter")
{ {
static constexpr auto to_string = [](std::string_view some_toml) static constexpr auto to_string = [](std::string_view some_toml,
format_flags flags = default_formatter::default_flags,
format_flags exclude_flags = format_flags::none)
{ {
auto val = toml::parse(some_toml); auto val = toml::parse(some_toml);
std::stringstream ss; std::stringstream ss;
ss << val; ss << default_formatter{ val, flags & ~(exclude_flags) };
return ss.str(); return ss.str();
}; };
@ -417,4 +419,136 @@ c = 3)"sv;
static constexpr auto some_toml = "key = 1\n\n[a]\nkey = 1\n\n[b]\n\n[[c]]\n\n[[c]]"sv; static constexpr auto some_toml = "key = 1\n\n[a]\nkey = 1\n\n[b]\n\n[[c]]\n\n[[c]]"sv;
CHECK(to_string(some_toml) == some_toml); CHECK(to_string(some_toml) == some_toml);
} }
{
constexpr auto input = R"(key1 = 'val1'
key2 = [ 1, 2, 3, 4, '5' ]
key3 = [ 'this is a really long array', 'and should be split over multiple lines', 'by the formatter', 'unless i dun goofed', 'i guess thats what tests are for' ]
[sub1]
key4 = 'val'
[sub2]
key5 = 'val'
[sub2.sub3]
key6 = 'val'
key7 = [ 1, 2, 3, 4, '5' ]
key8 = [ 'this is a really long array', 'and should be split over multiple lines', 'by the formatter', 'unless i dun goofed', 'i guess thats what tests are for' ])"sv;
constexpr auto expected_default = R"(key1 = 'val1'
key2 = [ 1, 2, 3, 4, '5' ]
key3 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
]
[sub1]
key4 = 'val'
[sub2]
key5 = 'val'
[sub2.sub3]
key6 = 'val'
key7 = [ 1, 2, 3, 4, '5' ]
key8 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
])"sv;
CHECK(to_string(input) == expected_default);
constexpr auto expected_without_indented_subtables = R"(key1 = 'val1'
key2 = [ 1, 2, 3, 4, '5' ]
key3 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
]
[sub1]
key4 = 'val'
[sub2]
key5 = 'val'
[sub2.sub3]
key6 = 'val'
key7 = [ 1, 2, 3, 4, '5' ]
key8 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
])"sv;
CHECK(to_string(input, default_formatter::default_flags, format_flags::indent_sub_tables)
== expected_without_indented_subtables);
constexpr auto expected_without_indented_arrays = R"(key1 = 'val1'
key2 = [ 1, 2, 3, 4, '5' ]
key3 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
]
[sub1]
key4 = 'val'
[sub2]
key5 = 'val'
[sub2.sub3]
key6 = 'val'
key7 = [ 1, 2, 3, 4, '5' ]
key8 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
])"sv;
CHECK(to_string(input, default_formatter::default_flags, format_flags::indent_array_elements)
== expected_without_indented_arrays);
constexpr auto expected_without_indentation = R"(key1 = 'val1'
key2 = [ 1, 2, 3, 4, '5' ]
key3 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
]
[sub1]
key4 = 'val'
[sub2]
key5 = 'val'
[sub2.sub3]
key6 = 'val'
key7 = [ 1, 2, 3, 4, '5' ]
key8 = [
'this is a really long array',
'and should be split over multiple lines',
'by the formatter',
'unless i dun goofed',
'i guess thats what tests are for'
])"sv;
CHECK(to_string(input, default_formatter::default_flags, format_flags::indentation)
== expected_without_indentation);
}
} }

View File

@ -88,7 +88,7 @@ TEST_CASE("values - construction")
#endif #endif
} }
TEST_CASE("values - printing") TEST_CASE("values - default_formatter")
{ {
static constexpr auto print_value = [](auto&& raw) static constexpr auto print_value = [](auto&& raw)
{ {

View File

@ -220,8 +220,8 @@ namespace Catch
{ {
template struct StringMaker<node_view<node>>; template struct StringMaker<node_view<node>>;
template struct StringMaker<node_view<const node>>; template struct StringMaker<node_view<const node>>;
template ReusableStringStream& ReusableStringStream::operator<<(toml::node_view<toml::node> const&); template ReusableStringStream& ReusableStringStream::operator<<(node_view<node> const&);
template ReusableStringStream& ReusableStringStream::operator<<(toml::node_view<const toml::node> const&); template ReusableStringStream& ReusableStringStream::operator<<(node_view<const node> const&);
namespace Detail namespace Detail
{ {
template std::string stringify(const node_view<node>&); template std::string stringify(const node_view<node>&);

View File

@ -30,15 +30,18 @@
#if defined(TOML_INT128) ^ defined(TOML_UINT128) #if defined(TOML_INT128) ^ defined(TOML_UINT128)
#error TOML_INT128 and TOML_UINT128 must both be defined, or neither be defined #error TOML_INT128 and TOML_UINT128 must both be defined, or neither be defined
#endif #endif
#if TOML_COMPILER_EXCEPTIONS != SHOULD_HAVE_EXCEPTIONS #if TOML_COMPILER_EXCEPTIONS ^ SHOULD_HAVE_EXCEPTIONS
#error TOML_COMPILER_EXCEPTIONS was not deduced correctly #error TOML_COMPILER_EXCEPTIONS was not deduced correctly
#endif #endif
#if TOML_COMPILER_EXCEPTIONS != TOML_EXCEPTIONS #if TOML_COMPILER_EXCEPTIONS ^ TOML_EXCEPTIONS
#error TOML_EXCEPTIONS does not match TOML_COMPILER_EXCEPTIONS (default behaviour should be to match) #error TOML_EXCEPTIONS does not match TOML_COMPILER_EXCEPTIONS (default behaviour should be to match)
#endif #endif
#if (defined(_WIN32) && !TOML_WINDOWS_COMPAT) || (!defined(_WIN32) && TOML_WINDOWS_COMPAT) #if defined(_WIN32) ^ TOML_WINDOWS_COMPAT
#error TOML_WINDOWS_COMPAT does not match _WIN32 (default behaviour should be to match) #error TOML_WINDOWS_COMPAT does not match _WIN32 (default behaviour should be to match)
#endif #endif
#if !(TOML_HEADER_ONLY ^ TOML_EXTERN_TEMPLATES) && !TOML_INTELLISENSE
#error TOML_EXTERN_TEMPLATES should hold the opposite value to TOML_HEADER_ONLY by default
#endif
#if TOML_ICC #if TOML_ICC
#define UNICODE_LITERALS_OK 0 #define UNICODE_LITERALS_OK 0
@ -130,7 +133,7 @@ class function_view<R(P...)> final
} }
}; };
using pss_func = function_view<void(toml::table&&)>; using pss_func = function_view<void(table&&)>;
bool parsing_should_succeed(std::string_view test_file, bool parsing_should_succeed(std::string_view test_file,
uint32_t test_line, uint32_t test_line,

326
toml.hpp
View File

@ -303,6 +303,11 @@
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \ _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
static_assert(true) static_assert(true)
#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \
static_assert(true)
#define TOML_DISABLE_SPAM_WARNINGS \ #define TOML_DISABLE_SPAM_WARNINGS \
_Pragma("GCC diagnostic ignored \"-Wpadded\"") \ _Pragma("GCC diagnostic ignored \"-Wpadded\"") \
_Pragma("GCC diagnostic ignored \"-Wcast-align\"") \ _Pragma("GCC diagnostic ignored \"-Wcast-align\"") \
@ -313,8 +318,6 @@
_Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \ _Pragma("GCC diagnostic ignored \"-Wsubobject-linkage\"") \
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \ _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") \
_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=pure\"") \
static_assert(true) static_assert(true)
#define TOML_POP_WARNINGS \ #define TOML_POP_WARNINGS \
@ -329,6 +332,7 @@
TOML_DISABLE_SWITCH_WARNINGS; \ TOML_DISABLE_SWITCH_WARNINGS; \
TOML_DISABLE_ARITHMETIC_WARNINGS; \ TOML_DISABLE_ARITHMETIC_WARNINGS; \
TOML_DISABLE_SPAM_WARNINGS; \ TOML_DISABLE_SPAM_WARNINGS; \
TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \
static_assert(true) static_assert(true)
#define TOML_ENABLE_WARNINGS \ #define TOML_ENABLE_WARNINGS \
@ -511,6 +515,9 @@
#ifndef TOML_DISABLE_SWITCH_WARNINGS #ifndef TOML_DISABLE_SWITCH_WARNINGS
#define TOML_DISABLE_SWITCH_WARNINGS static_assert(true) #define TOML_DISABLE_SWITCH_WARNINGS static_assert(true)
#endif #endif
#ifndef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS static_assert(true)
#endif
#ifndef TOML_DISABLE_SPAM_WARNINGS #ifndef TOML_DISABLE_SPAM_WARNINGS
#define TOML_DISABLE_SPAM_WARNINGS static_assert(true) #define TOML_DISABLE_SPAM_WARNINGS static_assert(true)
#endif #endif
@ -664,6 +671,24 @@
#define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__) #define TOML_EXTERN_NOEXCEPT(...) noexcept(__VA_ARGS__)
#endif #endif
#define TOML_PURE_GETTER \
TOML_NODISCARD \
TOML_ATTR(pure)
#define TOML_PURE_INLINE_GETTER \
TOML_NODISCARD \
TOML_ALWAYS_INLINE \
TOML_ATTR(pure)
#define TOML_CONST_GETTER \
TOML_NODISCARD \
TOML_ATTR(const)
#define TOML_CONST_INLINE_GETTER \
TOML_NODISCARD \
TOML_ALWAYS_INLINE \
TOML_ATTR(const)
// SFINAE // SFINAE
#if defined(__cpp_concepts) && __cpp_concepts >= 201907 #if defined(__cpp_concepts) && __cpp_concepts >= 201907
#define TOML_REQUIRES(...) requires(__VA_ARGS__) #define TOML_REQUIRES(...) requires(__VA_ARGS__)
@ -1142,7 +1167,7 @@ TOML_NAMESPACE_START // abi namespace
} }
} }
enum class value_flags : uint8_t enum class value_flags : uint16_t
{ {
none, none,
format_as_binary = 1, format_as_binary = 1,
@ -1151,13 +1176,16 @@ TOML_NAMESPACE_START // abi namespace
}; };
TOML_MAKE_FLAGS(value_flags); TOML_MAKE_FLAGS(value_flags);
enum class format_flags : uint8_t enum class format_flags : uint64_t
{ {
none, none,
quote_dates_and_times = 1, quote_dates_and_times = 1,
allow_literal_strings = 2, allow_literal_strings = 2,
allow_multi_line_strings = 4, allow_multi_line_strings = 4,
allow_value_format_flags = 8, allow_value_format_flags = 8,
indent_sub_tables = 16,
indent_array_elements = 32,
indentation = indent_sub_tables | indent_array_elements,
}; };
TOML_MAKE_FLAGS(format_flags); TOML_MAKE_FLAGS(format_flags);
@ -2253,8 +2281,7 @@ TOML_NAMESPACE_START
decltype(auto) get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>); decltype(auto) get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
template <typename T, typename N> template <typename T, typename N>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
static decltype(auto) do_ref(N&& n) noexcept static decltype(auto) do_ref(N&& n) noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -2285,27 +2312,21 @@ TOML_NAMESPACE_START
node& operator=(node&&) noexcept; node& operator=(node&&) noexcept;
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
impl::wrap_node<T>& ref_cast() & noexcept impl::wrap_node<T>& ref_cast() & noexcept
{ {
return *reinterpret_cast<impl::wrap_node<T>*>(this); return *reinterpret_cast<impl::wrap_node<T>*>(this);
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
impl::wrap_node<T>&& ref_cast() && noexcept impl::wrap_node<T>&& ref_cast() && noexcept
{ {
return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this)); return std::move(*reinterpret_cast<impl::wrap_node<T>*>(this));
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
TOML_ATTR(pure)
const impl::wrap_node<T>& ref_cast() const& noexcept const impl::wrap_node<T>& ref_cast() const& noexcept
{ {
return *reinterpret_cast<const impl::wrap_node<T>*>(this); return *reinterpret_cast<const impl::wrap_node<T>*>(this);
@ -2321,81 +2342,80 @@ TOML_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
virtual node_type type() const noexcept = 0; virtual node_type type() const noexcept = 0;
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_table() const noexcept virtual bool is_table() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_array() const noexcept virtual bool is_array() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_value() const noexcept virtual bool is_value() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_string() const noexcept virtual bool is_string() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_integer() const noexcept virtual bool is_integer() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_floating_point() const noexcept virtual bool is_floating_point() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_number() const noexcept virtual bool is_number() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_boolean() const noexcept virtual bool is_boolean() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_date() const noexcept virtual bool is_date() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_time() const noexcept virtual bool is_time() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_date_time() const noexcept virtual bool is_date_time() const noexcept
{ {
return false; return false;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual bool is_array_of_tables() const noexcept virtual bool is_array_of_tables() const noexcept
{ {
return false; return false;
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
bool is() const noexcept bool is() const noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -2432,8 +2452,7 @@ TOML_NAMESPACE_START
virtual bool is_homogeneous(node_type ntype) const noexcept = 0; virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
template <typename ElemType = void> template <typename ElemType = void>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
bool is_homogeneous() const noexcept bool is_homogeneous() const noexcept
{ {
using type = impl::unwrap_node<ElemType>; using type = impl::unwrap_node<ElemType>;
@ -2445,117 +2464,116 @@ TOML_NAMESPACE_START
return is_homogeneous(impl::node_type_of<type>); return is_homogeneous(impl::node_type_of<type>);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual table* as_table() noexcept virtual table* as_table() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual array* as_array() noexcept virtual array* as_array() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<std::string>* as_string() noexcept virtual toml::value<std::string>* as_string() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<int64_t>* as_integer() noexcept virtual toml::value<int64_t>* as_integer() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<double>* as_floating_point() noexcept virtual toml::value<double>* as_floating_point() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<bool>* as_boolean() noexcept virtual toml::value<bool>* as_boolean() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<date>* as_date() noexcept virtual toml::value<date>* as_date() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<time>* as_time() noexcept virtual toml::value<time>* as_time() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual toml::value<date_time>* as_date_time() noexcept virtual toml::value<date_time>* as_date_time() noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const table* as_table() const noexcept virtual const table* as_table() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const array* as_array() const noexcept virtual const array* as_array() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<std::string>* as_string() const noexcept virtual const toml::value<std::string>* as_string() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<int64_t>* as_integer() const noexcept virtual const toml::value<int64_t>* as_integer() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<double>* as_floating_point() const noexcept virtual const toml::value<double>* as_floating_point() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<bool>* as_boolean() const noexcept virtual const toml::value<bool>* as_boolean() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<date>* as_date() const noexcept virtual const toml::value<date>* as_date() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<time>* as_time() const noexcept virtual const toml::value<time>* as_time() const noexcept
{ {
return nullptr; return nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
virtual const toml::value<date_time>* as_date_time() const noexcept virtual const toml::value<date_time>* as_date_time() const noexcept
{ {
return nullptr; return nullptr;
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
impl::wrap_node<T>* as() noexcept impl::wrap_node<T>* as() noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -2583,8 +2601,7 @@ TOML_NAMESPACE_START
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ATTR(pure)
const impl::wrap_node<T>* as() const noexcept const impl::wrap_node<T>* as() const noexcept
{ {
using type = impl::unwrap_node<T>; using type = impl::unwrap_node<T>;
@ -2624,30 +2641,27 @@ TOML_NAMESPACE_START
auto value_or(T&& default_value) const noexcept(impl::value_retrieval_is_nothrow<T>); auto value_or(T&& default_value) const noexcept(impl::value_retrieval_is_nothrow<T>);
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
impl::unwrap_node<T>& ref() & noexcept impl::unwrap_node<T>& ref() & noexcept
{ {
return do_ref<T>(*this); return do_ref<T>(*this);
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
impl::unwrap_node<T>&& ref() && noexcept impl::unwrap_node<T>&& ref() && noexcept
{ {
return do_ref<T>(std::move(*this)); return do_ref<T>(std::move(*this));
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
TOML_ATTR(pure)
const impl::unwrap_node<T>& ref() const& noexcept const impl::unwrap_node<T>& ref() const& noexcept
{ {
return do_ref<T>(*this); return do_ref<T>(*this);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
const source_region& source() const noexcept const source_region& source() const noexcept
{ {
return source_; return source_;
@ -2890,105 +2904,105 @@ TOML_NAMESPACE_START
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
node_view(const node_view&) noexcept = default; node_view(const node_view&) noexcept = default;
node_view& operator=(const node_view&) & noexcept = default;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
node_view(node_view&&) noexcept = default; node_view(node_view&&) noexcept = default;
node_view& operator=(const node_view&) & noexcept = default;
node_view& operator=(node_view&&) & noexcept = default; node_view& operator=(node_view&&) & noexcept = default;
TOML_NODISCARD TOML_PURE_INLINE_GETTER
explicit operator bool() const noexcept explicit operator bool() const noexcept
{ {
return node_ != nullptr; return node_ != nullptr;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
viewed_type* node() const noexcept viewed_type* node() const noexcept
{ {
return node_; return node_;
} }
TOML_NODISCARD TOML_PURE_GETTER
node_type type() const noexcept node_type type() const noexcept
{ {
return node_ ? node_->type() : node_type::none; return node_ ? node_->type() : node_type::none;
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_table() const noexcept bool is_table() const noexcept
{ {
return node_ && node_->is_table(); return node_ && node_->is_table();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_array() const noexcept bool is_array() const noexcept
{ {
return node_ && node_->is_array(); return node_ && node_->is_array();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_value() const noexcept bool is_value() const noexcept
{ {
return node_ && node_->is_value(); return node_ && node_->is_value();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_string() const noexcept bool is_string() const noexcept
{ {
return node_ && node_->is_string(); return node_ && node_->is_string();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_integer() const noexcept bool is_integer() const noexcept
{ {
return node_ && node_->is_integer(); return node_ && node_->is_integer();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_floating_point() const noexcept bool is_floating_point() const noexcept
{ {
return node_ && node_->is_floating_point(); return node_ && node_->is_floating_point();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_number() const noexcept bool is_number() const noexcept
{ {
return node_ && node_->is_number(); return node_ && node_->is_number();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_boolean() const noexcept bool is_boolean() const noexcept
{ {
return node_ && node_->is_boolean(); return node_ && node_->is_boolean();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_date() const noexcept bool is_date() const noexcept
{ {
return node_ && node_->is_date(); return node_ && node_->is_date();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_time() const noexcept bool is_time() const noexcept
{ {
return node_ && node_->is_time(); return node_ && node_->is_time();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_date_time() const noexcept bool is_date_time() const noexcept
{ {
return node_ && node_->is_date_time(); return node_ && node_->is_date_time();
} }
TOML_NODISCARD TOML_PURE_GETTER
bool is_array_of_tables() const noexcept bool is_array_of_tables() const noexcept
{ {
return node_ && node_->is_array_of_tables(); return node_ && node_->is_array_of_tables();
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_GETTER
bool is() const noexcept bool is() const noexcept
{ {
return node_ ? node_->template is<T>() : false; return node_ ? node_->template is<T>() : false;
@ -3012,73 +3026,73 @@ TOML_NAMESPACE_START
} }
template <typename ElemType = void> template <typename ElemType = void>
TOML_NODISCARD TOML_PURE_GETTER
bool is_homogeneous() const noexcept bool is_homogeneous() const noexcept
{ {
return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false; return node_ ? node_->template is_homogeneous<impl::unwrap_node<ElemType>>() : false;
} }
TOML_NODISCARD template <typename T>
TOML_PURE_GETTER
auto as() const noexcept
{
return node_ ? node_->template as<T>() : nullptr;
}
TOML_PURE_GETTER
auto as_table() const noexcept auto as_table() const noexcept
{ {
return as<table>(); return as<table>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_array() const noexcept auto as_array() const noexcept
{ {
return as<array>(); return as<array>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_string() const noexcept auto as_string() const noexcept
{ {
return as<std::string>(); return as<std::string>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_integer() const noexcept auto as_integer() const noexcept
{ {
return as<int64_t>(); return as<int64_t>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_floating_point() const noexcept auto as_floating_point() const noexcept
{ {
return as<double>(); return as<double>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_boolean() const noexcept auto as_boolean() const noexcept
{ {
return as<bool>(); return as<bool>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_date() const noexcept auto as_date() const noexcept
{ {
return as<date>(); return as<date>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_time() const noexcept auto as_time() const noexcept
{ {
return as<time>(); return as<time>();
} }
TOML_NODISCARD TOML_PURE_GETTER
auto as_date_time() const noexcept auto as_date_time() const noexcept
{ {
return as<date_time>(); return as<date_time>();
} }
template <typename T>
TOML_NODISCARD
auto as() const noexcept
{
return node_ ? node_->template as<T>() : nullptr;
}
template <typename T> template <typename T>
TOML_NODISCARD TOML_NODISCARD
optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>) optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>)
@ -3138,7 +3152,7 @@ TOML_NAMESPACE_START
} }
template <typename T> template <typename T>
TOML_NODISCARD TOML_PURE_INLINE_GETTER
decltype(auto) ref() const noexcept decltype(auto) ref() const noexcept
{ {
TOML_ASSERT(node_ && "toml::node_view::ref() called on a node_view that did not reference a node"); TOML_ASSERT(node_ && "toml::node_view::ref() called on a node_view that did not reference a node");
@ -7368,32 +7382,30 @@ TOML_IMPL_NAMESPACE_START
private: private:
const toml::node* source_; const toml::node* source_;
std::ostream* stream_ = {}; std::ostream* stream_ = {};
format_flags flags_; format_flags flags_; //
int indent_; int indent_; // these are set in attach()
bool naked_newline_; bool naked_newline_; //
#if TOML_PARSER && !TOML_EXCEPTIONS #if TOML_PARSER && !TOML_EXCEPTIONS
const parse_result* result_ = {}; const parse_result* result_ = {};
#endif #endif
protected: protected:
TOML_NODISCARD static constexpr size_t indent_columns = 4;
TOML_ALWAYS_INLINE static constexpr std::string_view indent_string = " "sv;
TOML_PURE_INLINE_GETTER
const toml::node& source() const noexcept const toml::node& source() const noexcept
{ {
return *source_; return *source_;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
TOML_ALWAYS_INLINE
std::ostream& stream() const noexcept std::ostream& stream() const noexcept
{ {
return *stream_; return *stream_;
} }
static constexpr size_t indent_columns = 4; TOML_PURE_INLINE_GETTER
static constexpr std::string_view indent_string = " "sv;
TOML_NODISCARD
int indent() const noexcept int indent() const noexcept
{ {
return indent_; return indent_;
@ -7414,31 +7426,43 @@ TOML_IMPL_NAMESPACE_START
indent_--; indent_--;
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool indent_array_elements() const noexcept
{
return !!(flags_ & format_flags::indent_array_elements);
}
TOML_PURE_INLINE_GETTER
bool indent_sub_tables() const noexcept
{
return !!(flags_ & format_flags::indent_sub_tables);
}
TOML_PURE_INLINE_GETTER
bool quote_dates_and_times() const noexcept bool quote_dates_and_times() const noexcept
{ {
return !!(flags_ & format_flags::quote_dates_and_times); return !!(flags_ & format_flags::quote_dates_and_times);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool literal_strings_allowed() const noexcept bool literal_strings_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_literal_strings); return !!(flags_ & format_flags::allow_literal_strings);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool multi_line_strings_allowed() const noexcept bool multi_line_strings_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_multi_line_strings); return !!(flags_ & format_flags::allow_multi_line_strings);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool value_format_flags_allowed() const noexcept bool value_format_flags_allowed() const noexcept
{ {
return !!(flags_ & format_flags::allow_value_format_flags); return !!(flags_ & format_flags::allow_value_format_flags);
} }
TOML_NODISCARD TOML_PURE_INLINE_GETTER
bool naked_newline() const noexcept bool naked_newline() const noexcept
{ {
return naked_newline_; return naked_newline_;
@ -7562,22 +7586,26 @@ TOML_NAMESPACE_START
TOML_API TOML_API
void print(); void print();
static constexpr format_flags mandatory_flags = format_flags::none;
static constexpr format_flags ignored_flags = format_flags::none;
public: public:
static constexpr format_flags default_flags = format_flags::allow_literal_strings static constexpr format_flags default_flags = format_flags::allow_literal_strings //
| format_flags::allow_multi_line_strings | format_flags::allow_multi_line_strings //
| format_flags::allow_value_format_flags; | format_flags::allow_value_format_flags //
| format_flags::indentation;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags } : base{ source, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS) #if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags } : base{ result, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#endif #endif
@ -7624,20 +7652,25 @@ TOML_NAMESPACE_START
TOML_API TOML_API
void print(); void print();
static constexpr format_flags mandatory_flags = format_flags::quote_dates_and_times;
static constexpr format_flags ignored_flags =
format_flags::allow_literal_strings | format_flags::allow_multi_line_strings;
public: public:
static constexpr format_flags default_flags = format_flags::quote_dates_and_times; static constexpr format_flags default_flags = format_flags::quote_dates_and_times //
| format_flags::indentation;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
: base{ source, flags } : base{ source, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS) #if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
: base{ result, flags } : base{ result, (flags | mandatory_flags) & ~ignored_flags }
{} {}
#endif #endif
@ -12614,18 +12647,29 @@ TOML_IMPL_NAMESPACE_START
} }
} }
TOML_EXTERNAL_LINKAGE
bool formatter::dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS)
{
#if TOML_PARSER && !TOML_EXCEPTIONS #if TOML_PARSER && !TOML_EXCEPTIONS
TOML_EXTERNAL_LINKAGE
bool formatter::dump_failed_parse_result() noexcept(false)
{
if (result_ && !(*result_)) if (result_ && !(*result_))
{ {
stream() << result_->error(); stream() << result_->error();
return true; return true;
} }
#endif
return false; return false;
} }
#else
TOML_EXTERNAL_LINKAGE
TOML_ATTR(const)
bool formatter::dump_failed_parse_result() noexcept(true)
{
return false;
}
#endif
} }
TOML_IMPL_NAMESPACE_END; TOML_IMPL_NAMESPACE_END;
@ -12878,7 +12922,8 @@ TOML_NAMESPACE_START
{ {
if (original_indent < 0) if (original_indent < 0)
base::indent(0); base::indent(0);
base::increase_indent(); if (base::indent_array_elements())
base::increase_indent();
} }
else else
impl::print_to_stream(base::stream(), ' '); impl::print_to_stream(base::stream(), ' ');
@ -12998,7 +13043,8 @@ TOML_NAMESPACE_START
if (!skip_self) if (!skip_self)
{ {
print_pending_table_separator(); print_pending_table_separator();
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), "["sv); impl::print_to_stream(base::stream(), "["sv);
print_key_path(); print_key_path();
@ -13009,7 +13055,7 @@ TOML_NAMESPACE_START
print(child_tbl); print(child_tbl);
key_path_.pop_back(); key_path_.pop_back();
if (!skip_self) if (!skip_self && base::indent_sub_tables())
base::decrease_indent(); base::decrease_indent();
} }
@ -13020,7 +13066,8 @@ TOML_NAMESPACE_START
continue; continue;
auto& arr = *reinterpret_cast<const array*>(&v); auto& arr = *reinterpret_cast<const array*>(&v);
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
key_path_.push_back(make_key_segment(k)); key_path_.push_back(make_key_segment(k));
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
@ -13035,7 +13082,8 @@ TOML_NAMESPACE_START
} }
key_path_.pop_back(); key_path_.pop_back();
base::decrease_indent(); if (base::indent_sub_tables())
base::decrease_indent();
} }
} }
@ -13086,7 +13134,8 @@ TOML_NAMESPACE_START
else else
{ {
impl::print_to_stream(base::stream(), '{'); impl::print_to_stream(base::stream(), '{');
base::increase_indent(); if (base::indent_sub_tables())
base::increase_indent();
bool first = false; bool first = false;
for (auto&& [k, v] : tbl) for (auto&& [k, v] : tbl)
{ {
@ -13108,7 +13157,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type); default: base::print_value(v, type);
} }
} }
base::decrease_indent(); if (base::indent_sub_tables())
base::decrease_indent();
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), '}'); impl::print_to_stream(base::stream(), '}');
@ -13124,7 +13174,8 @@ TOML_NAMESPACE_START
else else
{ {
impl::print_to_stream(base::stream(), '['); impl::print_to_stream(base::stream(), '[');
base::increase_indent(); if (base::indent_array_elements())
base::increase_indent();
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0u) if (i > 0u)
@ -13142,7 +13193,8 @@ TOML_NAMESPACE_START
default: base::print_value(v, type); default: base::print_value(v, type);
} }
} }
base::decrease_indent(); if (base::indent_array_elements())
base::decrease_indent();
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();
impl::print_to_stream(base::stream(), ']'); impl::print_to_stream(base::stream(), ']');
@ -13192,12 +13244,14 @@ TOML_POP_WARNINGS;
#undef TOML_COMPILER_EXCEPTIONS #undef TOML_COMPILER_EXCEPTIONS
#undef TOML_CONCAT #undef TOML_CONCAT
#undef TOML_CONCAT_1 #undef TOML_CONCAT_1
#undef TOML_CONST_GETTER
#undef TOML_CONST_INLINE_GETTER
#undef TOML_CONSTRAINED_TEMPLATE #undef TOML_CONSTRAINED_TEMPLATE
#undef TOML_CPP #undef TOML_CPP
#undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_ARITHMETIC_WARNINGS
#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS #undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
#undef TOML_DISABLE_SPAM_WARNINGS #undef TOML_DISABLE_SPAM_WARNINGS
#undef TOML_DISABLE_SUGGEST_WARNINGS #undef TOML_DISABLE_SUGGEST_ATTR_WARNINGS
#undef TOML_DISABLE_SWITCH_WARNINGS #undef TOML_DISABLE_SWITCH_WARNINGS
#undef TOML_DISABLE_WARNINGS #undef TOML_DISABLE_WARNINGS
#undef TOML_EMPTY_BASES #undef TOML_EMPTY_BASES
@ -13205,9 +13259,9 @@ TOML_POP_WARNINGS;
#undef TOML_ENABLE_WARNINGS #undef TOML_ENABLE_WARNINGS
#undef TOML_EVAL_BOOL_0 #undef TOML_EVAL_BOOL_0
#undef TOML_EVAL_BOOL_1 #undef TOML_EVAL_BOOL_1
#undef TOML_EXTERNAL_LINKAGE
#undef TOML_EXTERN_NOEXCEPT #undef TOML_EXTERN_NOEXCEPT
#undef TOML_EXTERN_TEMPLATES #undef TOML_EXTERN_TEMPLATES
#undef TOML_EXTERNAL_LINKAGE
#undef TOML_FLOAT_CHARCONV #undef TOML_FLOAT_CHARCONV
#undef TOML_FLOAT128 #undef TOML_FLOAT128
#undef TOML_FLOAT16 #undef TOML_FLOAT16
@ -13246,6 +13300,8 @@ TOML_POP_WARNINGS;
#undef TOML_NODISCARD_CTOR #undef TOML_NODISCARD_CTOR
#undef TOML_PARSER_TYPENAME #undef TOML_PARSER_TYPENAME
#undef TOML_POP_WARNINGS #undef TOML_POP_WARNINGS
#undef TOML_PURE_GETTER
#undef TOML_PURE_INLINE_GETTER
#undef TOML_PUSH_WARNINGS #undef TOML_PUSH_WARNINGS
#undef TOML_REQUIRES #undef TOML_REQUIRES
#undef TOML_SA_LIST_BEG #undef TOML_SA_LIST_BEG