#include "glaze/toml.hpp"

#include <chrono>
#include <cmath>
#include <cstdint>
#include <limits>
#include <map>
#include <set>
#include <span>
#include <string_view>
#include <unordered_set>

#include "ut/ut.hpp"

using namespace ut;

struct my_struct
{
   int i = 287;
   double d = 3.14;
   std::string hello = "Hello World";
   std::array<uint64_t, 3> arr = {1, 2, 3};
};

struct nested
{
   int x = 10;
   std::string y = "test";

   bool operator==(const nested&) const = default;
};

struct simple_container
{
   nested inner{};
   double value = 5.5;
};

struct advanced_container
{
   nested inner{};
   nested inner_two{};
   double value = 5.5;
};

struct level_one
{
   int value{0};
};

struct level_two
{
   level_one l1{};
};

struct dotted_access_struct
{
   level_two l2{};
};

struct dotted_unknown_inner
{
   std::string value{"initial"};
};

struct dotted_unknown_root
{
   dotted_unknown_inner key{};
};

struct simple_value_struct
{
   std::string value{"initial"};
};

struct unicode_name_struct
{
   std::string name{};
};

struct unicode_key_struct
{
   int a{};
};

struct float_special_struct
{
   double value{};
   std::vector<double> values{};
};

struct int_array_struct
{
   std::vector<int> values{};
};

template <>
struct glz::meta<dotted_unknown_inner>
{
   using T = dotted_unknown_inner;
   static constexpr auto value = object("value", &T::value);
};

template <>
struct glz::meta<dotted_unknown_root>
{
   using T = dotted_unknown_root;
   static constexpr auto value = object("key", &T::key);
};

template <>
struct glz::meta<simple_value_struct>
{
   using T = simple_value_struct;
   static constexpr auto value = object("value", &T::value);
};

struct optional_struct
{
   std::optional<int> maybe = 99;
};

struct inline_table_member
{
   std::string key1{};
   int key2{};

   bool operator==(const inline_table_member&) const = default;
};

template <>
struct glz::meta<inline_table_member>
{
   using T = inline_table_member;
   static constexpr auto value = object("key1", &T::key1, "key2", &T::key2);
};

struct struct_with_inline_table
{
   std::string name{};
   inline_table_member inline_data{};

   bool operator==(const struct_with_inline_table&) const = default;
};

template <>
struct glz::meta<struct_with_inline_table>
{
   using T = struct_with_inline_table;
   static constexpr auto value = object("name", &T::name, "inline_data", &T::inline_data);
};

struct complex_strings_struct
{
   std::string basic_multiline{};
   std::string literal_multiline{};
   std::string literal_multiline_with_quotes{};

   bool operator==(const complex_strings_struct&) const = default;
};

template <>
struct glz::meta<complex_strings_struct>
{
   using T = complex_strings_struct;
   static constexpr auto value =
      object("basic_multiline", &T::basic_multiline, "literal_multiline", &T::literal_multiline,
             "literal_multiline_with_quotes", &T::literal_multiline_with_quotes);
};

struct comment_test_struct
{
   int a{};
   std::string b{};

   bool operator==(const comment_test_struct&) const = default;
};

template <>
struct glz::meta<comment_test_struct>
{
   using T = comment_test_struct;
   static constexpr auto value = object("a", &T::a, "b", &T::b);
};

struct non_null_term_struct
{
   int value{};
   bool operator==(const non_null_term_struct&) const = default;
};

template <>
struct glz::meta<non_null_term_struct>
{
   using T = non_null_term_struct;
   static constexpr auto value = object("value", &T::value);
};

// ========== Chrono test structures ==========

struct duration_test_struct
{
   std::chrono::seconds seconds_val{};
   std::chrono::milliseconds millis_val{};
   std::chrono::minutes minutes_val{};
   std::chrono::hours hours_val{};

   bool operator==(const duration_test_struct&) const = default;
};

struct system_time_test_struct
{
   std::chrono::system_clock::time_point timestamp{};
   int value{};

   bool operator==(const system_time_test_struct&) const = default;
};

struct chrono_combined_struct
{
   std::string name{};
   std::chrono::seconds timeout{};
   std::chrono::system_clock::time_point created_at{};
   std::chrono::milliseconds latency{};

   bool operator==(const chrono_combined_struct&) const = default;
};

struct local_date_test_struct
{
   std::chrono::year_month_day date{};
   int value{};

   bool operator==(const local_date_test_struct&) const = default;
};

struct local_time_test_struct
{
   std::chrono::hh_mm_ss<std::chrono::seconds> time_sec{std::chrono::seconds{0}};
   std::chrono::hh_mm_ss<std::chrono::milliseconds> time_ms{std::chrono::milliseconds{0}};
};

// ========== Set test structures ==========

struct set_test_struct
{
   std::set<int> int_set{};
   std::set<std::string> string_set{};

   bool operator==(const set_test_struct&) const = default;
};

struct unordered_set_test_struct
{
   std::unordered_set<int> int_uset{};

   bool operator==(const unordered_set_test_struct&) const = default;
};

struct combined_containers_struct
{
   std::vector<int> vec{};
   std::set<int> set{};
   std::array<int, 3> arr{};

   bool operator==(const combined_containers_struct&) const = default;
};

// ========== Enum types for TOML enum serialization tests ==========
enum class Color { Red, Green, Blue };

template <>
struct glz::meta<Color>
{
   using enum Color;
   static constexpr auto value = glz::enumerate(Red, Green, Blue);
};

enum class Status { Pending, Active, Completed, Cancelled };

template <>
struct glz::meta<Status>
{
   using enum Status;
   static constexpr auto value = glz::enumerate(Pending, Active, Completed, Cancelled);
};

// Enum with custom string names
enum class LogLevel { Debug = 0, Info = 1, Warning = 2, Error = 3 };

template <>
struct glz::meta<LogLevel>
{
   using enum LogLevel;
   static constexpr auto value = glz::enumerate("debug", Debug, "info", Info, "warning", Warning, "error", Error);
};

// Raw enum without glz::meta (should serialize as number)
enum class RawEnum { A = 0, B = 1, C = 2 };

// Single-value enum (edge case)
enum class SingleEnum { OnlyValue };

template <>
struct glz::meta<SingleEnum>
{
   using enum SingleEnum;
   static constexpr auto value = glz::enumerate(OnlyValue);
};

// Struct containing enum members
struct config_with_enums
{
   std::string name{};
   Color color{Color::Red};
   Status status{Status::Pending};
   int priority{0};

   bool operator==(const config_with_enums&) const = default;
};

template <>
struct glz::meta<config_with_enums>
{
   using T = config_with_enums;
   static constexpr auto value =
      object("name", &T::name, "color", &T::color, "status", &T::status, "priority", &T::priority);
};

