diff --git a/README.md b/README.md
index 766c01d..61cd7be 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ toml++.
| `TOML_ASSERT(expr)` | function macro | `assert(expr)`
(or undefined) | Sets the assert function used by the library. |
| `TOML_CHAR_8_STRINGS` | boolean | `0` | Uses C++20 [char8_t]-based strings as the toml string data type. |
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
+| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
| `TOML_UNDEF_MACROS` | boolean | `1` | `#undefs` the library's internal macros at the end of the header. |
| `TOML_UNRELEASED_FEATURES` | boolean | `1` | Enables support for [unreleased TOML language features] not yet part of a [numbered version]. |
diff --git a/examples/example.toml b/examples/example.toml
index c7ad462..e9102d1 100644
--- a/examples/example.toml
+++ b/examples/example.toml
@@ -10,6 +10,7 @@ int2 = 9223372036854775807
flt1 = 0.00000000001
flt2 = 1e-11
flt3 = 11.0
+flt4 = +1.0
# hexadecimal with prefix `0x`
hex1 = 0xDEADBEEF
diff --git a/examples/toml_to_json_transcoder.cpp b/examples/toml_to_json_transcoder.cpp
index 254fcf8..5a17cc2 100644
--- a/examples/toml_to_json_transcoder.cpp
+++ b/examples/toml_to_json_transcoder.cpp
@@ -27,7 +27,7 @@ int main(int argc, char** argv)
try
{
const auto table = toml::parse(file, std::move(path));
- std::cout << table << std::endl;
+ std::cout << toml::json_formatter{ table } << std::endl;
}
catch (const toml::parse_error & err)
{
@@ -49,7 +49,7 @@ int main(int argc, char** argv)
const auto table = toml::parse(std::cin);
std::cout << toml::json_formatter{ table } << std::endl;
}
- catch (const toml::parse_error & err)
+ catch (const toml::parse_error& err)
{
std::cerr
<< "Error parsing stdin:\n"sv << err.what()
diff --git a/include/toml++/toml.h b/include/toml++/toml.h
index 4351f2e..70d9323 100644
--- a/include/toml++/toml.h
+++ b/include/toml++/toml.h
@@ -5,6 +5,7 @@
//# is used as the source for generate_single_header.py.
#include "toml_common.h"
+#include "toml_print_to_stream.h"
#include "toml_node.h"
#include "toml_table.h"
#include "toml_array.h"
@@ -20,10 +21,10 @@
#if TOML_UNDEF_MACROS
#undef TOML_EXCEPTIONS
#undef TOML_USE_STREAMS_FOR_FLOATS
+ #undef TOML_GCC_ATTR
#undef TOML_PUSH_WARNINGS
- #undef TOML_DISABLE_SWITCH_WARNING
- #undef TOML_DISABLE_FIELD_INIT_WARNING
- #undef TOML_DISABLE_VAR_INIT_WARNING
+ #undef TOML_DISABLE_SWITCH_WARNINGS
+ #undef TOML_DISABLE_INIT_WARNINGS
#undef TOML_DISABLE_ALL_WARNINGS
#undef TOML_POP_WARNINGS
#undef TOML_ALWAYS_INLINE
@@ -31,6 +32,7 @@
#undef TOML_UNREACHABLE
#undef TOML_INTERFACE
#undef TOML_EMPTY_BASES
+ #undef TOML_CPP_VERSION
#undef TOML_CPP
#undef TOML_CONDITIONAL_NOEXCEPT
#undef TOML_MAY_THROW
diff --git a/include/toml++/toml_array.h b/include/toml++/toml_array.h
index c82e4ca..f37618a 100644
--- a/include/toml++/toml_array.h
+++ b/include/toml++/toml_array.h
@@ -1,6 +1,82 @@
#pragma once
#include "toml_node.h"
+namespace toml::impl
+{
+ template
+ class array_iterator final
+ {
+ private:
+ friend class toml::array;
+
+ using raw_iterator = std::conditional_t<
+ is_const,
+ std::vector>::const_iterator,
+ std::vector>::iterator
+ >;
+
+ mutable raw_iterator raw_;
+
+ array_iterator(const raw_iterator& raw) noexcept
+ : raw_{ raw }
+ {}
+
+ array_iterator(raw_iterator&& raw) noexcept
+ : raw_{ std::move(raw) }
+ {}
+
+ public:
+
+ array_iterator() noexcept = default;
+
+ using reference = std::conditional_t;
+
+ array_iterator& operator++() noexcept // ++pre
+ {
+ ++raw_;
+ return *this;
+ }
+
+ array_iterator operator++(int) noexcept // post++
+ {
+ array_iterator out{ raw_ };
+ ++raw_;
+ return out;
+ }
+
+ array_iterator& operator--() noexcept // --pre
+ {
+ --raw_;
+ return *this;
+ }
+
+ array_iterator operator--(int) noexcept // post--
+ {
+ array_iterator out{ raw_ };
+ --raw_;
+ return out;
+ }
+
+ [[nodiscard]]
+ reference operator* () const noexcept
+ {
+ return *raw_->get();
+ }
+
+ [[nodiscard]]
+ friend constexpr bool operator == (const array_iterator& lhs, const array_iterator& rhs) noexcept
+ {
+ return lhs.raw_ == rhs.raw_;
+ }
+
+ [[nodiscard]]
+ friend constexpr bool operator != (const array_iterator& lhs, const array_iterator& rhs) noexcept
+ {
+ return lhs.raw_ != rhs.raw_;
+ }
+ };
+}
+
namespace toml
{
class array final
@@ -12,6 +88,9 @@ namespace toml
public:
+ using iterator = impl::array_iterator;
+ using const_iterator = impl::array_iterator;
+
TOML_NODISCARD_CTOR
array() noexcept = default;
@@ -27,8 +106,12 @@ namespace toml
values = std::move(rhs.values);
return *this;
}
+
+ [[nodiscard]] node_type type() const noexcept override { return node_type::array; }
+ [[nodiscard]] bool is_table() const noexcept override { return false; }
[[nodiscard]] bool is_array() const noexcept override { return true; }
+ [[nodiscard]] bool is_value() const noexcept override { return false; }
[[nodiscard]] bool is_array_of_tables() const noexcept override
{
@@ -42,40 +125,56 @@ namespace toml
return true;
}
+ template
[[nodiscard]] bool is_homogeneous() const noexcept
{
- if (values.size() <= 1_sz)
- return true;
+ if (values.empty())
+ return false;
- const auto type = values[0]->type();
- for (size_t i = 1; i < values.size(); i++)
- if (values[i]->type() != type)
- return false;
+ if constexpr (std::is_same_v)
+ {
+ const auto type = values[0]->type();
+ for (size_t i = 1; i < values.size(); i++)
+ if (values[i]->type() != type)
+ return false;
+ }
+ else
+ {
+ for (auto& v : values)
+ if (!v->is())
+ return false;
+ }
return true;
}
[[nodiscard]] array* as_array() noexcept override { return this; }
[[nodiscard]] const array* as_array() const noexcept override { return this; }
- [[nodiscard]] node_type type() const noexcept override { return node_type::array; }
-
[[nodiscard]] bool empty() const noexcept { return values.empty(); }
-
[[nodiscard]] size_t size() const noexcept { return values.size(); }
- [[nodiscard]] node* get(size_t index) noexcept { return values[index].get(); }
- [[nodiscard]] const node* get(size_t index) const noexcept { return values[index].get(); }
+ [[nodiscard]] node& operator[] (size_t index) & noexcept { return *values[index].get(); }
+ [[nodiscard]] node&& operator[] (size_t index) && noexcept { return std::move(*values[index].get()); }
+ [[nodiscard]] const node& operator[] (size_t index) const& noexcept { return *values[index].get(); }
template
[[nodiscard]] node_of* get_as(size_t index) noexcept
{
- return get(index)->as();
+ return values[index]->as();
}
template
[[nodiscard]] const node_of* get_as(size_t index) const noexcept
{
- return get(index)->as();
+ return values[index]->as();
}
+
+ [[nodiscard]] iterator begin() noexcept { return { values.begin() }; }
+ [[nodiscard]] const_iterator begin() const noexcept { return { values.begin() }; }
+ [[nodiscard]] const_iterator cbegin() const noexcept { return { values.cbegin() }; }
+
+ [[nodiscard]] iterator end() noexcept { return { values.end() }; }
+ [[nodiscard]] const_iterator end() const noexcept { return { values.end() }; }
+ [[nodiscard]] const_iterator cend() const noexcept { return { values.cend() }; }
};
}
diff --git a/include/toml++/toml_common.h b/include/toml++/toml_common.h
index ed44f40..94f4341 100644
--- a/include/toml++/toml_common.h
+++ b/include/toml++/toml_common.h
@@ -16,6 +16,10 @@
#define TOML_UNRELEASED_FEATURES 1
#endif
+#ifndef TOML_LARGE_FILES
+ #define TOML_LARGE_FILES 0
+#endif
+
#ifndef TOML_ASSERT
#ifdef assert
#define TOML_ASSERT(expr) assert(expr)
@@ -34,6 +38,12 @@
#error toml++ is a C++ library.
#endif
+#if defined(__clang__) or defined(__GNUC__)
+ #define TOML_GCC_ATTR(attr) __attribute__((attr))
+#else
+ #define TOML_GCC_ATTR(attr)
+#endif
+
#ifdef __clang__
#ifndef __cpp_exceptions
@@ -41,11 +51,11 @@
#endif
#define TOML_PUSH_WARNINGS _Pragma("clang diagnostic push")
- #define TOML_DISABLE_SWITCH_WARNING _Pragma("clang diagnostic ignored \"-Wswitch\"")
- #define TOML_DISABLE_FIELD_INIT_WARNING _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"")
+ #define TOML_DISABLE_SWITCH_WARNINGS _Pragma("clang diagnostic ignored \"-Wswitch\"")
+ #define TOML_DISABLE_INIT_WARNINGS _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"")
#define TOML_DISABLE_ALL_WARNINGS _Pragma("clang diagnostic ignored \"-Weverything\"")
#define TOML_POP_WARNINGS _Pragma("clang diagnostic pop")
- #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline
+ #define TOML_ALWAYS_INLINE TOML_GCC_ATTR(__always_inline__) inline
#define TOML_ASSUME(cond) __builtin_assume(cond)
#define TOML_UNREACHABLE __builtin_unreachable()
@@ -70,7 +80,7 @@
#define TOML_CPP_VERSION _MSVC_LANG
#define TOML_PUSH_WARNINGS __pragma(warning(push))
- #define TOML_DISABLE_SWITCH_WARNING __pragma(warning(disable: 4063))
+ #define TOML_DISABLE_SWITCH_WARNINGS __pragma(warning(disable: 4063))
#define TOML_DISABLE_ALL_WARNINGS __pragma(warning(pop)) \
__pragma(warning(push, 0))
#define TOML_POP_WARNINGS __pragma(warning(pop))
@@ -87,16 +97,16 @@
#endif
#define TOML_PUSH_WARNINGS _Pragma("GCC diagnostic push")
- #define TOML_DISABLE_SWITCH_WARNING _Pragma("GCC diagnostic ignored \"-Wswitch\"")
- #define TOML_DISABLE_FIELD_INIT_WARNING _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
- #define TOML_DISABLE_VAR_INIT_WARNING _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
- #define TOML_DISABLE_ALL_WARNINGS _Pragma("GCC diagnostic ignored \"-Wall\"") \
- _Pragma("GCC diagnostic ignored \"-Wextra\"") \
- _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \
+ #define TOML_DISABLE_SWITCH_WARNINGS _Pragma("GCC diagnostic ignored \"-Wswitch\"")
+ #define TOML_DISABLE_INIT_WARNINGS _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
+ _Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
+ #define TOML_DISABLE_ALL_WARNINGS _Pragma("GCC diagnostic ignored \"-Wall\"") \
+ _Pragma("GCC diagnostic ignored \"-Wextra\"") \
+ _Pragma("GCC diagnostic ignored \"-Wchar-subscripts\"") \
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
-
#define TOML_POP_WARNINGS _Pragma("GCC diagnostic pop")
- #define TOML_ALWAYS_INLINE __attribute__((__always_inline__)) inline
+ #define TOML_ALWAYS_INLINE TOML_GCC_ATTR(__always_inline__) inline
#define TOML_UNREACHABLE __builtin_unreachable()
//floating-point from_chars and to_chars are not implemented in any version of gcc as of 1/1/2020
@@ -109,7 +119,11 @@
#ifndef TOML_CPP_VERSION
#define TOML_CPP_VERSION __cplusplus
#endif
-#if TOML_CPP_VERSION >= 202600L
+#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
+#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
+#elif TOML_CPP_VERSION >= 202600L
#define TOML_CPP 26
#elif TOML_CPP_VERSION >= 202300L
#define TOML_CPP 23
@@ -117,12 +131,7 @@
#define TOML_CPP 20
#elif TOML_CPP_VERSION >= 201703L
#define TOML_CPP 17
-#elif TOML_CPP_VERSION >= 201100L
- #error toml++ requires C++17 or higher. For a TOML parser supporting C++11 see https://github.com/skystrife/cpptoml
-#else
- #error toml++ requires C++17 or higher. For a TOML parser supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml
#endif
-#undef TOML_CPP_VERSION
#ifndef TOML_EXCEPTIONS
#define TOML_EXCEPTIONS 1
@@ -135,11 +144,8 @@
#define TOML_MAY_THROW noexcept
#endif
-#ifndef TOML_DISABLE_FIELD_INIT_WARNING
- #define TOML_DISABLE_FIELD_INIT_WARNING
-#endif
-#ifndef TOML_DISABLE_VAR_INIT_WARNING
- #define TOML_DISABLE_VAR_INIT_WARNING
+#ifndef TOML_DISABLE_INIT_WARNINGS
+ #define TOML_DISABLE_INIT_WARNINGS
#endif
#ifndef TOML_USE_STREAMS_FOR_FLOATS
#define TOML_USE_STREAMS_FOR_FLOATS 0
@@ -282,98 +288,6 @@ namespace toml
}
}
- struct date final
- {
- uint16_t year;
- uint8_t month;
- uint8_t day;
-
- [[nodiscard]]
- friend constexpr bool operator == (date lhs, date rhs) noexcept
- {
- return lhs.year == rhs.year
- && lhs.month == rhs.month
- && lhs.day == rhs.day;
- }
-
- [[nodiscard]]
- friend constexpr bool operator != (date lhs, date rhs) noexcept
- {
- return lhs.year != rhs.year
- || lhs.month != rhs.month
- || lhs.day != rhs.day;
- }
- };
-
- struct time final
- {
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- uint32_t nanosecond;
-
- [[nodiscard]]
- friend constexpr bool operator == (time lhs, time rhs) noexcept
- {
- return lhs.hour == rhs.hour
- && lhs.minute == rhs.minute
- && lhs.second == rhs.second
- && lhs.nanosecond == rhs.nanosecond;
- }
-
- [[nodiscard]]
- friend constexpr bool operator != (time lhs, time rhs) noexcept
- {
- return lhs.hour != rhs.hour
- || lhs.minute != rhs.minute
- || lhs.second != rhs.second
- || lhs.nanosecond != rhs.nanosecond;
- }
- };
-
- struct time_offset final
- {
- int8_t hours;
- int8_t minutes;
-
- [[nodiscard]]
- friend constexpr bool operator == (time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.hours == rhs.hours
- && lhs.minutes == rhs.minutes;
- }
-
- [[nodiscard]]
- friend constexpr bool operator != (time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.hours != rhs.hours
- || lhs.minutes != rhs.minutes;
- }
- };
-
- struct date_time final
- {
- toml::date date;
- toml::time time;
- std::optional time_offset;
-
- [[nodiscard]]
- friend constexpr bool operator == (const date_time& lhs, const date_time& rhs) noexcept
- {
- return lhs.date == rhs.date
- && lhs.time == rhs.time
- && lhs.time_offset == rhs.time_offset;
- }
-
- [[nodiscard]]
- friend constexpr bool operator != (const date_time& lhs, const date_time& rhs) noexcept
- {
- return lhs.date != rhs.date
- || lhs.time != rhs.time
- || lhs.time_offset != rhs.time_offset;
- }
- };
-
#if TOML_CHAR_8_STRINGS
using string_char = char8_t;
@@ -392,125 +306,43 @@ namespace toml
using string_map = std::map>; //heterogeneous lookup
class node;
- template
- class node_view;
- template
- class value;
+ template class node_view;
+ template class value;
class array;
class table;
- class default_formatter;
- class json_formatter;
-
- namespace impl
+ enum class node_type : uint8_t
{
- #if defined(__cpp_lib_remove_cvref) || (defined(_MSC_VER) && defined(_HAS_CXX20))
+ table,
+ array,
+ string,
+ integer,
+ floating_point,
+ boolean,
+ date,
+ time,
+ date_time
+ };
- template
- using remove_cvref_t = std::remove_cvref_t;
+ #if TOML_LARGE_FILES
- #else
+ using source_index = uint32_t;
- template
- using remove_cvref_t = std::remove_cv_t>;
+ #else
- #endif
+ using source_index = uint16_t;
- template
- struct is_generic_invocable
- {
- template
- static constexpr auto test(U&&) -> decltype(std::declval()(std::declval()), std::true_type{});
- static constexpr std::false_type test(...);
+ #endif
- struct tester {};
- static constexpr auto value = decltype(test(tester{}))::value;
- };
-
-
- template
- inline constexpr bool is_generic_invocable_v = is_generic_invocable::value;
-
- class parser;
- class formatter;
-
- template
- inline constexpr bool is_value =
- std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v;
-
- template
- inline constexpr bool is_value_or_promotable =
- is_value
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v
- || std::is_same_v;
-
- template
- inline constexpr bool is_value_or_node =
- is_value
- || std::is_same_v
- || std::is_same_v;
-
- template struct node_wrapper { using type = T; };
- template <> struct node_wrapper { using type = value; };
- template <> struct node_wrapper { using type = value; };
- template <> struct node_wrapper { using type = value; };
- template <> struct node_wrapper { using type = value; };
- template <> struct node_wrapper { using type = value; };
- template <> struct node_wrapper