Skip to content

Commit e7d8137

Browse files
committed
Add compile-time option to enable table order preservation
1 parent 3017243 commit e7d8137

File tree

9 files changed

+639
-14
lines changed

9 files changed

+639
-14
lines changed

include/toml++/impl/key.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,4 +332,10 @@ TOML_NAMESPACE_START
332332
}
333333
TOML_NAMESPACE_END;
334334

335+
template<> struct std::hash<toml::key> {
336+
std::size_t operator()(toml::key const& k) const noexcept {
337+
return std::hash<std::string_view>{}(k.str());
338+
}
339+
};
340+
335341
#include "header_end.hpp"

include/toml++/impl/parser.inl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3186,10 +3186,18 @@ TOML_IMPL_NAMESPACE_START
31863186
for (size_t i = 0, e = key_buffer.size() - 1u; i < e; i++)
31873187
{
31883188
const std::string_view segment = key_buffer[i];
3189+
#if TOML_ENABLE_ORDERED_TABLES
3190+
auto pit = parent->find(segment);
3191+
#else
31893192
auto pit = parent->lower_bound(segment);
3193+
#endif
31903194

31913195
// parent already existed
3196+
#if TOML_ENABLE_ORDERED_TABLES
3197+
if (pit != parent->end())
3198+
#else
31923199
if (pit != parent->end() && pit->first == segment)
3200+
#endif
31933201
{
31943202
node& p = pit->second;
31953203

@@ -3240,13 +3248,21 @@ TOML_IMPL_NAMESPACE_START
32403248
}
32413249

32423250
const auto last_segment = key_buffer.back();
3251+
#if TOML_ENABLE_ORDERED_TABLES
3252+
auto it = parent->find(last_segment);
3253+
#else
32433254
auto it = parent->lower_bound(last_segment);
3255+
#endif
32443256

32453257
// if there was already a matching node some sanity checking is necessary;
32463258
// this is ok if we're making an array and the existing element is already an array (new element)
32473259
// or if we're making a table and the existing element is an implicitly-created table (promote it),
32483260
// otherwise this is a redefinition error.
3261+
#if TOML_ENABLE_ORDERED_TABLES
3262+
if (it != parent->end())
3263+
#else
32493264
if (it != parent->end() && it->first == last_segment)
3265+
#endif
32503266
{
32513267
node& matching_node = it->second;
32523268
if (auto arr = matching_node.as_array();
@@ -3376,10 +3392,18 @@ TOML_IMPL_NAMESPACE_START
33763392
for (size_t i = 0; i < key_buffer.size() - 1u; i++)
33773393
{
33783394
const std::string_view segment = key_buffer[i];
3395+
#if TOML_ENABLE_ORDERED_TABLES
3396+
auto pit = tbl->find(segment);
3397+
#else
33793398
auto pit = tbl->lower_bound(segment);
3399+
#endif
33803400

33813401
// parent already existed
3402+
#if TOML_ENABLE_ORDERED_TABLES
3403+
if (pit != tbl->end())
3404+
#else
33823405
if (pit != tbl->end() && pit->first == segment)
3406+
#endif
33833407
{
33843408
table* p = pit->second.as_table();
33853409

@@ -3413,8 +3437,13 @@ TOML_IMPL_NAMESPACE_START
34133437

34143438
// ensure this isn't a redefinition
34153439
const std::string_view last_segment = key_buffer.back();
3440+
#if TOML_ENABLE_ORDERED_TABLES
3441+
auto it = tbl->find(last_segment);
3442+
if (it != tbl->end())
3443+
#else
34163444
auto it = tbl->lower_bound(last_segment);
34173445
if (it != tbl->end() && it->first == last_segment)
3446+
#endif
34183447
{
34193448
set_error("cannot redefine existing "sv,
34203449
to_sv(it->second.type()),

include/toml++/impl/preprocessor.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,42 @@ TOML_ENABLE_WARNINGS;
12111211
/// \detail Defaults to `0`.
12121212
//# }}
12131213

1214+
#ifndef TOML_ENABLE_ORDERED_TABLES
1215+
#define TOML_ENABLE_ORDERED_TABLES 0
1216+
#endif
1217+
//# {{
1218+
/// \def TOML_ENABLE_ORDERED_TABLES
1219+
/// \brief Make tables retain insertion order instead of lexicographic order.
1220+
/// \detail Defaults to `0`.
1221+
//# }}
1222+
1223+
#ifndef TOML_DISABLE_CONDITIONAL_NOEXCEPT_LAMBDA
1224+
#define TOML_DISABLE_CONDITIONAL_NOEXCEPT_LAMBDA 0
1225+
#endif
1226+
//# {{
1227+
/// \def TOML_DISABLE_CONDITIONAL_NOEXCEPT_LAMBDA
1228+
/// \brief Disable using noexcept(<condition>) in lambda definitions within the toml++ library implementation.
1229+
/// \detail This macro offers a workaround to a bug in the old "legacy lambda processor" of Visual C++, which
1230+
/// caused compile errors like "error C2057: expected constant expression", when it encountered such lambda's.
1231+
/// These compile errors were reported by Kevin Dick, Jan 19, 2024, at https://github.com/marzer/tomlplusplus/issues/219
1232+
//# }}
1233+
1234+
#ifndef TOML_DISABLE_NOEXCEPT_NOEXCEPT
1235+
#define TOML_DISABLE_NOEXCEPT_NOEXCEPT 0
1236+
#ifdef _MSC_VER
1237+
#if _MSC_VER <= 1943 // Up to Visual Studio 2022 Version 17.13.6
1238+
#undef TOML_DISABLE_NOEXCEPT_NOEXCEPT
1239+
#define TOML_DISABLE_NOEXCEPT_NOEXCEPT 1
1240+
#endif
1241+
#endif
1242+
#endif
1243+
//# {{
1244+
/// \def TOML_DISABLE_NOEXCEPT_NOEXCEPT
1245+
/// \brief Disable using noexcept(noexcept(<expression>)) within the toml++ library implementation.
1246+
/// \detail This macro offers a workaround to a bug in Visual C++ (Visual Studio 2022), which caused
1247+
/// compile errors, saying: "error C3878: syntax error: unexpected token ',' following 'simple-type-specifier'"
1248+
//# }}
1249+
12141250
/// @}
12151251
//#====================================================================================================================
12161252
//# CHARCONV SUPPORT

include/toml++/impl/std_list.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
2+
//# Copyright (c) Mark Gillard <[email protected]>
3+
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
4+
// SPDX-License-Identifier: MIT
5+
#pragma once
6+
7+
#include "preprocessor.hpp"
8+
TOML_DISABLE_WARNINGS;
9+
#include <list>
10+
TOML_ENABLE_WARNINGS;

0 commit comments

Comments
 (0)