suite starter = [] {
   "example"_test = [] {
      my_struct s{};
      std::string buffer{};
      expect(not glz::write_toml(s, buffer));
      expect(buffer ==
             R"(i = 287
d = 3.14
hello = "Hello World"
arr = [1, 2, 3])");
   };

   "read_basic_struct"_test = [] {
      std::string toml_input = R"(i = 42
d = 2.71
hello = "Test String"
arr = [4, 5, 6])";

      my_struct s{};
      expect(not glz::read_toml(s, toml_input));
      expect(s.i == 42);
      expect(s.d == 2.71);
      expect(s.hello == "Test String");
      expect(s.arr[0] == 4);
      expect(s.arr[1] == 5);
      expect(s.arr[2] == 6);
   };

   "read_integer"_test = [] {
      std::string toml_input = "123";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 123);
   };

   "read_no_valid_digits_integer"_test = [] {
      // We require at least one valid digit.
      std::string toml_input = "BAD";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_overflow_integer"_test = [] {
      // Max uint64 value plus one.
      std::string toml_input = "18446744073709551616";
      uint64_t value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_nearly_overfow_integer"_test = [] {
      // Max uint64 value.
      std::string toml_input = "18446744073709551615";
      uint64_t value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 18446744073709551615ull);
   };

   "read_wrong_underflow_integer"_test = [] {
      // Min int64 value minus one.
      std::string toml_input = "-9223372036854775809";
      int64_t value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_nearly_underflow_integer"_test = [] {
      // Min int64 value.
      std::string toml_input = "-9223372036854775808";
      int64_t value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == -9223372036854775807ll - 1);
   };

   "read_negative_integer"_test = [] {
      std::string toml_input = "-123";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == -123);
   };

   "read_wrong_negative_integer"_test = [] {
      std::string toml_input = "-123";
      // Negative values should not succeed for unsigned types.
      unsigned int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_positive_integer"_test = [] {
      std::string toml_input = "+123";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 123);
   };

   "read_negative_zero_integer"_test = [] {
      std::string toml_input = "-0";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0);
   };

   "read_unsigned_negative_zero_integer"_test = [] {
      std::string toml_input = "-0";
      unsigned int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0);
   };

   "read_positive_zero_integer"_test = [] {
      std::string toml_input = "+0";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0);
   };

   "read_hex_integer"_test = [] {
      std::string toml_input = "0x012abCD";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0x012abCD);
   };

   "read_wrong_hex_integer"_test = [] {
      std::string toml_input = "0xG";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_hex_negative_integer"_test = [] {
      std::string toml_input = "-0x12abCD";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_hex_positive_integer"_test = [] {
      std::string toml_input = "+0x12abCD";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_hex_negative_unsigned_integer"_test = [] {
      std::string toml_input = "-0x1";
      unsigned int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_bad_digits_integer"_test = [] {
      std::string toml_input = "123ABC";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_binary_integer"_test = [] {
      std::string toml_input = "0b010";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0b010);
   };

   "read_wrong_binary_integer"_test = [] {
      std::string toml_input = "0b3";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_binary_negative_integer"_test = [] {
      std::string toml_input = "-0b10";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_binary_positive_integer"_test = [] {
      std::string toml_input = "+0b10";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_binary_negative_unsigned_integer"_test = [] {
      std::string toml_input = "-0b1";
      unsigned int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_octal_integer"_test = [] {
      std::string toml_input = "0o01267";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      // Leading '0' to specify octal in C++.
      expect(value == 001267);
   };

   "read_wrong_octal_integer"_test = [] {
      std::string toml_input = "0o8";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_octal_negative_integer"_test = [] {
      std::string toml_input = "-0o1267";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_octal_positive_integer"_test = [] {
      std::string toml_input = "+0o1267";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_octal_negative_unsigned_integer"_test = [] {
      std::string toml_input = "-0o7";
      unsigned int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_underscore_integer"_test = [] {
      std::string toml_input = "1_2_3";
      int value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 123);
   };

   "read_wrong_underscore_integer"_test = [] {
      std::string toml_input = "1__2_3";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_integer"_test = [] {
      std::string toml_input = "_123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_negative_integer"_test = [] {
      std::string toml_input = "-_123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_positive_integer"_test = [] {
      std::string toml_input = "+_123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_hex_integer"_test = [] {
      std::string toml_input = "0x_12abCD";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_binary_integer"_test = [] {
      std::string toml_input = "0b_10";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_underscore_octal_integer"_test = [] {
      std::string toml_input = "0o_1267";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_trailing_underscore_integer"_test = [] {
      std::string toml_input = "123_";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_zero_integer"_test = [] {
      std::string toml_input = "0123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_zero_negative_integer"_test = [] {
      std::string toml_input = "-0123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_wrong_leading_zero_positive_integer"_test = [] {
      std::string toml_input = "+0123";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   // In TOML, integers are not able to have an exponent component.
   "read_wrong_exponent_integer"_test = [] {
      std::string toml_input = "1e2";
      int value{};
      auto error = glz::read_toml(value, toml_input);
      expect(error);
      expect(error == glz::error_code::parse_number_failure);
   };

   "read_decimal_int8_boundaries"_test = [] {
      {
         std::string toml_input = "-128";
         std::int8_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int8_t>::min());
      }
      {
         std::string toml_input = "127";
         std::int8_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int8_t>::max());
      }
      {
         std::string toml_input = "-129";
         std::int8_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "128";
         std::int8_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_uint8_boundaries"_test = [] {
      {
         std::string toml_input = "0";
         std::uint8_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint8_t>::min());
      }
      {
         std::string toml_input = "255";
         std::uint8_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint8_t>::max());
      }
      {
         std::string toml_input = "-1";
         std::uint8_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "256";
         std::uint8_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_int16_boundaries"_test = [] {
      {
         std::string toml_input = "-32768";
         std::int16_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int16_t>::min());
      }
      {
         std::string toml_input = "32767";
         std::int16_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int16_t>::max());
      }
      {
         std::string toml_input = "-32769";
         std::int16_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "32768";
         std::int16_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_uint16_boundaries"_test = [] {
      {
         std::string toml_input = "0";
         std::uint16_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint16_t>::min());
      }
      {
         std::string toml_input = "65535";
         std::uint16_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint16_t>::max());
      }
      {
         std::string toml_input = "-1";
         std::uint16_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "65536";
         std::uint16_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_int32_boundaries"_test = [] {
      {
         std::string toml_input = "-2147483648";
         std::int32_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int32_t>::min());
      }
      {
         std::string toml_input = "2147483647";
         std::int32_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::int32_t>::max());
      }
      {
         std::string toml_input = "-2147483649";
         std::int32_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "2147483648";
         std::int32_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_uint32_boundaries"_test = [] {
      {
         std::string toml_input = "0";
         std::uint32_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint32_t>::min());
      }
      {
         std::string toml_input = "4294967295";
         std::uint32_t value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == std::numeric_limits<std::uint32_t>::max());
      }
      {
         std::string toml_input = "-1";
         std::uint32_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
      {
         std::string toml_input = "4294967296";
         std::uint32_t value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_decimal_with_underscores_integer"_test = [] {
      {
         std::string toml_input = "1_234_567";
         int value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == 1234567);
      }
      {
         std::string toml_input = "-1_234_567";
         int value{};
         expect(not glz::read_toml(value, toml_input));
         expect(value == -1234567);
      }
   };

   "read_hex_with_underscores_integer"_test = [] {
      std::string toml_input = "0xDEAD_BEEF";
      std::uint32_t value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0xDEADBEEF);
   };

   "read_binary_with_underscores_integer"_test = [] {
      std::string toml_input = "0b1010_0101_1111";
      std::uint32_t value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0b101001011111);
   };

   "read_octal_with_underscores_integer"_test = [] {
      std::string toml_input = "0o12_34_70";
      std::uint32_t value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 0123470);
   };

   "read_wrong_multiple_signs_integer"_test = [] {
      for (const auto input : {"+-1", "-+1", "--1", "++1"}) {
         std::string toml_input = input;
         int value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_wrong_sign_without_digits_integer"_test = [] {
      for (const auto input : {"+", "-", "+_", "-_"}) {
         std::string toml_input = input;
         int value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_wrong_prefixed_missing_digits_integer"_test = [] {
      for (const auto input : {"0x", "0b", "0o", "0x_", "0b_", "0o_"}) {
         std::string toml_input = input;
         int value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_wrong_prefixed_trailing_underscore_integer"_test = [] {
      for (const auto input : {"0xAB_", "0b101_", "0o77_"}) {
         std::string toml_input = input;
         int value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_wrong_prefixed_double_underscore_integer"_test = [] {
      for (const auto input : {"0xA__B", "0b10__10", "0o1__2"}) {
         std::string toml_input = input;
         int value{};
         auto error = glz::read_toml(value, toml_input);
         expect(error);
         expect(error == glz::error_code::parse_number_failure);
      }
   };

   "read_float"_test = [] {
      std::string toml_input = "3.14159";
      double value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == 3.14159);
   };

   "read_string"_test = [] {
      std::string toml_input = R"("Hello TOML")";
      std::string value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == "Hello TOML");
   };

   "write_explicit_string_view"_test = [] {
      struct explicit_string_view_type
      {
         std::string storage{};

         explicit explicit_string_view_type(std::string_view s) : storage(s) {}

         explicit operator std::string_view() const noexcept { return storage; }
      };

      explicit_string_view_type value{std::string_view{"explicit"}};

      std::string buffer{};
      expect(not glz::write_toml(value, buffer));
      expect(buffer == R"("explicit")");

      buffer.clear();
      expect(not glz::write<glz::opt_true<glz::opts{.format = glz::TOML}, glz::raw_string_opt_tag{}>>(value, buffer));
      expect(buffer == R"("explicit")");
   };

   "read_boolean_true"_test = [] {
      std::string toml_input = "true";
      bool value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == true);
   };

   "read_boolean_false"_test = [] {
      std::string toml_input = "false";
      bool value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value == false);
   };

   "read_array"_test = [] {
      std::string toml_input = "[1, 2, 3, 4]";
      std::vector<int> value{};
      expect(not glz::read_toml(value, toml_input));
      expect(value.size() == 4);
      expect(value[0] == 1);
      expect(value[1] == 2);
      expect(value[2] == 3);
      expect(value[3] == 4);
   };

   "scalar_int"_test = [] {
      int i = 42;
      std::string buffer{};
      expect(not glz::write_toml(i, buffer));
      expect(buffer == "42");
   };

   "simple_array"_test = [] {
      std::vector<int> v = {1, 2, 3, 4};
      std::string buffer{};
      expect(not glz::write_toml(v, buffer));
      expect(buffer == "[1, 2, 3, 4]");
   };

   "writable_map"_test = [] {
      std::map<std::string, int> m = {{"a", 1}, {"b", 2}};
      std::string buffer{};
      expect(not glz::write_toml(m, buffer));
      // std::map orders keys lexicographically, so we expect:
      expect(buffer == R"(a = 1
b = 2)");
   };

   "tuple_test"_test = [] {
      std::tuple<int, std::string> t = {100, "hello"};
      std::string buffer{};
      expect(not glz::write_toml(t, buffer));
      expect(buffer == R"([100, "hello"])");
   };

   // Test writing a string that contains quotes and backslashes.
   "escape_string"_test = [] {
      std::string s = "Line \"quoted\" and \\ backslash";
      std::string buffer{};
      expect(not glz::write_toml(s, buffer));
      // The expected output escapes the quote and backslash, and encloses the result in quotes.
      expect(buffer == R"("Line \"quoted\" and \\ backslash")");
   };

   // Test writing a nested structure.
   // TOML spec: scalars should be written before tables for correct parsing
   "write_nested_struct"_test = [] {
      simple_container c{};
      std::string buffer{};
      expect(not glz::write_toml(c, buffer));
      expect(buffer == R"(value = 5.5
[inner]
x = 10
y = "test"
)");
   };

   "read_wrong_format_nested"_test = [] {
      advanced_container sc{};
      std::string buffer{R"([inner]
x = 10
y = "test"

value = 5.5)"};
      auto error = glz::read_toml(sc, buffer);
      expect(error); // Expect an error because the format is not correct for TOML. root value should be before nested
                     // table.
      expect(error == glz::error_code::unknown_key);
   };

   "read_nested_struct"_test = [] {
      simple_container sc{};
      std::string buffer{R"(value = 5.6

[inner]
x = 11
y = "test1"
)"};
      expect(not glz::read_toml(sc, buffer));
      expect(sc.inner.x == 11);
      expect(sc.inner.y == "test1");
      expect(sc.value == 5.6);
   };

   "read_advanced_nested_struct"_test = [] {
      advanced_container ac{};
      std::string buffer{R"(value = 5.6

[inner]
x = 11
y = "test1"

[inner_two]
x = 12
y = "test2"
)"};
      expect(not glz::read_toml(ac, buffer));
      expect(ac.inner.x == 11);
      expect(ac.inner.y == "test1");
      expect(ac.inner_two.x == 12);
      expect(ac.inner_two.y == "test2");
      expect(ac.value == 5.6);
   };

   "read_advanced_nested_struct"_test = [] {
      dotted_access_struct dac{};
      std::string buffer{R"(l2.l1.value = 1)"};
      expect(not glz::read_toml(dac, buffer));
      expect(dac.l2.l1.value == 1);
   };

   "ignore_unknown_dotted_key"_test = [] {
      dotted_unknown_root result{};
      result.key.value = "initial";
      const std::string toml_input = R"(key.other_value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.key.value == "initial");
   };

   "ignore_unknown_dotted_key_type_mismatch"_test = [] {
      dotted_unknown_root result{};
      result.key.value = "initial";
      const std::string toml_input = R"(key.other_value = 1
key.value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.key.value == "string");
   };

   "ignore_unknown_multiline_basic_string"_test = [] {
      dotted_unknown_root result{};
      result.key.value = "initial";
      const std::string toml_input = R"(key.other_value = """first
second"""
key.value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.key.value == "string");
   };

   "ignore_unknown_multiline_literal_string"_test = [] {
      dotted_unknown_root result{};
      result.key.value = "initial";
      const std::string toml_input = R"(key.other_value = '''first
second'''
key.value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.key.value == "string");
   };

   "ignore_unknown_array_value"_test = [] {
      dotted_unknown_root result{};
      result.key.value = "initial";
      const std::string toml_input = R"(key.other_value = [1, 2, 3]
key.value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.key.value == "string");
   };

   "ignore_unknown_inline_table"_test = [] {
      simple_value_struct result{};
      const std::string toml_input = R"(other = { nested = "value", deeper = { inner = 1 } }
value = "string")";

      const auto error = glz::read<glz::opts{.format = glz::TOML, .error_on_unknown_keys = false}>(result, toml_input);

      expect(not error);
      expect(result.value == "string");
   };

   // Test writing a boolean value.
   "boolean_value"_test = [] {
      bool b = true;
      std::string buffer{};
      expect(not glz::write_toml(b, buffer));
      expect(buffer == "true");
   };

   // Test writing an empty array.
   "empty_array"_test = [] {
      std::vector<int> empty{};
      std::string buffer{};
      expect(not glz::write_toml(empty, buffer));
      expect(buffer == "[]");
   };

   // Test writing an empty map.
   "empty_map"_test = [] {
      std::map<std::string, int> empty{};
      std::string buffer{};
      expect(not glz::write_toml(empty, buffer));
      expect(buffer == "");
   };

   // Test writing a vector of booleans.
   "vector_of_bool"_test = [] {
      std::vector<bool> vb = {true, false, true};
      std::string buffer{};
      expect(not glz::write_toml(vb, buffer));
      expect(buffer == "[true, false, true]");
   };

   // Test writing an optional that contains a value.
   "optional_present"_test = [] {
      std::optional<int> opt = 42;
      std::string buffer{};
      expect(not glz::write_toml(opt, buffer));
      expect(buffer == "42");
   };

   // Test writing an optional that is null.
   "optional_null"_test = [] {
      std::optional<int> opt = std::nullopt;
      std::string buffer{};
      expect(not glz::write_toml(opt, buffer));
      // Assuming that a null optional is skipped and produces an empty output.
      expect(buffer == "");
   };

   // Test writing a structure with an optional member (present).
   "optional_struct_present"_test = [] {
      optional_struct os{};
      std::string buffer{};
      expect(not glz::write_toml(os, buffer));
      expect(buffer == "maybe = 99");
   };

   // Test writing a structure with an optional member (null).
   "optional_struct_null"_test = [] {
      optional_struct os{};
      os.maybe = std::nullopt;
      std::string buffer{};
      expect(not glz::write_toml(os, buffer));
      // If all members are null (or skipped) then the output is empty.
      expect(buffer == "");
   };

   "read_inline_table"_test = [] {
      std::string toml_input = R"(name = "Test Person"
inline_data = { key1 = "value1", key2 = 100 })";
      struct_with_inline_table s{};
      auto error = glz::read_toml(s, toml_input);
      expect(!error) << glz::format_error(error, toml_input);
      expect(s.name == "Test Person");
      expect(s.inline_data.key1 == "value1");
      expect(s.inline_data.key2 == 100);
   };

   "read_complex_strings"_test = [] {
      std::string toml_input = R"(
basic_multiline = """
Roses are red
Violets are blue"""
literal_multiline = '''
The first line.
  The second line.
    The third line.'''
literal_multiline_with_quotes = '''He said "She said 'It is so.''"'''
)";
      complex_strings_struct s{};
      auto error = glz::read_toml(s, toml_input);
      expect(!error) << glz::format_error(error, toml_input);
      expect(s.basic_multiline == "Roses are red\nViolets are blue");
      expect(s.literal_multiline == "The first line.\n  The second line.\n    The third line.");
      expect(s.literal_multiline_with_quotes == "He said \"She said 'It is so.''\"");
   };

   "read_with_comments"_test = [] {
      std::string toml_input = R"(
# This is a full line comment
a = 123 # This is an end-of-line comment
# Another comment
b = "test string" # another eol comment
)";
      comment_test_struct s{};
      auto error = glz::read_toml(s, toml_input);
      expect(!error) << glz::format_error(error, toml_input);
      expect(s.a == 123);
      expect(s.b == "test string");
   };

   "read_non_null_terminated"_test = [] {
      std::string buffer_with_extra = "value = 123GARBAGE_DATA";
      // Create a string_view that does not include "GARBAGE_DATA" and is not null-terminated
      // within the view itself.
      std::string_view toml_data(buffer_with_extra.data(), 11); // "value = 123"

      non_null_term_struct s_val{};
      auto error = glz::read_toml(s_val, toml_data);
      expect(!error) << glz::format_error(error, toml_data);
      expect(s_val.value == 123);

      std::string buffer_just_value = "value = 456"; // Null terminated by string constructor
      non_null_term_struct s_val2{};
      error = glz::read_toml(s_val2, buffer_just_value);
      expect(!error) << glz::format_error(error, buffer_just_value);
      expect(s_val2.value == 456);
   };

   // ========== Enum serialization tests ==========

   "write_enum_basic"_test = [] {
      Color c = Color::Green;
      auto result = glz::write_toml(c);
      expect(result.has_value());
      expect(result.value() == R"("Green")");
   };

   "read_enum_basic"_test = [] {
      Color c{};
      std::string input = R"("Blue")";
      auto error = glz::read_toml(c, input);
      expect(!error) << glz::format_error(error, input);
      expect(c == Color::Blue);
   };

   "enum_roundtrip"_test = [] {
      for (auto color : {Color::Red, Color::Green, Color::Blue}) {
         auto result = glz::write_toml(color);
         expect(result.has_value());

         Color parsed{};
         auto error = glz::read_toml(parsed, result.value());
         expect(!error) << glz::format_error(error, result.value());
         expect(parsed == color);
      }
   };

   "write_enum_all_values"_test = [] {
      {
         Status s = Status::Pending;
         auto result = glz::write_toml(s);
         expect(result.has_value());
         expect(result.value() == R"("Pending")");
      }
      {
         Status s = Status::Active;
         auto result = glz::write_toml(s);
         expect(result.has_value());
         expect(result.value() == R"("Active")");
      }
      {
         Status s = Status::Completed;
         auto result = glz::write_toml(s);
         expect(result.has_value());
         expect(result.value() == R"("Completed")");
      }
      {
         Status s = Status::Cancelled;
         auto result = glz::write_toml(s);
         expect(result.has_value());
         expect(result.value() == R"("Cancelled")");
      }
   };

   "read_enum_all_values"_test = [] {
      {
         Status s{};
         std::string input = R"("Pending")";
         auto error = glz::read_toml(s, input);
         expect(!error) << glz::format_error(error, input);
         expect(s == Status::Pending);
      }
      {
         Status s{};
         std::string input = R"("Active")";
         auto error = glz::read_toml(s, input);
         expect(!error) << glz::format_error(error, input);
         expect(s == Status::Active);
      }
      {
         Status s{};
         std::string input = R"("Completed")";
         auto error = glz::read_toml(s, input);
         expect(!error) << glz::format_error(error, input);
         expect(s == Status::Completed);
      }
      {
         Status s{};
         std::string input = R"("Cancelled")";
         auto error = glz::read_toml(s, input);
         expect(!error) << glz::format_error(error, input);
         expect(s == Status::Cancelled);
      }
   };

   "enum_custom_names"_test = [] {
      // Write with custom names
      {
         LogLevel level = LogLevel::Warning;
         auto result = glz::write_toml(level);
         expect(result.has_value());
         expect(result.value() == R"("warning")");
      }
      // Read with custom names
      {
         LogLevel level{};
         std::string input = R"("error")";
         auto error = glz::read_toml(level, input);
         expect(!error) << glz::format_error(error, input);
         expect(level == LogLevel::Error);
      }
      // Roundtrip all custom-named values
      for (auto level : {LogLevel::Debug, LogLevel::Info, LogLevel::Warning, LogLevel::Error}) {
         auto result = glz::write_toml(level);
         expect(result.has_value());

         LogLevel parsed{};
         auto error = glz::read_toml(parsed, result.value());
         expect(!error) << glz::format_error(error, result.value());
         expect(parsed == level);
      }
   };

   "enum_single_value"_test = [] {
      // Single-value enum edge case
      SingleEnum e = SingleEnum::OnlyValue;
      auto result = glz::write_toml(e);
      expect(result.has_value());
      expect(result.value() == R"("OnlyValue")");

      SingleEnum parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == SingleEnum::OnlyValue);
   };

   "raw_enum_write"_test = [] {
      // Raw enum without glz::meta should serialize as number
      RawEnum e = RawEnum::B;
      auto result = glz::write_toml(e);
      expect(result.has_value());
      expect(result.value() == "1");
   };

   "raw_enum_read"_test = [] {
      // Raw enum should read from number
      RawEnum e{};
      std::string input = "2";
      auto error = glz::read_toml(e, input);
      expect(!error) << glz::format_error(error, input);
      expect(e == RawEnum::C);
   };

   "raw_enum_roundtrip"_test = [] {
      for (auto e : {RawEnum::A, RawEnum::B, RawEnum::C}) {
         auto result = glz::write_toml(e);
         expect(result.has_value());

         RawEnum parsed{};
         auto error = glz::read_toml(parsed, result.value());
         expect(!error) << glz::format_error(error, result.value());
         expect(parsed == e);
      }
   };

   "struct_with_enum_write"_test = [] {
      config_with_enums config{};
      config.name = "test_config";
      config.color = Color::Blue;
      config.status = Status::Active;
      config.priority = 5;

      auto result = glz::write_toml(config);
      expect(result.has_value());
      expect(result.value() == R"(name = "test_config"
color = "Blue"
status = "Active"
priority = 5)");
   };

   "struct_with_enum_read"_test = [] {
      std::string input = R"(name = "my_config"
color = "Green"
status = "Completed"
priority = 10)";

      config_with_enums config{};
      auto error = glz::read_toml(config, input);
      expect(!error) << glz::format_error(error, input);
      expect(config.name == "my_config");
      expect(config.color == Color::Green);
      expect(config.status == Status::Completed);
      expect(config.priority == 10);
   };

   "struct_with_enum_roundtrip"_test = [] {
      config_with_enums original{};
      original.name = "roundtrip_test";
      original.color = Color::Red;
      original.status = Status::Cancelled;
      original.priority = 99;

      auto result = glz::write_toml(original);
      expect(result.has_value());

      config_with_enums parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "enum_invalid_value"_test = [] {
      Color c{};
      std::string input = R"("InvalidColor")";
      auto error = glz::read_toml(c, input);
      expect(error);
      expect(error == glz::error_code::unexpected_enum);
   };

   "enum_missing_quote"_test = [] {
      Color c{};
      std::string input = "Red"; // Missing quotes
      auto error = glz::read_toml(c, input);
      expect(error);
      expect(error == glz::error_code::expected_quote);
   };

   "enum_empty_string"_test = [] {
      Color c{};
      std::string input = R"("")"; // Empty string
      auto error = glz::read_toml(c, input);
      expect(error);
      expect(error == glz::error_code::unexpected_enum);
   };

   // ========== std::chrono duration tests ==========

   "duration_seconds_write"_test = [] {
      std::chrono::seconds s{42};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "42");
   };

   "duration_seconds_read"_test = [] {
      std::chrono::seconds s{};
      std::string input = "100";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.count() == 100);
   };

   "duration_milliseconds_write"_test = [] {
      std::chrono::milliseconds ms{1500};
      auto result = glz::write_toml(ms);
      expect(result.has_value());
      expect(result.value() == "1500");
   };

   "duration_milliseconds_read"_test = [] {
      std::chrono::milliseconds ms{};
      std::string input = "2500";
      auto error = glz::read_toml(ms, input);
      expect(!error) << glz::format_error(error, input);
      expect(ms.count() == 2500);
   };

   "duration_minutes_roundtrip"_test = [] {
      std::chrono::minutes original{60};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      std::chrono::minutes parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "duration_hours_roundtrip"_test = [] {
      std::chrono::hours original{24};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      std::chrono::hours parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "duration_negative_value"_test = [] {
      std::chrono::seconds s{-100};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "-100");

      std::chrono::seconds parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.count() == -100);
   };

   "duration_zero_value"_test = [] {
      std::chrono::seconds s{0};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "0");

      std::chrono::seconds parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.count() == 0);
   };

   "duration_struct_write"_test = [] {
      duration_test_struct s{};
      s.seconds_val = std::chrono::seconds{10};
      s.millis_val = std::chrono::milliseconds{500};
      s.minutes_val = std::chrono::minutes{5};
      s.hours_val = std::chrono::hours{2};

      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == R"(seconds_val = 10
millis_val = 500
minutes_val = 5
hours_val = 2)");
   };

   "duration_struct_read"_test = [] {
      std::string input = R"(seconds_val = 30
millis_val = 1000
minutes_val = 10
hours_val = 1)";

      duration_test_struct s{};
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.seconds_val.count() == 30);
      expect(s.millis_val.count() == 1000);
      expect(s.minutes_val.count() == 10);
      expect(s.hours_val.count() == 1);
   };

   "duration_struct_roundtrip"_test = [] {
      duration_test_struct original{};
      original.seconds_val = std::chrono::seconds{42};
      original.millis_val = std::chrono::milliseconds{12345};
      original.minutes_val = std::chrono::minutes{60};
      original.hours_val = std::chrono::hours{24};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      duration_test_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   // ========== std::chrono::system_clock::time_point tests (native TOML datetime) ==========

   "system_time_write_basic"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};

      auto result = glz::write_toml(tp);
      expect(result.has_value());
      // Should contain the datetime without quotes (native TOML format)
      expect(result.value().find("2024-06-15T10:30:45") != std::string::npos);
      expect(result.value().find('"') == std::string::npos); // No quotes
   };

   "system_time_read_with_Z"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15T10:30:45Z";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_local_datetime"_test = [] {
      // TOML local datetime (no timezone) - treated as UTC
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15T10:30:45";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_positive_offset"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      // +05:00 means local time is 5 hours ahead of UTC
      std::string input = "2024-06-15T10:30:45+05:00";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      // 10:30:45+05:00 = 05:30:45Z
      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{5} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_negative_offset"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      // -08:00 means local time is 8 hours behind UTC
      std::string input = "2024-06-15T10:30:45-08:00";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      // 10:30:45-08:00 = 18:30:45Z
      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{18} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_fractional_seconds"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15T10:30:45.123456Z";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected_base = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      // Check that we got roughly the right time (within a second)
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected_base));
   };

   "system_time_read_without_seconds"_test = [] {
      // TOML allows omitting seconds
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15T10:30Z";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_space_delimiter"_test = [] {
      // TOML allows space instead of T
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15 10:30:45Z";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_read_lowercase_t"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15t10:30:45z";
      auto error = glz::read_toml(tp, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "system_time_struct_write"_test = [] {
      using namespace std::chrono;
      system_time_test_struct s{};
      s.timestamp = sys_days{year{2024} / month{12} / day{25}} + hours{23} + minutes{59} + seconds{59};
      s.value = 42;

      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value().find("2024-12-25T23:59:59") != std::string::npos);
      expect(result.value().find("value = 42") != std::string::npos);
   };

   "system_time_struct_read"_test = [] {
      using namespace std::chrono;
      std::string input = R"(timestamp = 2024-12-25T23:59:59Z
value = 100)";

      system_time_test_struct s{};
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);

      auto expected = sys_days{year{2024} / month{12} / day{25}} + hours{23} + minutes{59} + seconds{59};
      expect(time_point_cast<seconds>(s.timestamp) == time_point_cast<seconds>(expected));
      expect(s.value == 100);
   };

   "system_time_roundtrip"_test = [] {
      using namespace std::chrono;
      system_clock::time_point original =
         sys_days{year{2030} / month{1} / day{1}} + hours{12} + minutes{0} + seconds{0};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      system_clock::time_point parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(time_point_cast<seconds>(parsed) == time_point_cast<seconds>(original));
   };

   "chrono_combined_struct_roundtrip"_test = [] {
      using namespace std::chrono;
      chrono_combined_struct original{};
      original.name = "test_config";
      original.timeout = seconds{30};
      original.created_at = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30} + seconds{45};
      original.latency = milliseconds{150};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      chrono_combined_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.name == original.name);
      expect(parsed.timeout == original.timeout);
      expect(time_point_cast<seconds>(parsed.created_at) == time_point_cast<seconds>(original.created_at));
      expect(parsed.latency == original.latency);
   };

   // ========== std::set tests ==========

   "set_int_write"_test = [] {
      std::set<int> s = {1, 2, 3};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "[1, 2, 3]");
   };

   "set_int_read"_test = [] {
      std::set<int> s{};
      std::string input = "[3, 1, 2]";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.size() == 3);
      expect(s.contains(1));
      expect(s.contains(2));
      expect(s.contains(3));
   };

   "set_string_write"_test = [] {
      std::set<std::string> s = {"apple", "banana", "cherry"};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == R"(["apple", "banana", "cherry"])");
   };

   "set_string_read"_test = [] {
      std::set<std::string> s{};
      std::string input = R"(["cherry", "apple", "banana"])";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.size() == 3);
      expect(s.contains("apple"));
      expect(s.contains("banana"));
      expect(s.contains("cherry"));
   };

   "set_empty_write"_test = [] {
      std::set<int> s{};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "[]");
   };

   "set_empty_read"_test = [] {
      std::set<int> s{1, 2, 3}; // Pre-populate
      std::string input = "[]";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.empty());
   };

   "set_roundtrip"_test = [] {
      std::set<int> original = {10, 20, 30, 40, 50};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      std::set<int> parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "set_duplicates_in_input"_test = [] {
      // Sets should handle duplicate values (they just get deduplicated)
      std::set<int> s{};
      std::string input = "[1, 2, 2, 3, 3, 3]";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.size() == 3);
      expect(s.contains(1));
      expect(s.contains(2));
      expect(s.contains(3));
   };

   "set_struct_write"_test = [] {
      set_test_struct s{};
      s.int_set = {1, 2, 3};
      s.string_set = {"a", "b", "c"};

      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value().find("int_set = [1, 2, 3]") != std::string::npos);
      expect(result.value().find(R"(string_set = ["a", "b", "c"])") != std::string::npos);
   };

   "set_struct_read"_test = [] {
      std::string input = R"(int_set = [3, 2, 1]
string_set = ["z", "y", "x"])";

      set_test_struct s{};
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.int_set.size() == 3);
      expect(s.int_set.contains(1));
      expect(s.int_set.contains(2));
      expect(s.int_set.contains(3));
      expect(s.string_set.size() == 3);
      expect(s.string_set.contains("x"));
      expect(s.string_set.contains("y"));
      expect(s.string_set.contains("z"));
   };

   "set_struct_roundtrip"_test = [] {
      set_test_struct original{};
      original.int_set = {100, 200, 300};
      original.string_set = {"foo", "bar", "baz"};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      set_test_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   // ========== std::unordered_set tests ==========

   "unordered_set_int_write"_test = [] {
      std::unordered_set<int> s = {1, 2, 3};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      // Order is unspecified, but should contain all elements
      expect(result.value().find("1") != std::string::npos);
      expect(result.value().find("2") != std::string::npos);
      expect(result.value().find("3") != std::string::npos);
   };

   "unordered_set_int_read"_test = [] {
      std::unordered_set<int> s{};
      std::string input = "[3, 1, 2]";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.size() == 3);
      expect(s.contains(1));
      expect(s.contains(2));
      expect(s.contains(3));
   };

   "unordered_set_empty_write"_test = [] {
      std::unordered_set<int> s{};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "[]");
   };

   "unordered_set_empty_read"_test = [] {
      std::unordered_set<int> s{1, 2, 3}; // Pre-populate
      std::string input = "[]";
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.empty());
   };

   "unordered_set_roundtrip"_test = [] {
      std::unordered_set<int> original = {10, 20, 30, 40, 50};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      std::unordered_set<int> parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "unordered_set_struct_roundtrip"_test = [] {
      unordered_set_test_struct original{};
      original.int_uset = {100, 200, 300};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      unordered_set_test_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   // ========== Combined container tests ==========

   "combined_containers_write"_test = [] {
      combined_containers_struct s{};
      s.vec = {1, 2, 3};
      s.set = {4, 5, 6};
      s.arr = {7, 8, 9};

      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value().find("vec = [1, 2, 3]") != std::string::npos);
      expect(result.value().find("set = [4, 5, 6]") != std::string::npos);
      expect(result.value().find("arr = [7, 8, 9]") != std::string::npos);
   };

   "combined_containers_read"_test = [] {
      std::string input = R"(vec = [1, 2, 3]
set = [6, 5, 4]
arr = [7, 8, 9])";

      combined_containers_struct s{};
      auto error = glz::read_toml(s, input);
      expect(!error) << glz::format_error(error, input);
      expect(s.vec == std::vector<int>{1, 2, 3});
      expect(s.set == std::set<int>{4, 5, 6});
      expect(s.arr == std::array<int, 3>{7, 8, 9});
   };

   "combined_containers_roundtrip"_test = [] {
      combined_containers_struct original{};
      original.vec = {10, 20, 30};
      original.set = {40, 50, 60};
      original.arr = {70, 80, 90};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      combined_containers_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   // ========== Edge cases and error handling ==========

   "system_time_invalid_format"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "not-a-datetime";
      auto error = glz::read_toml(tp, input);
      expect(error);
   };

   "system_time_invalid_date"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-13-45T25:61:61Z"; // Invalid month, day, hour, minute, second
      auto error = glz::read_toml(tp, input);
      expect(error);
   };

   "system_time_too_short"_test = [] {
      using namespace std::chrono;
      system_clock::time_point tp{};
      std::string input = "2024-06-15"; // Date only, no time (too short for time_point)
      auto error = glz::read_toml(tp, input);
      expect(error);
   };

   "set_nested_array"_test = [] {
      // Sets of complex types
      std::set<std::pair<int, int>> s{};
      // This tests that the implementation handles value types correctly
      // Note: std::pair may not work directly without meta, but this tests the concept
   };

   "duration_large_value"_test = [] {
      std::chrono::seconds s{999999999};
      auto result = glz::write_toml(s);
      expect(result.has_value());
      expect(result.value() == "999999999");

      std::chrono::seconds parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.count() == 999999999);
   };

   // ========== TOML Local Date (year_month_day) tests ==========

   "local_date_write"_test = [] {
      using namespace std::chrono;
      year_month_day ymd{year{2024}, month{6}, day{15}};
      auto result = glz::write_toml(ymd);
      expect(result.has_value());
      expect(result.value() == "2024-06-15");
   };

   "local_date_read"_test = [] {
      using namespace std::chrono;
      year_month_day ymd{};
      std::string input = "2024-12-25";
      auto error = glz::read_toml(ymd, input);
      expect(!error) << glz::format_error(error, input);
      expect(ymd.year() == year{2024});
      expect(ymd.month() == month{12});
      expect(ymd.day() == day{25});
   };

   "local_date_roundtrip"_test = [] {
      using namespace std::chrono;
      year_month_day original{year{2030}, month{1}, day{1}};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      year_month_day parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   "local_date_leap_year"_test = [] {
      using namespace std::chrono;
      year_month_day ymd{};
      std::string input = "2024-02-29"; // 2024 is a leap year
      auto error = glz::read_toml(ymd, input);
      expect(!error) << glz::format_error(error, input);
      expect(ymd.year() == year{2024});
      expect(ymd.month() == month{2});
      expect(ymd.day() == day{29});
      expect(ymd.ok());
   };

   "local_date_invalid"_test = [] {
      using namespace std::chrono;
      year_month_day ymd{};
      std::string input = "2024-02-30"; // Invalid date
      auto error = glz::read_toml(ymd, input);
      expect(error);
   };

   "local_date_struct_roundtrip"_test = [] {
      using namespace std::chrono;
      local_date_test_struct original{};
      original.date = year_month_day{year{2024}, month{6}, day{15}};
      original.value = 42;

      auto result = glz::write_toml(original);
      expect(result.has_value());

      local_date_test_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed == original);
   };

   // ========== TOML Local Time (hh_mm_ss) tests ==========

   "local_time_write_seconds"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{hours{10} + minutes{30} + seconds{45}};
      auto result = glz::write_toml(tod);
      expect(result.has_value());
      expect(result.value() == "10:30:45");
   };

   "local_time_write_milliseconds"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<milliseconds> tod{hours{10} + minutes{30} + seconds{45} + milliseconds{123}};
      auto result = glz::write_toml(tod);
      expect(result.has_value());
      expect(result.value() == "10:30:45.123");
   };

   "local_time_read_basic"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "23:59:59";
      auto error = glz::read_toml(tod, input);
      expect(!error) << glz::format_error(error, input);
      expect(tod.hours().count() == 23);
      expect(tod.minutes().count() == 59);
      expect(tod.seconds().count() == 59);
   };

   "local_time_read_fractional"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<milliseconds> tod{milliseconds{0}};
      std::string input = "12:30:45.500";
      auto error = glz::read_toml(tod, input);
      expect(!error) << glz::format_error(error, input);
      expect(tod.hours().count() == 12);
      expect(tod.minutes().count() == 30);
      expect(tod.seconds().count() == 45);
      expect(tod.subseconds().count() == 500);
   };

   "local_time_read_without_seconds"_test = [] {
      // TOML allows omitting seconds
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "14:30";
      auto error = glz::read_toml(tod, input);
      expect(!error) << glz::format_error(error, input);
      expect(tod.hours().count() == 14);
      expect(tod.minutes().count() == 30);
      expect(tod.seconds().count() == 0);
   };

   "local_time_roundtrip"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> original{hours{8} + minutes{15} + seconds{30}};
      auto result = glz::write_toml(original);
      expect(result.has_value());

      hh_mm_ss<seconds> parsed{seconds{0}};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.hours() == original.hours());
      expect(parsed.minutes() == original.minutes());
      expect(parsed.seconds() == original.seconds());
   };

   "local_time_midnight"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "00:00:00";
      auto error = glz::read_toml(tod, input);
      expect(!error) << glz::format_error(error, input);
      expect(tod.hours().count() == 0);
      expect(tod.minutes().count() == 0);
      expect(tod.seconds().count() == 0);
   };

   "local_time_end_of_day"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "23:59:59";
      auto error = glz::read_toml(tod, input);
      expect(!error) << glz::format_error(error, input);
      expect(tod.hours().count() == 23);
      expect(tod.minutes().count() == 59);
      expect(tod.seconds().count() == 59);
   };

   "local_time_invalid_hour"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "25:00:00";
      auto error = glz::read_toml(tod, input);
      expect(error);
   };

   "local_time_invalid_minute"_test = [] {
      using namespace std::chrono;
      hh_mm_ss<seconds> tod{seconds{0}};
      std::string input = "12:60:00";
      auto error = glz::read_toml(tod, input);
      expect(error);
   };

   "local_time_struct_roundtrip"_test = [] {
      using namespace std::chrono;
      local_time_test_struct original{};
      original.time_sec = hh_mm_ss<seconds>{hours{10} + minutes{30} + seconds{45}};
      original.time_ms = hh_mm_ss<milliseconds>{hours{12} + minutes{0} + seconds{0} + milliseconds{500}};

      auto result = glz::write_toml(original);
      expect(result.has_value());

      local_time_test_struct parsed{};
      auto error = glz::read_toml(parsed, result.value());
      expect(!error) << glz::format_error(error, result.value());
      expect(parsed.time_sec.hours() == original.time_sec.hours());
      expect(parsed.time_sec.minutes() == original.time_sec.minutes());
      expect(parsed.time_sec.seconds() == original.time_sec.seconds());
      expect(parsed.time_ms.hours() == original.time_ms.hours());
      expect(parsed.time_ms.minutes() == original.time_ms.minutes());
      expect(parsed.time_ms.seconds() == original.time_ms.seconds());
      expect(parsed.time_ms.subseconds() == original.time_ms.subseconds());
   };
};

// Bounded buffer overflow tests for TOML format
namespace toml_bounded_buffer_tests
{
   struct simple_toml_obj
   {
      int x = 42;
      std::string name = "hello";
      bool active = true;
   };

   struct large_toml_obj
   {
      int x = 42;
      std::string long_name = "this is a very long string that definitely won't fit in a tiny buffer";
      std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
      double value = 3.14159265358979;
   };

   struct toml_nested
   {
      int id = 1;
      ::nested child{};
   };

   struct toml_with_array
   {
      std::vector<int> numbers = {1, 2, 3, 4, 5};
   };
}

suite toml_bounded_buffer_overflow_tests = [] {
   using namespace toml_bounded_buffer_tests;

   "toml write to std::array with sufficient space succeeds"_test = [] {
      simple_toml_obj obj{};
      std::array<char, 512> buffer{};

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write should succeed with sufficient buffer";
      expect(result.count > 0) << "count should be non-zero";
      expect(result.count < buffer.size()) << "count should be less than buffer size";

      std::string_view toml(buffer.data(), result.count);
      expect(toml.find("x = 42") != std::string_view::npos) << "TOML should contain x = 42";
   };

   "toml write to std::array that is too small returns buffer_overflow"_test = [] {
      large_toml_obj obj{};
      std::array<char, 10> buffer{};

      auto result = glz::write_toml(obj, buffer);
      expect(result.ec == glz::error_code::buffer_overflow) << "should return buffer_overflow error";
   };

   "toml write to std::span with sufficient space succeeds"_test = [] {
      simple_toml_obj obj{};
      std::array<char, 512> storage{};
      std::span<char> buffer(storage);

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write should succeed with sufficient buffer";
      expect(result.count > 0) << "count should be non-zero";
   };

   "toml write to std::span that is too small returns buffer_overflow"_test = [] {
      large_toml_obj obj{};
      std::array<char, 5> storage{};
      std::span<char> buffer(storage);

      auto result = glz::write_toml(obj, buffer);
      expect(result.ec == glz::error_code::buffer_overflow) << "should return buffer_overflow error";
   };

   "toml write nested struct to bounded buffer"_test = [] {
      toml_nested obj{};
      std::array<char, 512> buffer{};

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write should succeed";
      expect(result.count > 0) << "count should be non-zero";
   };

   "toml resizable buffer still works as before"_test = [] {
      simple_toml_obj obj{};
      std::string buffer;

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write to resizable buffer should succeed";
      expect(buffer.size() > 0) << "buffer should have data";
   };

   "toml write array to bounded buffer"_test = [] {
      toml_with_array obj{};
      std::array<char, 512> buffer{};

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write should succeed";
   };

   "toml write map to bounded buffer"_test = [] {
      std::map<std::string, int> obj{{"one", 1}, {"two", 2}, {"three", 3}};
      std::array<char, 512> buffer{};

      auto result = glz::write_toml(obj, buffer);
      expect(not result) << "write should succeed";
   };
};

// ========== Array-of-Tables test structures ==========

struct product
{
   std::string name{};
   int sku{};

   bool operator==(const product&) const = default;
};

template <>
struct glz::meta<product>
{
   using T = product;
   static constexpr auto value = object("name", &T::name, "sku", &T::sku);
};

struct catalog
{
   std::string store_name{};
   std::vector<product> products{};

   bool operator==(const catalog&) const = default;
};

template <>
struct glz::meta<catalog>
{
   using T = catalog;
   static constexpr auto value = object("store_name", &T::store_name, "products", &T::products);
};

struct fruit_variety
{
   std::string name{};

   bool operator==(const fruit_variety&) const = default;
};

template <>
struct glz::meta<fruit_variety>
{
   using T = fruit_variety;
   static constexpr auto value = object("name", &T::name);
};

struct fruit
{
   std::string name{};
   std::vector<fruit_variety> varieties{};

   bool operator==(const fruit&) const = default;
};

template <>
struct glz::meta<fruit>
{
   using T = fruit;
   static constexpr auto value = object("name", &T::name, "varieties", &T::varieties);
};

struct fruit_basket
{
   std::vector<fruit> fruits{};

   bool operator==(const fruit_basket&) const = default;
};

template <>
struct glz::meta<fruit_basket>
{
   using T = fruit_basket;
   static constexpr auto value = object("fruits", &T::fruits);
};

// Reflectable struct for array-of-tables
struct reflectable_item
{
   std::string id{};
   int count{};

   bool operator==(const reflectable_item&) const = default;
};

struct reflectable_container
{
   std::string name{};
   std::vector<reflectable_item> items{};

   bool operator==(const reflectable_container&) const = default;
};

// Struct for the TOML spec example test (needs external linkage)
struct simple_catalog
{
   std::vector<product> products{};

   bool operator==(const simple_catalog&) const = default;
};

template <>
struct glz::meta<simple_catalog>
{
   using T = simple_catalog;
   static constexpr auto value = object("products", &T::products);
};

struct quoted_header_catalog
{
   std::vector<product> products_list{};

   bool operator==(const quoted_header_catalog&) const = default;
};

// Structs for edge case tests (need external linkage)
struct item_with_tags
{
   std::string name{};
   std::vector<int> tags{};

   bool operator==(const item_with_tags&) const = default;
};

template <>
struct glz::meta<item_with_tags>
{
   using T = item_with_tags;
   static constexpr auto value = object("name", &T::name, "tags", &T::tags);
};

struct container_with_tags
{
   std::vector<item_with_tags> items{};

   bool operator==(const container_with_tags&) const = default;
};

template <>
struct glz::meta<container_with_tags>
{
   using T = container_with_tags;
   static constexpr auto value = object("items", &T::items);
};

struct mixed_container
{
   std::string title{};
   nested inner{};
   std::vector<product> items{};

   bool operator==(const mixed_container&) const = default;
};

template <>
struct glz::meta<mixed_container>
{
   using T = mixed_container;
   static constexpr auto value = object("title", &T::title, "inner", &T::inner, "items", &T::items);
};

suite array_of_tables_tests = [] {
   "write_array_of_tables_basic"_test = [] {
      catalog c{};
      c.store_name = "Hardware Store";
      c.products = {{"Hammer", 738594937}, {"Nail", 284758393}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // Scalar fields should come first, then array-of-tables
      expect(buffer == R"(store_name = "Hardware Store"
[[products]]
name = "Hammer"
sku = 738594937

[[products]]
name = "Nail"
sku = 284758393
)");
   };

   "write_array_of_tables_empty"_test = [] {
      catalog c{};
      c.store_name = "Empty Store";
      c.products = {};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // Empty array should be written as inline []
      expect(buffer == R"(store_name = "Empty Store"
products = [])");
   };

   "read_array_of_tables_basic"_test = [] {
      std::string input = R"(store_name = "Hardware Store"
[[products]]
name = "Hammer"
sku = 738594937

[[products]]
name = "Nail"
sku = 284758393
)";

      catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.store_name == "Hardware Store");
      expect(c.products.size() == 2);
      expect(c.products[0].name == "Hammer");
      expect(c.products[0].sku == 738594937);
      expect(c.products[1].name == "Nail");
      expect(c.products[1].sku == 284758393);
   };

   "read_array_of_tables_single_element"_test = [] {
      std::string input = R"(store_name = "Single Item Store"
[[products]]
name = "Screwdriver"
sku = 123456
)";

      catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.store_name == "Single Item Store");
      expect(c.products.size() == 1);
      expect(c.products[0].name == "Screwdriver");
      expect(c.products[0].sku == 123456);
   };

   "roundtrip_array_of_tables"_test = [] {
      catalog original{};
      original.store_name = "Test Store";
      original.products = {{"Item1", 111}, {"Item2", 222}, {"Item3", 333}};

      std::string buffer{};
      expect(not glz::write_toml(original, buffer));

      catalog parsed{};
      expect(not glz::read_toml(parsed, buffer));

      expect(original == parsed);
   };

   "read_array_of_tables_toml_spec_example"_test = [] {
      // Example from TOML spec
      std::string input = R"([[products]]
name = "Hammer"
sku = 738594937

[[products]]

[[products]]
name = "Nail"
sku = 284758393
)";

      simple_catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.products.size() == 3);
      expect(c.products[0].name == "Hammer");
      expect(c.products[0].sku == 738594937);
      // Second element is empty (default values)
      expect(c.products[1].name == "");
      expect(c.products[1].sku == 0);
      expect(c.products[2].name == "Nail");
      expect(c.products[2].sku == 284758393);
   };

   "write_nested_array_of_tables"_test = [] {
      // Nested array-of-tables: fruits is an array, each fruit has varieties array
      fruit_basket basket{};
      basket.fruits = {{"apple", {{"red delicious"}, {"granny smith"}}}};

      std::string buffer{};
      expect(not glz::write_toml(basket, buffer));

      // Verify nested arrays use TOML-spec-compliant [[parent.child]] syntax
      expect(buffer.find("[[fruits]]") != std::string::npos);
      expect(buffer.find("name = \"apple\"") != std::string::npos);
      expect(buffer.find("[[fruits.varieties]]") != std::string::npos); // Full dotted path
      expect(buffer.find("name = \"red delicious\"") != std::string::npos);
      expect(buffer.find("name = \"granny smith\"") != std::string::npos);
   };

   "reflectable_array_of_tables_write"_test = [] {
      reflectable_container c{};
      c.name = "Test Container";
      c.items = {{"A", 1}, {"B", 2}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      expect(buffer.find("name = \"Test Container\"") != std::string::npos);
      expect(buffer.find("[[items]]") != std::string::npos);
      expect(buffer.find("id = \"A\"") != std::string::npos);
      expect(buffer.find("id = \"B\"") != std::string::npos);
   };

   "reflectable_array_of_tables_read"_test = [] {
      std::string input = R"(name = "Parsed Container"
[[items]]
id = "X"
count = 10

[[items]]
id = "Y"
count = 20
)";

      reflectable_container c{};
      expect(not glz::read_toml(c, input));

      expect(c.name == "Parsed Container");
      expect(c.items.size() == 2);
      expect(c.items[0].id == "X");
      expect(c.items[0].count == 10);
      expect(c.items[1].id == "Y");
      expect(c.items[1].count == 20);
   };

   "reflectable_array_of_tables_roundtrip"_test = [] {
      reflectable_container original{};
      original.name = "Roundtrip Test";
      original.items = {{"First", 100}, {"Second", 200}};

      std::string buffer{};
      expect(not glz::write_toml(original, buffer));

      reflectable_container parsed{};
      expect(not glz::read_toml(parsed, buffer));

      expect(original == parsed);
   };

   // ========== Edge Case Tests ==========

   "read_array_of_tables_at_file_start"_test = [] {
      // Array-of-tables can appear at the start of a file without preceding scalars
      std::string input = R"([[products]]
name = "First"
sku = 100

[[products]]
name = "Second"
sku = 200
)";

      simple_catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.products.size() == 2);
      expect(c.products[0].name == "First");
      expect(c.products[1].name == "Second");
   };

   "read_array_of_tables_with_comments"_test = [] {
      // Comments should be ignored around array-of-tables headers
      std::string input = R"(store_name = "Test"
# Comment before array-of-tables
[[products]]
name = "Item1"
sku = 1
# Comment between entries

[[products]]
# Comment after header
name = "Item2"
sku = 2
)";

      catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.store_name == "Test");
      expect(c.products.size() == 2);
      expect(c.products[0].name == "Item1");
      expect(c.products[1].name == "Item2");
   };

   "read_array_of_tables_multiple_empty"_test = [] {
      // Multiple consecutive empty array-of-tables entries
      std::string input = R"([[products]]
[[products]]
[[products]]
name = "OnlyThird"
sku = 3
)";

      simple_catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.products.size() == 3);
      expect(c.products[0].name == "");
      expect(c.products[0].sku == 0);
      expect(c.products[1].name == "");
      expect(c.products[1].sku == 0);
      expect(c.products[2].name == "OnlyThird");
      expect(c.products[2].sku == 3);
   };

   "read_array_of_tables_with_whitespace"_test = [] {
      // Whitespace in various positions should be handled
      std::string input = R"(  [[  products  ]]
name = "Spaced"
sku = 42
)";

      simple_catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.products.size() == 1);
      expect(c.products[0].name == "Spaced");
   };

   "read_array_of_tables_error_missing_bracket"_test = [] {
      // Missing closing bracket should error
      std::string input = R"([[products]
name = "Bad"
)";

      simple_catalog c{};
      auto error = glz::read_toml(c, input);
      expect(error);
      expect(error == glz::error_code::syntax_error);
   };

   "read_array_of_tables_error_single_bracket"_test = [] {
      // Using single bracket when expecting array-of-tables should be handled
      // This is a normal table, not array-of-tables, so it would try to write to "products" as a table
      std::string input = R"([products]
name = "NotArray"
)";

      simple_catalog c{};
      auto error = glz::read_toml(c, input);
      // This should error because products is an array, not a single object
      expect(error);
   };

   "write_array_of_tables_with_inline_array_field"_test = [] {
      // Array-of-tables where each element has an inline array field
      container_with_tags c{};
      c.items = {{"First", {1, 2, 3}}, {"Second", {4, 5}}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // Should have [[items]] with inline array tags = [...]
      expect(buffer.find("[[items]]") != std::string::npos);
      expect(buffer.find("tags = [1, 2, 3]") != std::string::npos);
      expect(buffer.find("tags = [4, 5]") != std::string::npos);
   };

   "nested_array_of_tables_roundtrip"_test = [] {
      // Complete roundtrip for nested array-of-tables with TOML-spec-compliant [[parent.child]] syntax
      fruit_basket original{};
      original.fruits = {
         {"apple", {{"red delicious"}, {"granny smith"}, {"fuji"}}},
         {"banana", {{"cavendish"}}},
         {"orange", {}} // Empty varieties
      };

      std::string buffer{};
      expect(not glz::write_toml(original, buffer));

      // Verify spec-compliant output
      expect(buffer.find("[[fruits]]") != std::string::npos);
      expect(buffer.find("[[fruits.varieties]]") != std::string::npos);

      fruit_basket parsed{};
      expect(not glz::read_toml(parsed, buffer));

      expect(parsed.fruits.size() == 3);
      expect(parsed.fruits[0].name == "apple");
      expect(parsed.fruits[0].varieties.size() == 3);
      expect(parsed.fruits[0].varieties[0].name == "red delicious");
      expect(parsed.fruits[0].varieties[1].name == "granny smith");
      expect(parsed.fruits[0].varieties[2].name == "fuji");
      expect(parsed.fruits[1].name == "banana");
      expect(parsed.fruits[1].varieties.size() == 1);
      expect(parsed.fruits[1].varieties[0].name == "cavendish");
      expect(parsed.fruits[2].name == "orange");
      expect(parsed.fruits[2].varieties.size() == 0);
   };

   "write_array_of_tables_single_element"_test = [] {
      // Single element should still use [[]] syntax
      catalog c{};
      c.store_name = "Single";
      c.products = {{"Only", 1}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      expect(buffer.find("[[products]]") != std::string::npos);
      expect(buffer.find("name = \"Only\"") != std::string::npos);
   };

   "array_of_tables_preserves_order"_test = [] {
      // Verify elements maintain their order through roundtrip
      catalog original{};
      original.store_name = "Ordered";
      original.products = {{"A", 1}, {"B", 2}, {"C", 3}, {"D", 4}, {"E", 5}};

      std::string buffer{};
      expect(not glz::write_toml(original, buffer));

      catalog parsed{};
      expect(not glz::read_toml(parsed, buffer));

      expect(parsed.products.size() == 5);
      for (size_t i = 0; i < 5; ++i) {
         expect(parsed.products[i] == original.products[i]);
      }
   };

   "read_array_of_tables_partial_fields"_test = [] {
      // Some entries have all fields, some have partial
      std::string input = R"([[products]]
name = "Full"
sku = 100

[[products]]
name = "NameOnly"

[[products]]
sku = 200
)";

      simple_catalog c{};
      expect(not glz::read_toml(c, input));

      expect(c.products.size() == 3);
      expect(c.products[0].name == "Full");
      expect(c.products[0].sku == 100);
      expect(c.products[1].name == "NameOnly");
      expect(c.products[1].sku == 0); // Default
      expect(c.products[2].name == ""); // Default
      expect(c.products[2].sku == 200);
   };

   "array_of_tables_mixed_with_scalars_and_tables"_test = [] {
      // Test struct with scalar, nested table, AND array of tables
      mixed_container original{};
      original.title = "Mixed";
      original.inner = {42, "nested_value"};
      original.items = {{"Item1", 1}, {"Item2", 2}};

      std::string buffer{};
      expect(not glz::write_toml(original, buffer));

      // Scalars should come first, then [inner], then [[items]]
      auto title_pos = buffer.find("title");
      auto inner_pos = buffer.find("[inner]");
      auto items_pos = buffer.find("[[items]]");

      expect(title_pos != std::string::npos);
      expect(inner_pos != std::string::npos);
      expect(items_pos != std::string::npos);
      expect(title_pos < inner_pos);
      expect(inner_pos < items_pos);
   };
};

// Struct for inline_table wrapper tests
struct inline_product
{
   std::string name{};
   int sku{};

   bool operator==(const inline_product&) const = default;
};

template <>
struct glz::meta<inline_product>
{
   using T = inline_product;
   static constexpr auto value = object(&T::name, &T::sku);
};

struct inline_catalog
{
   std::string store_name{};
   std::vector<inline_product> products{};
};

template <>
struct glz::meta<inline_catalog>
{
   using T = inline_catalog;
   // Use inline_table wrapper to force inline syntax instead of [[products]]
   static constexpr auto value = object(&T::store_name, "products", glz::inline_table<&T::products>);
};

struct mixed_inline_and_aot_container
{
   std::string title{};
   std::vector<inline_product> inline_items{}; // Will use inline_table
   std::vector<product> aot_items{}; // Will use array-of-tables
};

template <>
struct glz::meta<mixed_inline_and_aot_container>
{
   using T = mixed_inline_and_aot_container;
   static constexpr auto value = object(&T::title, "inline_items", glz::inline_table<&T::inline_items>, // Inline syntax
                                        &T::aot_items // Array-of-tables syntax
   );
};

suite inline_table_tests = [] {
   "write_inline_table_basic"_test = [] {
      inline_catalog c{};
      c.store_name = "Hardware Store";
      c.products = {{"Hammer", 100}, {"Nail", 200}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // Should use inline table syntax, not [[products]]
      expect(buffer.find("[[products]]") == std::string::npos) << "Should not use array-of-tables syntax";
      expect(buffer.find("products = [{") != std::string::npos) << "Should use inline table syntax";
      expect(buffer.find("name = \"Hammer\"") != std::string::npos);
      expect(buffer.find("sku = 100") != std::string::npos);
   };

   "write_inline_table_empty"_test = [] {
      inline_catalog c{};
      c.store_name = "Empty Store";
      c.products = {};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      expect(buffer.find("products = []") != std::string::npos) << "Empty inline array";
   };

   "write_inline_table_single_element"_test = [] {
      inline_catalog c{};
      c.store_name = "Single Item Store";
      c.products = {{"Widget", 42}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      expect(buffer.find("[[products]]") == std::string::npos);
      expect(buffer.find("products = [{name = \"Widget\", sku = 42}]") != std::string::npos);
   };

   "write_inline_table_multiple_elements"_test = [] {
      inline_catalog c{};
      c.store_name = "Multi Store";
      c.products = {{"A", 1}, {"B", 2}, {"C", 3}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // All elements should be on the same line with inline table format
      expect(buffer.find("}, {") != std::string::npos) << "Elements separated by comma-brace";
      expect(buffer.find("[[products]]") == std::string::npos);
   };

   "mixed_inline_and_array_of_tables"_test = [] {
      // Test that inline_table and regular array-of-tables can coexist
      mixed_inline_and_aot_container c{};
      c.title = "Mixed Container";
      c.inline_items = {{"Inline1", 10}, {"Inline2", 20}};
      c.aot_items = {{"AOT1", 100}, {"AOT2", 200}};

      std::string buffer{};
      expect(not glz::write_toml(c, buffer));

      // inline_items should use inline syntax
      expect(buffer.find("inline_items = [{") != std::string::npos) << "Inline items should use inline syntax";
      expect(buffer.find("[[inline_items]]") == std::string::npos) << "Inline items should NOT use [[]] syntax";

      // aot_items should use array-of-tables syntax
      expect(buffer.find("[[aot_items]]") != std::string::npos) << "AOT items should use [[]] syntax";
   };

   "write_with_toml_opts_inline"_test = [] {
      // Test using toml_opts with inline_arrays to force inline arrays globally
      catalog c{};
      c.store_name = "Hardware Store";
      c.products = {{"Hammer", 100}, {"Nail", 200}};

      std::string buffer{};
      expect(not glz::write<glz::toml_opts{true}>(c, buffer));

      // Should use inline syntax, not array-of-tables
      expect(buffer.find("[[products]]") == std::string::npos) << "Should not use [[]] syntax";
      expect(buffer.find("products = [{") != std::string::npos) << "Should use inline array syntax";
   };

   "write_toml_vs_toml_opts_inline_comparison"_test = [] {
      // Compare default write_toml (array-of-tables) vs toml_opts{true}
      catalog c{};
      c.store_name = "Test";
      c.products = {{"A", 1}};

      std::string aot_buffer{};
      std::string inline_buffer{};

      expect(not glz::write_toml(c, aot_buffer));
      expect(not glz::write<glz::toml_opts{true}>(c, inline_buffer));

      // Default uses array-of-tables
      expect(aot_buffer.find("[[products]]") != std::string::npos);
      expect(aot_buffer.find("products = [") == std::string::npos);

      // Inline uses inline arrays
      expect(inline_buffer.find("[[products]]") == std::string::npos);
      expect(inline_buffer.find("products = [{") != std::string::npos);
   };

   "toml_opts_as_constexpr"_test = [] {
      // Users can create their own named constants
      catalog c{};
      c.store_name = "Named";
      c.products = {{"Y", 99}};

      std::string buffer{};
      constexpr glz::toml_opts inline_opts{true};
      expect(not glz::write<inline_opts>(c, buffer));

      expect(buffer.find("[[products]]") == std::string::npos);
      expect(buffer.find("products = [{") != std::string::npos);
   };
};

// ============================================
// Variant and generic type tests for TOML
// ============================================

#include "glaze/json.hpp"
#include "glaze/json/generic.hpp"

suite variant_toml_tests = [] {
   "variant_write_toml_int"_test = [] {
      std::variant<int, double, std::string, bool> v = 42;
      std::string buffer{};
      auto ec = glz::write_toml(v, buffer);
      expect(not ec);
      expect(buffer == "42");
   };

   "variant_write_toml_double"_test = [] {
      std::variant<int, double, std::string, bool> v = 3.14;
      std::string buffer{};
      auto ec = glz::write_toml(v, buffer);
      expect(not ec);
      expect(buffer.find("3.14") != std::string::npos);
   };

   "variant_write_toml_string"_test = [] {
      std::variant<int, double, std::string, bool> v = std::string{"hello"};
      std::string buffer{};
      auto ec = glz::write_toml(v, buffer);
      expect(not ec);
      expect(buffer == "\"hello\"");
   };

   "variant_write_toml_bool"_test = [] {
      std::variant<int, double, std::string, bool> v = true;
      std::string buffer{};
      auto ec = glz::write_toml(v, buffer);
      expect(not ec);
      expect(buffer == "true");
   };

   "variant_read_toml_int"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "42";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 42);
   };

   "variant_read_toml_double"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "3.14";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<double>(v));
      expect(std::get<double>(v) == 3.14);
   };

   "variant_read_toml_string"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "\"hello world\"";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::string>(v));
      expect(std::get<std::string>(v) == "hello world");
   };

   "variant_read_toml_bool_true"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "true";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<bool>(v));
      expect(std::get<bool>(v) == true);
   };

   "variant_read_toml_bool_false"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "false";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<bool>(v));
      expect(std::get<bool>(v) == false);
   };

   "variant_read_toml_array"_test = [] {
      std::variant<int64_t, std::vector<int>, std::string> v;
      std::string toml = "[1, 2, 3]";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::vector<int>>(v));
      auto& arr = std::get<std::vector<int>>(v);
      expect(arr.size() == 3);
      expect(arr[0] == 1);
      expect(arr[1] == 2);
      expect(arr[2] == 3);
   };

   // Note: TOML inf parsing test removed - the number parser
   // may not support inf/nan for all integer types in variants

   "variant_read_toml_negative_int"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "-123";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == -123);
   };

   "variant_read_toml_scientific"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "1e10";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<double>(v));
      expect(std::get<double>(v) == 1e10);
   };
};

// Tests for glz::generic_i64 with TOML
suite generic_toml_tests = [] {
   "generic_i64_write_toml_int"_test = [] {
      glz::generic_i64 g = int64_t{42};
      std::string buffer{};
      auto ec = glz::write_toml(g, buffer);
      expect(not ec);
      expect(buffer == "42");
   };

   "generic_i64_write_toml_double"_test = [] {
      glz::generic_i64 g = 3.14;
      std::string buffer{};
      auto ec = glz::write_toml(g, buffer);
      expect(not ec);
      expect(buffer.find("3.14") != std::string::npos);
   };

   "generic_i64_write_toml_string"_test = [] {
      glz::generic_i64 g = std::string{"hello"};
      std::string buffer{};
      auto ec = glz::write_toml(g, buffer);
      expect(not ec);
      expect(buffer == "\"hello\"");
   };

   "generic_i64_write_toml_bool"_test = [] {
      glz::generic_i64 g = true;
      std::string buffer{};
      auto ec = glz::write_toml(g, buffer);
      expect(not ec);
      expect(buffer == "true");
   };

   "generic_i64_write_toml_array"_test = [] {
      // First read an array from JSON to properly construct it
      glz::generic_i64 g;
      expect(not glz::read_json(g, "[1, 2, 3]"));
      expect(g.is_array());

      std::string buffer{};
      auto ec = glz::write_toml(g, buffer);
      expect(not ec);
      expect(buffer == "[1, 2, 3]");
   };

   "generic_i64_read_toml_int"_test = [] {
      glz::generic_i64 g;
      std::string toml = "42";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == 42);
   };

   "generic_i64_read_toml_double"_test = [] {
      glz::generic_i64 g;
      std::string toml = "3.14";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      expect(g.holds<double>());
      expect(g.get<double>() == 3.14);
   };

   "generic_i64_read_toml_string"_test = [] {
      glz::generic_i64 g;
      std::string toml = "\"hello world\"";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_string());
      expect(g.get<std::string>() == "hello world");
   };

   "generic_i64_read_toml_bool"_test = [] {
      glz::generic_i64 g;
      std::string toml = "true";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_boolean());
      expect(g.get<bool>() == true);
   };

   "generic_i64_read_toml_array"_test = [] {
      glz::generic_i64 g;
      std::string toml = "[1, 2, 3]";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_array());
      auto& arr = g.get<glz::generic_i64::array_t>();
      expect(arr.size() == 3);
      expect(arr[0].get<int64_t>() == 1);
      expect(arr[1].get<int64_t>() == 2);
      expect(arr[2].get<int64_t>() == 3);
   };

   "generic_i64_read_toml_negative_int"_test = [] {
      glz::generic_i64 g;
      std::string toml = "-999";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == -999);
   };

   "generic_i64_read_toml_scientific"_test = [] {
      glz::generic_i64 g;
      std::string toml = "1.5e10";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      expect(g.holds<double>());
      expect(std::get<double>(g.data) == 1.5e10);
   };

   "generic_i64_roundtrip_toml"_test = [] {
      // Read array from JSON to properly construct it
      glz::generic_i64 original;
      expect(not glz::read_json(original, R"([42, 3.14, "test", true])"));
      expect(original.is_array());

      std::string buffer{};
      auto write_ec = glz::write_toml(original, buffer);
      expect(not write_ec);

      glz::generic_i64 parsed;
      auto read_ec = glz::read_toml(parsed, buffer);
      expect(not read_ec) << glz::format_error(read_ec, buffer);

      expect(parsed.is_array());
      auto& arr = parsed.get<glz::generic_i64::array_t>();
      expect(arr.size() == 4);
      expect(arr[0].get<int64_t>() == 42);
      expect(arr[2].get<std::string>() == "test");
      expect(arr[3].get<bool>() == true);
   };
};

// Tests for glz::generic_u64 with TOML
suite generic_u64_toml_tests = [] {
   "generic_u64_read_toml_positive_int"_test = [] {
      glz::generic_u64 g;
      std::string toml = "42";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      // Positive integers should go to uint64_t (first int type)
      expect(g.holds<uint64_t>());
      expect(g.get<uint64_t>() == 42);
   };

   "generic_u64_read_toml_negative_int"_test = [] {
      glz::generic_u64 g;
      std::string toml = "-42";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      // Negative integers should go to int64_t
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == -42);
   };

   "generic_u64_read_toml_double"_test = [] {
      glz::generic_u64 g;
      std::string toml = "3.14";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_number());
      expect(g.holds<double>());
      expect(g.get<double>() == 3.14);
   };
};

// Tests for glz::generic (f64 mode) with TOML
suite generic_f64_toml_tests = [] {
   "generic_f64_read_toml_int_as_double"_test = [] {
      glz::generic g;
      std::string toml = "42";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      // In f64 mode, all numbers are stored as double
      expect(g.is_number());
      expect(g.holds<double>());
      expect(g.get<double>() == 42.0);
   };

   "generic_f64_roundtrip_toml"_test = [] {
      // Read array from JSON to properly construct it
      glz::generic original;
      expect(not glz::read_json(original, R"([42.0, 3.14, "test"])"));
      expect(original.is_array());

      std::string buffer{};
      auto write_ec = glz::write_toml(original, buffer);
      expect(not write_ec);

      glz::generic parsed;
      auto read_ec = glz::read_toml(parsed, buffer);
      expect(not read_ec) << glz::format_error(read_ec, buffer);

      expect(parsed.is_array());
      auto& arr = parsed.get<glz::generic::array_t>();
      expect(arr.size() == 3);
      expect(arr[2].get<std::string>() == "test");
   };
};

// ============================================
// Corner cases and nested structure tests
// ============================================

suite variant_toml_corner_cases = [] {
   // TOML-specific number formats
   "variant_read_hex_number"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "0xDEAD";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 0xDEAD);
   };

   "variant_read_octal_number"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "0o755";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 0755);
   };

   "variant_read_binary_number"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "0b11010110";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 0b11010110);
   };

   "variant_read_underscore_number"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "1_000_000";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 1000000);
   };

   // Note: inf/nan tests removed - TOML parser doesn't fully support inf/nan in typed arrays
   // The core variant functionality is tested elsewhere

   // String edge cases
   "variant_read_empty_string"_test = [] {
      std::variant<int64_t, double, std::string, bool> v;
      std::string toml = "\"\"";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::string>(v));
      expect(std::get<std::string>(v).empty());
   };

   "variant_read_literal_string"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = R"('literal \n not escaped')";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::string>(v));
      expect(std::get<std::string>(v) == "literal \\n not escaped");
   };

   "variant_read_escaped_string"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = R"("hello\nworld")";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::string>(v));
      expect(std::get<std::string>(v) == "hello\nworld");
   };

   // Empty and single element arrays
   "variant_read_empty_array"_test = [] {
      std::variant<int64_t, std::vector<int64_t>, std::string> v;
      std::string toml = "[]";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::vector<int64_t>>(v));
      expect(std::get<std::vector<int64_t>>(v).empty());
   };

   "variant_read_single_element_array"_test = [] {
      std::variant<int64_t, std::vector<int64_t>, std::string> v;
      std::string toml = "[42]";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::vector<int64_t>>(v));
      auto& arr = std::get<std::vector<int64_t>>(v);
      expect(arr.size() == 1);
      expect(arr[0] == 42);
   };

   // Boundary values
   "variant_read_zero"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "0";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<int64_t>(v));
      expect(std::get<int64_t>(v) == 0);
   };

   "variant_read_negative_zero_float"_test = [] {
      std::variant<int64_t, double, std::string> v;
      std::string toml = "-0.0";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<double>(v));
      expect(std::get<double>(v) == 0.0);
   };

   // Whitespace handling in arrays
   "variant_read_array_with_whitespace"_test = [] {
      std::variant<int64_t, std::vector<int64_t>, std::string> v;
      std::string toml = "[  1  ,  2  ,  3  ]";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::vector<int64_t>>(v));
      auto& arr = std::get<std::vector<int64_t>>(v);
      expect(arr.size() == 3);
      expect(arr[0] == 1);
      expect(arr[1] == 2);
      expect(arr[2] == 3);
   };

   // Nested arrays
   "variant_read_nested_array"_test = [] {
      std::variant<int64_t, std::vector<std::vector<int64_t>>, std::string> v;
      std::string toml = "[[1, 2], [3, 4]]";
      auto ec = glz::read_toml(v, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(std::holds_alternative<std::vector<std::vector<int64_t>>>(v));
      auto& arr = std::get<std::vector<std::vector<int64_t>>>(v);
      expect(arr.size() == 2);
      expect(arr[0].size() == 2);
      expect(arr[0][0] == 1);
      expect(arr[0][1] == 2);
      expect(arr[1][0] == 3);
      expect(arr[1][1] == 4);
   };
};

suite generic_toml_corner_cases = [] {
   // TOML-specific number formats with generic types
   "generic_i64_read_hex"_test = [] {
      glz::generic_i64 g;
      std::string toml = "0xCAFE";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == 0xCAFE);
   };

   "generic_i64_read_octal"_test = [] {
      glz::generic_i64 g;
      std::string toml = "0o777";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == 0777);
   };

   "generic_i64_read_binary"_test = [] {
      glz::generic_i64 g;
      std::string toml = "0b10101010";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == 0b10101010);
   };

   "generic_i64_read_underscore_number"_test = [] {
      glz::generic_i64 g;
      std::string toml = "1_234_567";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == 1234567);
   };

   // Note: inf/nan tests removed - TOML parser doesn't fully support inf/nan in generic arrays
   // The float detection (is_toml_float) correctly identifies inf/nan, but the underlying
   // number parser has limitations for typed arrays

   // Empty containers
   "generic_i64_read_empty_array"_test = [] {
      glz::generic_i64 g;
      std::string toml = "[]";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_array());
      expect(g.get<glz::generic_i64::array_t>().empty());
   };

   "generic_i64_read_empty_string"_test = [] {
      glz::generic_i64 g;
      std::string toml = "\"\"";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<std::string>());
      expect(g.get<std::string>().empty());
   };

   // Nested arrays
   "generic_i64_read_nested_arrays"_test = [] {
      glz::generic_i64 g;
      std::string toml = "[[1, 2], [3, 4], [5]]";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_array());
      auto& arr = g.get<glz::generic_i64::array_t>();
      expect(arr.size() == 3);
      expect(arr[0].is_array());
      expect(arr[0].get<glz::generic_i64::array_t>().size() == 2);
      expect(arr[2].get<glz::generic_i64::array_t>().size() == 1);
   };

   // Mixed type arrays
   "generic_i64_read_mixed_array"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"([1, "two", true, 4.0])";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.is_array());
      auto& arr = g.get<glz::generic_i64::array_t>();
      expect(arr.size() == 4);
      expect(arr[0].holds<int64_t>());
      expect(arr[0].get<int64_t>() == 1);
      expect(arr[1].holds<std::string>());
      expect(arr[1].get<std::string>() == "two");
      expect(arr[2].holds<bool>());
      expect(arr[2].get<bool>() == true);
      expect(arr[3].holds<double>());
      expect(arr[3].get<double>() == 4.0);
   };

   // Literal strings
   "generic_i64_read_literal_string"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"('C:\path\to\file')";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<std::string>());
      expect(g.get<std::string>() == "C:\\path\\to\\file");
   };

   // Boundary values
   "generic_u64_read_large_positive"_test = [] {
      glz::generic_u64 g;
      std::string toml = "18446744073709551615"; // UINT64_MAX
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<uint64_t>());
      expect(g.get<uint64_t>() == UINT64_MAX);
   };

   "generic_i64_read_large_negative"_test = [] {
      glz::generic_i64 g;
      std::string toml = "-9223372036854775808"; // INT64_MIN
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == INT64_MIN);
   };

   "generic_i64_read_large_positive"_test = [] {
      glz::generic_i64 g;
      std::string toml = "9223372036854775807"; // INT64_MAX
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == INT64_MAX);
   };

   // Write generic object to TOML (works because write supports maps)
   "generic_i64_write_object_to_toml"_test = [] {
      glz::generic_i64 original;
      expect(not glz::read_json(original, R"({"name":"test","count":42})"));

      std::string buffer{};
      auto write_ec = glz::write_toml(original, buffer);
      expect(not write_ec);
      // Verify the output contains expected key-value pairs
      expect(buffer.find("name = \"test\"") != std::string::npos);
      expect(buffer.find("count = 42") != std::string::npos);
   };

   // u64 mode boundary cases
   "generic_u64_read_zero"_test = [] {
      glz::generic_u64 g;
      std::string toml = "0";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<uint64_t>());
      expect(g.get<uint64_t>() == 0);
   };

   "generic_u64_read_one"_test = [] {
      glz::generic_u64 g;
      std::string toml = "1";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<uint64_t>());
      expect(g.get<uint64_t>() == 1);
   };

   "generic_u64_read_negative_one"_test = [] {
      glz::generic_u64 g;
      std::string toml = "-1";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<int64_t>());
      expect(g.get<int64_t>() == -1);
   };

   // Note: f64 mode inf/nan tests removed - same limitation as i64 mode

   // Scientific notation variations
   "generic_i64_read_scientific_uppercase_E"_test = [] {
      glz::generic_i64 g;
      std::string toml = "1E10";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<double>());
      expect(g.get<double>() == 1e10);
   };

   "generic_i64_read_scientific_negative_exponent"_test = [] {
      glz::generic_i64 g;
      std::string toml = "1e-5";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<double>());
      expect(std::abs(g.get<double>() - 1e-5) < 1e-10);
   };

   "generic_i64_read_float_with_exponent"_test = [] {
      glz::generic_i64 g;
      std::string toml = "6.022e23";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<double>());
      expect(std::abs(g.get<double>() - 6.022e23) < 1e18);
   };
};

// Tests for reading full TOML documents into generic types (map support)
suite generic_toml_document_tests = [] {
   // Basic TOML document with key-value pairs
   "generic_i64_read_simple_document"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(name = "test"
count = 42
enabled = true)";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.size() == 3);
      expect(obj.at("name").holds<std::string>());
      expect(obj.at("name").get<std::string>() == "test");
      expect(obj.at("count").holds<int64_t>());
      expect(obj.at("count").get<int64_t>() == 42);
      expect(obj.at("enabled").holds<bool>());
      expect(obj.at("enabled").get<bool>() == true);
   };

   // TOML document with nested tables using dotted keys
   "generic_i64_read_dotted_keys"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(server.host = "localhost"
server.port = 8080)";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.contains("server"));
      auto& server = obj.at("server").get<glz::generic_i64::object_t>();
      expect(server.at("host").get<std::string>() == "localhost");
      expect(server.at("port").get<int64_t>() == 8080);
   };

   // TOML document with table sections
   "generic_i64_read_table_sections"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(title = "Config"

[database]
server = "192.168.1.1"
port = 5432

[owner]
name = "Admin")";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.at("title").get<std::string>() == "Config");
      expect(obj.contains("database"));
      auto& db = obj.at("database").get<glz::generic_i64::object_t>();
      expect(db.at("server").get<std::string>() == "192.168.1.1");
      expect(db.at("port").get<int64_t>() == 5432);
      expect(obj.contains("owner"));
      auto& owner = obj.at("owner").get<glz::generic_i64::object_t>();
      expect(owner.at("name").get<std::string>() == "Admin");
   };

   // TOML document with arrays
   "generic_i64_read_document_with_arrays"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(numbers = [1, 2, 3]
names = ["Alice", "Bob"])";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.at("numbers").holds<glz::generic_i64::array_t>());
      auto& numbers = obj.at("numbers").get<glz::generic_i64::array_t>();
      expect(numbers.size() == 3);
      expect(numbers[0].get<int64_t>() == 1);
      expect(numbers[1].get<int64_t>() == 2);
      expect(numbers[2].get<int64_t>() == 3);
      auto& names = obj.at("names").get<glz::generic_i64::array_t>();
      expect(names.size() == 2);
      expect(names[0].get<std::string>() == "Alice");
      expect(names[1].get<std::string>() == "Bob");
   };

   // TOML document with inline table
   "generic_i64_read_inline_table"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(point = { x = 10, y = 20 })";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.contains("point"));
      auto& point = obj.at("point").get<glz::generic_i64::object_t>();
      expect(point.at("x").get<int64_t>() == 10);
      expect(point.at("y").get<int64_t>() == 20);
   };

   // Roundtrip test: JSON -> generic -> TOML -> generic (roundtrip)
   "generic_i64_document_roundtrip"_test = [] {
      glz::generic_i64 original;
      expect(not glz::read_json(original, R"({"name":"test","count":42,"active":true})"));

      std::string toml_buffer{};
      auto write_ec = glz::write_toml(original, toml_buffer);
      expect(not write_ec);

      glz::generic_i64 parsed;
      auto read_ec = glz::read_toml(parsed, toml_buffer);
      expect(not read_ec) << glz::format_error(read_ec, toml_buffer);

      // Verify the parsed values match
      expect(parsed.holds<glz::generic_i64::object_t>());
      auto& obj = parsed.get<glz::generic_i64::object_t>();
      expect(obj.at("name").get<std::string>() == "test");
      expect(obj.at("count").get<int64_t>() == 42);
      expect(obj.at("active").get<bool>() == true);
   };

   // TOML document with mixed types and deep nesting using dotted keys
   "generic_i64_read_deeply_nested_dotted"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"(a.b.c = 123
a.b.d = "nested"
a.e = true)";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& root = g.get<glz::generic_i64::object_t>();
      auto& a = root.at("a").get<glz::generic_i64::object_t>();
      auto& b = a.at("b").get<glz::generic_i64::object_t>();
      expect(b.at("c").get<int64_t>() == 123);
      expect(b.at("d").get<std::string>() == "nested");
      expect(a.at("e").get<bool>() == true);
   };

   // Reading standalone inline table into generic type
   "generic_i64_read_standalone_inline_table"_test = [] {
      glz::generic_i64 g;
      std::string toml = R"({ name = "inline", value = 42 })";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_i64::object_t>());
      auto& obj = g.get<glz::generic_i64::object_t>();
      expect(obj.at("name").get<std::string>() == "inline");
      expect(obj.at("value").get<int64_t>() == 42);
   };

   // Note: Empty string input produces no_read_input error from core reader.
   // This is consistent with other formats (JSON, etc.). Use whitespace-only
   // or comment-only documents if you need to represent "no data".

   // u64 mode document test
   "generic_u64_read_document"_test = [] {
      glz::generic_u64 g;
      std::string toml = R"(positive = 18446744073709551615
negative = -42)";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic_u64::object_t>());
      auto& obj = g.get<glz::generic_u64::object_t>();
      // Large positive number should be uint64_t
      expect(obj.at("positive").holds<uint64_t>());
      expect(obj.at("positive").get<uint64_t>() == UINT64_MAX);
      // Negative number should use int64_t
      expect(obj.at("negative").holds<int64_t>());
      expect(obj.at("negative").get<int64_t>() == -42);
   };

   // f64 mode document test
   "generic_f64_read_document"_test = [] {
      glz::generic g; // f64 mode by default
      std::string toml = R"(integer = 42
float = 3.14)";
      auto ec = glz::read_toml(g, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(g.holds<glz::generic::object_t>());
      auto& obj = g.get<glz::generic::object_t>();
      // In f64 mode, integers are parsed as doubles
      expect(obj.at("integer").holds<double>());
      expect(obj.at("integer").get<double>() == 42.0);
      expect(obj.at("float").holds<double>());
      expect(std::abs(obj.at("float").get<double>() - 3.14) < 0.001);
   };

   // std::map direct read test
   "std_map_read_toml_document"_test = [] {
      std::map<std::string, int64_t> m;
      std::string toml = R"(one = 1
two = 2
three = 3)";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3);
      expect(m["one"] == 1);
      expect(m["two"] == 2);
      expect(m["three"] == 3);
   };

   // std::unordered_map direct read test
   "std_unordered_map_read_toml_document"_test = [] {
      std::unordered_map<std::string, std::string> m;
      std::string toml = R"(name = "Alice"
city = "Boston")";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 2);
      expect(m["name"] == "Alice");
      expect(m["city"] == "Boston");
   };

   // Inline table into std::map
   "std_map_read_inline_table"_test = [] {
      std::map<std::string, int64_t> m;
      std::string toml = R"({ a = 1, b = 2, c = 3 })";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3);
      expect(m["a"] == 1);
      expect(m["b"] == 2);
      expect(m["c"] == 3);
   };

   // ========== std::map with generic value types ==========

   // std::map<std::string, glz::generic> - heterogeneous value types
   "std_map_generic_mixed_values"_test = [] {
      std::map<std::string, glz::generic> m;
      std::string toml = R"(name = "Alice"
age = 30
active = true
score = 95.5
tags = ["developer", "lead"])";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 5);
      expect(std::get<std::string>(m["name"].data) == "Alice");
      expect(std::get<double>(m["age"].data) == 30.0); // f64 mode stores as double
      expect(std::get<bool>(m["active"].data) == true);
      expect(std::abs(std::get<double>(m["score"].data) - 95.5) < 0.001);
      auto& tags = std::get<glz::generic::array_t>(m["tags"].data);
      expect(tags.size() == 2);
      expect(std::get<std::string>(tags[0].data) == "developer");
      expect(std::get<std::string>(tags[1].data) == "lead");
   };

   // std::map<std::string, glz::generic_i64> - preserves integer types
   "std_map_generic_i64_mixed_values"_test = [] {
      std::map<std::string, glz::generic_i64> m;
      std::string toml = R"(name = "Bob"
count = 42
rate = 3.14
enabled = false)";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 4);
      expect(std::get<std::string>(m["name"].data) == "Bob");
      expect(std::get<int64_t>(m["count"].data) == 42); // i64 mode preserves integers
      expect(std::abs(std::get<double>(m["rate"].data) - 3.14) < 0.001);
      expect(std::get<bool>(m["enabled"].data) == false);
   };

   // std::map<std::string, glz::generic_u64> - unsigned integers
   "std_map_generic_u64_mixed_values"_test = [] {
      std::map<std::string, glz::generic_u64> m;
      std::string toml = R"(big_positive = 18446744073709551615
negative = -100
name = "test")";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3);
      expect(std::get<uint64_t>(m["big_positive"].data) == UINT64_MAX);
      expect(std::get<int64_t>(m["negative"].data) == -100); // negative uses int64_t
      expect(std::get<std::string>(m["name"].data) == "test");
   };

   // std::map<std::string, glz::generic_i64> with nested objects via dotted keys
   "std_map_generic_i64_nested_dotted"_test = [] {
      std::map<std::string, glz::generic_i64> m;
      std::string toml = R"(server.host = "localhost"
server.port = 8080
server.ssl = true
database.name = "mydb")";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 2); // "server" and "database"

      // Check server object
      auto& server = std::get<glz::generic_i64::object_t>(m["server"].data);
      expect(std::get<std::string>(server.at("host").data) == "localhost");
      expect(std::get<int64_t>(server.at("port").data) == 8080);
      expect(std::get<bool>(server.at("ssl").data) == true);

      // Check database object
      auto& database = std::get<glz::generic_i64::object_t>(m["database"].data);
      expect(std::get<std::string>(database.at("name").data) == "mydb");
   };

   // std::map<std::string, glz::generic_i64> with table sections
   "std_map_generic_i64_table_sections"_test = [] {
      std::map<std::string, glz::generic_i64> m;
      std::string toml = R"(title = "Config"

[server]
host = "0.0.0.0"
port = 3000

[logging]
level = "debug"
verbose = true)";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3); // "title", "server", "logging"

      expect(std::get<std::string>(m["title"].data) == "Config");

      auto& server = std::get<glz::generic_i64::object_t>(m["server"].data);
      expect(std::get<std::string>(server.at("host").data) == "0.0.0.0");
      expect(std::get<int64_t>(server.at("port").data) == 3000);

      auto& logging = std::get<glz::generic_i64::object_t>(m["logging"].data);
      expect(std::get<std::string>(logging.at("level").data) == "debug");
      expect(std::get<bool>(logging.at("verbose").data) == true);
   };

   // std::map<std::string, glz::generic> with arrays of mixed types
   "std_map_generic_arrays"_test = [] {
      std::map<std::string, glz::generic> m;
      std::string toml = R"(numbers = [1, 2, 3]
strings = ["a", "b", "c"]
mixed_numbers = [1, 2.5, 3])";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3);

      auto& numbers = std::get<glz::generic::array_t>(m["numbers"].data);
      expect(numbers.size() == 3);
      expect(std::get<double>(numbers[0].data) == 1.0);
      expect(std::get<double>(numbers[1].data) == 2.0);
      expect(std::get<double>(numbers[2].data) == 3.0);

      auto& strings = std::get<glz::generic::array_t>(m["strings"].data);
      expect(strings.size() == 3);
      expect(std::get<std::string>(strings[0].data) == "a");

      auto& mixed = std::get<glz::generic::array_t>(m["mixed_numbers"].data);
      expect(mixed.size() == 3);
   };

   // std::map<std::string, glz::generic_i64> with inline tables
   "std_map_generic_i64_inline_tables"_test = [] {
      std::map<std::string, glz::generic_i64> m;
      std::string toml = R"(point = { x = 10, y = 20 }
name = "origin")";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 2);

      auto& point = std::get<glz::generic_i64::object_t>(m["point"].data);
      expect(std::get<int64_t>(point.at("x").data) == 10);
      expect(std::get<int64_t>(point.at("y").data) == 20);

      expect(std::get<std::string>(m["name"].data) == "origin");
   };

   // Roundtrip: std::map<std::string, glz::generic_i64>
   "std_map_generic_i64_roundtrip"_test = [] {
      // Create initial map with various value types
      std::map<std::string, glz::generic_i64> original;
      original["name"].data = std::string{"roundtrip_test"};
      original["count"].data = int64_t{999};
      original["ratio"].data = double{1.5};
      original["active"].data = true;

      // Write to TOML
      std::string toml_buffer{};
      auto write_ec = glz::write_toml(original, toml_buffer);
      expect(not write_ec);

      // Read back
      std::map<std::string, glz::generic_i64> parsed;
      auto read_ec = glz::read_toml(parsed, toml_buffer);
      expect(not read_ec) << glz::format_error(read_ec, toml_buffer);

      // Verify
      expect(parsed.size() == 4);
      expect(std::get<std::string>(parsed["name"].data) == "roundtrip_test");
      expect(std::get<int64_t>(parsed["count"].data) == 999);
      expect(std::abs(std::get<double>(parsed["ratio"].data) - 1.5) < 0.001);
      expect(std::get<bool>(parsed["active"].data) == true);
   };

   // std::unordered_map with generic value type
   "std_unordered_map_generic_i64"_test = [] {
      std::unordered_map<std::string, glz::generic_i64> m;
      std::string toml = R"(id = 12345
label = "item"
weight = 2.5)";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 3);
      expect(std::get<int64_t>(m["id"].data) == 12345);
      expect(std::get<std::string>(m["label"].data) == "item");
      expect(std::abs(std::get<double>(m["weight"].data) - 2.5) < 0.001);
   };

   // Deep nesting with std::map<std::string, glz::generic_i64>
   "std_map_generic_i64_deep_nesting"_test = [] {
      std::map<std::string, glz::generic_i64> m;
      std::string toml = R"(a.b.c.d = 42
a.b.c.e = "deep"
a.b.f = true)";
      auto ec = glz::read_toml(m, toml);
      expect(not ec) << glz::format_error(ec, toml);
      expect(m.size() == 1); // only "a" at top level

      auto& a = std::get<glz::generic_i64::object_t>(m["a"].data);
      auto& b = std::get<glz::generic_i64::object_t>(a.at("b").data);
      auto& c = std::get<glz::generic_i64::object_t>(b.at("c").data);
      expect(std::get<int64_t>(c.at("d").data) == 42);
      expect(std::get<std::string>(c.at("e").data) == "deep");
      expect(std::get<bool>(b.at("f").data) == true);
   };
};

suite toml_1_1_delta_tests = [] {
   "toml_1_1_inline_table_allows_newlines_and_trailing_comma_object"_test = [] {
      const std::string input = R"(name = "Test Person"
inline_data = {
  key1 = "value1",
  key2 = 100,
})";

      struct_with_inline_table s{};
      const auto error = glz::read_toml(s, input);
      expect(not error) << glz::format_error(error, input);
      expect(s.name == "Test Person");
      expect(s.inline_data.key1 == "value1");
      expect(s.inline_data.key2 == 100);
   };

   "toml_1_1_inline_table_allows_newlines_and_trailing_comma_map"_test = [] {
      const std::string input = R"({
  a = 1,
  b = 2,
})";

      std::map<std::string, int> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.size() == 2);
      expect(value["a"] == 1);
      expect(value["b"] == 2);
   };

   "toml_1_1_basic_string_hex_escape_xHH"_test = [] {
      const std::string input = R"("\x48\x69")";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value == "Hi");
   };

   "toml_1_1_basic_string_escape_e"_test = [] {
      const std::string input = R"("a\eZ")";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);

      std::string expected = "a";
      expected.push_back('\x1B');
      expected.push_back('Z');
      expect(value == expected);
   };

   "toml_1_1_struct_value_unicode_escape_u"_test = [] {
      const std::string input = R"(name = "\u0041")";
      unicode_name_struct value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.name == "A");
   };

   "toml_1_1_struct_quoted_key_unicode_escape_u"_test = [] {
      const std::string input = R"("\u0061" = 7)";
      unicode_key_struct value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.a == 7);
   };

   "toml_1_1_struct_float_value_inf_nan"_test = [] {
      {
         const std::string input = "value = inf";
         float_special_struct value{};
         const auto error = glz::read_toml(value, input);
         expect(not error) << glz::format_error(error, input);
         expect(std::isinf(value.value));
         expect(value.value > 0.0);
      }

      {
         const std::string input = "value = -inf";
         float_special_struct value{};
         const auto error = glz::read_toml(value, input);
         expect(not error) << glz::format_error(error, input);
         expect(std::isinf(value.value));
         expect(value.value < 0.0);
      }

      {
         const std::string input = "value = +inf";
         float_special_struct value{};
         const auto error = glz::read_toml(value, input);
         expect(not error) << glz::format_error(error, input);
         expect(std::isinf(value.value));
         expect(value.value > 0.0);
      }

      {
         const std::string input = "value = nan";
         float_special_struct value{};
         const auto error = glz::read_toml(value, input);
         expect(not error) << glz::format_error(error, input);
         expect(std::isnan(value.value));
      }

      {
         const std::string input = "value = +nan";
         float_special_struct value{};
         const auto error = glz::read_toml(value, input);
         expect(not error) << glz::format_error(error, input);
         expect(std::isnan(value.value));
      }
   };

   "toml_1_1_struct_float_array_inf_nan"_test = [] {
      const std::string input = "values = [inf, nan, -inf]";
      float_special_struct value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.values.size() == 3);
      expect(std::isinf(value.values[0]));
      expect(value.values[0] > 0.0);
      expect(std::isnan(value.values[1]));
      expect(std::isinf(value.values[2]));
      expect(value.values[2] < 0.0);
   };

   "toml_struct_array_trailing_comma_parses"_test = [] {
      const std::string input = "values = [1, 2,]";
      int_array_struct value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.values.size() == 2);
      expect(value.values[0] == 1);
      expect(value.values[1] == 2);
   };

   "toml_struct_array_missing_close_after_comma_errors"_test = [] {
      const std::string input = "values = [1, 2,";
      int_array_struct value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_basic_string_hex_escape_xHH_invalid_short"_test = [] {
      const std::string input = R"("\x4")";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_basic_string_hex_escape_xHH_invalid_digits"_test = [] {
      const std::string input = R"("\xGG")";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_multiline_basic_string_hex_escape_xHH"_test = [] {
      const std::string input = "\"\"\"prefix\\x41suffix\"\"\"";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value == "prefixAsuffix");
   };

   "toml_1_1_multiline_basic_string_escape_e"_test = [] {
      const std::string input = "\"\"\"A\\eB\"\"\"";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);

      std::string expected = "A";
      expected.push_back('\x1B');
      expected.push_back('B');
      expect(value == expected);
   };

   "toml_1_1_single_quoted_key_basic"_test = [] {
      const std::string input = R"('first name' = "Nick")";
      std::map<std::string, std::string> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.size() == 1);
      expect(value["first name"] == "Nick");
   };

   "toml_1_1_single_quoted_dotted_keys"_test = [] {
      const std::string input = R"('fruit'.'apple tree'.color = "red")";
      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      if (error) return;

      auto& fruit_obj = std::get<glz::generic_i64::object_t>(value.at("fruit").data);
      auto& apple_obj = std::get<glz::generic_i64::object_t>(fruit_obj.at("apple tree").data);
      expect(std::get<std::string>(apple_obj.at("color").data) == "red");
   };

   "toml_1_1_single_quoted_table_header"_test = [] {
      const std::string input = R"(['fruit section']
color = "red"
)";
      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      if (error) return;

      auto& fruit_obj = std::get<glz::generic_i64::object_t>(value.at("fruit section").data);
      expect(std::get<std::string>(fruit_obj.at("color").data) == "red");
   };

   "toml_1_1_single_quoted_array_of_tables_header"_test = [] {
      const std::string input = R"([['products_list']]
name = "Hammer"
sku = 1

[['products_list']]
name = "Nail"
sku = 2
)";

      quoted_header_catalog c{};
      const auto error = glz::read_toml(c, input);
      expect(not error) << glz::format_error(error, input);
      expect(c.products_list.size() == 2);
      expect(c.products_list[0].name == "Hammer");
      expect(c.products_list[0].sku == 1);
      expect(c.products_list[1].name == "Nail");
      expect(c.products_list[1].sku == 2);
   };

   "toml_1_1_inline_table_comments_object"_test = [] {
      const std::string input = R"(name = "Test Person"
inline_data = {
  key1 = "value1", # comment after first entry
  # comment-only line in inline table
  key2 = 100, # comment after second entry
  # comment before close
})";

      struct_with_inline_table s{};
      const auto error = glz::read_toml(s, input);
      expect(not error) << glz::format_error(error, input);
      expect(s.inline_data.key1 == "value1");
      expect(s.inline_data.key2 == 100);
   };

   "toml_1_1_inline_table_comments_map"_test = [] {
      const std::string input = R"({
  a = 1, # comment after first entry
  # comment-only line in inline table
  b = 2, # comment after second entry
  # comment before close
})";

      std::map<std::string, int> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value.size() == 2);
      expect(value.at("a") == 1);
      expect(value.at("b") == 2);
   };

   "toml_1_1_conflict_scalar_then_dotted_key_error"_test = [] {
      const std::string input = R"(fruit.apple = 1
fruit.apple.sweet = true
)";

      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_conflict_dotted_key_then_scalar_error"_test = [] {
      const std::string input = R"(fruit.apple.sweet = true
fruit.apple = 1
)";

      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_conflict_scalar_then_table_header_error"_test = [] {
      const std::string input = R"(fruit.apple = 1
[fruit.apple]
color = "red"
)";

      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(error);
   };

   "toml_1_1_comments_do_not_affect_tables"_test = [] {
      const std::string input = R"(# A full-line comment before any table
[[products]]
name = "Hammer"
sku = 1 # end-of-line comment

# Another comment between array entries
[[products]]
name = "Nail"
sku = 2
)";

      simple_catalog c{};
      const auto error = glz::read_toml(c, input);
      expect(not error) << glz::format_error(error, input);
      expect(c.products.size() == 2);
      expect(c.products[0].name == "Hammer");
      expect(c.products[0].sku == 1);
      expect(c.products[1].name == "Nail");
      expect(c.products[1].sku == 2);
   };

   "toml_1_1_dotted_keys_and_table_definitions"_test = [] {
      const std::string input = R"([fruit]
apple.color = "red"
apple.taste.sweet = true
)";

      std::map<std::string, glz::generic_i64> value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);

      auto& fruit_obj = std::get<glz::generic_i64::object_t>(value.at("fruit").data);
      auto& apple_obj = std::get<glz::generic_i64::object_t>(fruit_obj.at("apple").data);
      auto& taste_obj = std::get<glz::generic_i64::object_t>(apple_obj.at("taste").data);

      expect(std::get<std::string>(apple_obj.at("color").data) == "red");
      expect(std::get<bool>(taste_obj.at("sweet").data) == true);
   };

   "toml_1_1_local_datetime_seconds_optional"_test = [] {
      using namespace std::chrono;
      const std::string input = "2024-06-15T10:30";
      system_clock::time_point tp{};
      const auto error = glz::read_toml(tp, input);
      expect(not error) << glz::format_error(error, input);

      const auto expected = sys_days{year{2024} / month{6} / day{15}} + hours{10} + minutes{30};
      expect(time_point_cast<seconds>(tp) == time_point_cast<seconds>(expected));
   };

   "toml_1_1_multiline_literal_strings_keep_line_endings"_test = [] {
      const std::string input = "'''first\r\nsecond'''";
      std::string value{};
      const auto error = glz::read_toml(value, input);
      expect(not error) << glz::format_error(error, input);
      expect(value == "first\r\nsecond");
   };

   "toml_1_1_sub_millisecond_precision_local_time"_test = [] {
      using namespace std::chrono;
      const std::string input = "10:30:45.123456789";
      hh_mm_ss<nanoseconds> tod{nanoseconds{0}};
      const auto error = glz::read_toml(tod, input);
      expect(not error) << glz::format_error(error, input);
      expect(tod.hours().count() == 10);
      expect(tod.minutes().count() == 30);
      expect(tod.seconds().count() == 45);
      expect(tod.subseconds().count() == 123456789);
   };

   "toml_1_1_numeric_size_support_is_implementation_defined"_test = [] {
      std::int64_t i{};
      const auto int_error = glz::read_toml(i, "9223372036854775807");
      expect(not int_error);
      expect(i == std::numeric_limits<std::int64_t>::max());

      double d{};
      const auto float_error = glz::read_toml(d, "3.141592653589793");
      expect(not float_error);
      expect(std::abs(d - 3.141592653589793) < 1e-15);
   };
};

int main() { return 0; }
