Skip to content

Commit 794fb0b

Browse files
committed
Implement basic trivia preservation mode (whitespace+comments so far)
1 parent e7d8137 commit 794fb0b

20 files changed

+1141
-257
lines changed

include/toml++/impl/array.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "std_utility.hpp"
88
#include "std_vector.hpp"
99
#include "std_initializer_list.hpp"
10+
#include "preprocessor.hpp"
11+
#include "trivia_piece.hpp"
1012
#include "value.hpp"
1113
#include "make_node.hpp"
1214
#include "header_start.hpp"
@@ -290,6 +292,7 @@ TOML_NAMESPACE_START
290292
using vector_iterator = typename vector_type::iterator;
291293
using const_vector_iterator = typename vector_type::const_iterator;
292294
vector_type elems_;
295+
optional<std::vector<trivia_piece>> inner_trailing_trivia_;
293296

294297
TOML_NODISCARD_CTOR
295298
TOML_EXPORTED_MEMBER_FUNCTION
@@ -404,6 +407,20 @@ TOML_NAMESPACE_START
404407
TOML_EXPORTED_MEMBER_FUNCTION
405408
array& operator=(array&& rhs) noexcept;
406409

410+
/// \brief Gets the inner trailing trivia.
411+
TOML_CONST_INLINE_GETTER
412+
const optional<std::vector<trivia_piece>> inner_trailing_trivia() const noexcept
413+
{
414+
return inner_trailing_trivia_;
415+
}
416+
417+
/// \brief Sets the inner trailing trivia.
418+
TOML_EXPORTED_MEMBER_FUNCTION
419+
void set_inner_trailing_trivia(optional<std::vector<trivia_piece>> trivia) noexcept
420+
{
421+
inner_trailing_trivia_ = trivia;
422+
}
423+
407424
/// \name Type checks
408425
/// @{
409426

include/toml++/impl/array.inl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ TOML_NAMESPACE_START
6565

6666
TOML_EXTERNAL_LINKAGE
6767
array::array(const array& other) //
68-
: node(other)
68+
: node(other),
69+
inner_trailing_trivia_(other.inner_trailing_trivia_)
6970
{
7071
elems_.reserve(other.elems_.size());
7172
for (const auto& elem : other)
@@ -79,7 +80,8 @@ TOML_NAMESPACE_START
7980
TOML_EXTERNAL_LINKAGE
8081
array::array(array && other) noexcept //
8182
: node(std::move(other)),
82-
elems_(std::move(other.elems_))
83+
elems_(std::move(other.elems_)),
84+
inner_trailing_trivia_(other.inner_trailing_trivia_)
8385
{
8486
#if TOML_LIFETIME_HOOKS
8587
TOML_ARRAY_CREATED;
@@ -96,6 +98,7 @@ TOML_NAMESPACE_START
9698
elems_.reserve(rhs.elems_.size());
9799
for (const auto& elem : rhs)
98100
elems_.emplace_back(impl::make_node(elem));
101+
inner_trailing_trivia_ = rhs.inner_trailing_trivia_;
99102
}
100103
return *this;
101104
}
@@ -107,6 +110,7 @@ TOML_NAMESPACE_START
107110
{
108111
node::operator=(std::move(rhs));
109112
elems_ = std::move(rhs.elems_);
113+
inner_trailing_trivia_ = rhs.inner_trailing_trivia_;
110114
}
111115
return *this;
112116
}

include/toml++/impl/date_time.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "forward_declarations.hpp"
88
#include "print_to_stream.hpp"
99
#include "header_start.hpp"
10+
#include "std_optional.hpp"
1011

1112
TOML_NAMESPACE_START
1213
{

include/toml++/impl/formatter.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ TOML_IMPL_NAMESPACE_START
130130
return !!(config_.flags & format_flags::terse_key_value_pairs);
131131
}
132132

133+
TOML_PURE_INLINE_GETTER
134+
bool preserve_source_trivia() const noexcept
135+
{
136+
return !!(config_.flags & format_flags::preserve_source_trivia);
137+
}
138+
133139
TOML_EXPORTED_MEMBER_FUNCTION
134140
void attach(std::ostream& stream) noexcept;
135141

include/toml++/impl/forward_declarations.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ TOML_NAMESPACE_START // abi namespace
343343

344344
/// \brief Avoids the use of whitespace around key-value pairs.
345345
terse_key_value_pairs = (1ull << 12),
346+
347+
/// \brief Preserves trivia of nodes that have it (i.e. were passed with collect_trivia enabled).
348+
preserve_source_trivia = (1ull << 13)
346349
};
347350
TOML_MAKE_FLAGS(format_flags);
348351

include/toml++/impl/key.hpp

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// SPDX-License-Identifier: MIT
55
#pragma once
66

7+
#include "std_vector.hpp"
8+
#include "trivia_piece.hpp"
79
#include "source_region.hpp"
810
#include "std_utility.hpp"
911
#include "print_to_stream.hpp"
@@ -33,6 +35,8 @@ TOML_NAMESPACE_START
3335
private:
3436
std::string key_;
3537
source_region source_;
38+
std::optional<std::vector<trivia_piece>> leading_trivia_;
39+
std::optional<std::vector<trivia_piece>> trailing_trivia_;
3640

3741
public:
3842
/// \brief Default constructor.
@@ -41,44 +45,74 @@ TOML_NAMESPACE_START
4145

4246
/// \brief Constructs a key from a string view and source region.
4347
TOML_NODISCARD_CTOR
44-
explicit key(std::string_view k, source_region&& src = {}) //
48+
explicit key(std::string_view k,
49+
source_region&& src = {},
50+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
51+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
4552
: key_{ k },
46-
source_{ std::move(src) }
53+
source_{ std::move(src) },
54+
leading_trivia_(leading_trivia),
55+
trailing_trivia_(trailing_trivia)
4756
{}
4857

4958
/// \brief Constructs a key from a string view and source region.
5059
TOML_NODISCARD_CTOR
51-
explicit key(std::string_view k, const source_region& src) //
60+
explicit key(std::string_view k,
61+
const source_region& src,
62+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
63+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
5264
: key_{ k },
53-
source_{ src }
65+
source_{ src },
66+
leading_trivia_(leading_trivia),
67+
trailing_trivia_(trailing_trivia)
5468
{}
5569

5670
/// \brief Constructs a key from a string and source region.
5771
TOML_NODISCARD_CTOR
58-
explicit key(std::string&& k, source_region&& src = {}) noexcept //
72+
explicit key(std::string&& k,
73+
source_region&& src = {},
74+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
75+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) noexcept //
5976
: key_{ std::move(k) },
60-
source_{ std::move(src) }
77+
source_{ std::move(src) },
78+
leading_trivia_(leading_trivia),
79+
trailing_trivia_(trailing_trivia)
6180
{}
6281

6382
/// \brief Constructs a key from a string and source region.
6483
TOML_NODISCARD_CTOR
65-
explicit key(std::string&& k, const source_region& src) noexcept //
84+
explicit key(std::string&& k,
85+
const source_region& src,
86+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
87+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) noexcept //
6688
: key_{ std::move(k) },
67-
source_{ src }
89+
source_{ src },
90+
leading_trivia_(leading_trivia),
91+
trailing_trivia_(trailing_trivia)
6892
{}
6993

7094
/// \brief Constructs a key from a c-string and source region.
7195
TOML_NODISCARD_CTOR
72-
explicit key(const char* k, source_region&& src = {}) //
96+
explicit key(const char* k,
97+
source_region&& src = {},
98+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
99+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
73100
: key_{ k },
74-
source_{ std::move(src) }
101+
source_{ std::move(src) },
102+
leading_trivia_(leading_trivia),
103+
trailing_trivia_(trailing_trivia)
75104
{}
76105

77106
/// \brief Constructs a key from a c-string view and source region.
78107
TOML_NODISCARD_CTOR
79-
explicit key(const char* k, const source_region& src) //
108+
explicit key(const char* k,
109+
const source_region& src,
110+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
111+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
80112
: key_{ k },
81-
source_{ src }
113+
source_{ src },
114+
leading_trivia_(leading_trivia),
115+
trailing_trivia_(trailing_trivia)
82116
{}
83117

84118
#if TOML_ENABLE_WINDOWS_COMPAT
@@ -87,18 +121,28 @@ TOML_NAMESPACE_START
87121
///
88122
/// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
89123
TOML_NODISCARD_CTOR
90-
explicit key(std::wstring_view k, source_region&& src = {}) //
124+
explicit key(std::wstring_view k,
125+
source_region&& src = {},
126+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
127+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
91128
: key_{ impl::narrow(k) },
92-
source_{ std::move(src) }
129+
source_{ std::move(src) },
130+
leading_trivia_(leading_trivia),
131+
trailing_trivia_(trailing_trivia)
93132
{}
94133

95134
/// \brief Constructs a key from a wide string and source region.
96135
///
97136
/// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
98137
TOML_NODISCARD_CTOR
99-
explicit key(std::wstring_view k, const source_region& src) //
138+
explicit key(std::wstring_view k,
139+
const source_region& src,
140+
optional<std::vector<trivia_piece>> leading_trivia = optional<std::vector<trivia_piece>>(),
141+
optional<std::vector<trivia_piece>> trailing_trivia = optional<std::vector<trivia_piece>>()) //
100142
: key_{ impl::narrow(k) },
101-
source_{ src }
143+
source_{ src },
144+
leading_trivia_(leading_trivia),
145+
trailing_trivia_(trailing_trivia)
102146
{}
103147

104148
#endif
@@ -155,6 +199,23 @@ TOML_NAMESPACE_START
155199

156200
/// @}
157201

202+
/// \name Metadata
203+
/// @{
204+
205+
/// \brief Returns the key's leading trivia.
206+
optional<std::vector<trivia_piece>> leading_trivia() const noexcept
207+
{
208+
return leading_trivia_;
209+
}
210+
211+
/// \brief Returns the key's trailing trivia.
212+
optional<std::vector<trivia_piece>> trailing_trivia() const noexcept
213+
{
214+
return trailing_trivia_;
215+
}
216+
217+
/// @}
218+
158219
/// \name Equality and Comparison
159220
/// \attention These operations only compare the underlying strings; source regions are ignored for the purposes of all comparison!
160221
/// @{

include/toml++/impl/node.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#pragma once
66

77
#include "std_utility.hpp"
8+
#include "std_vector.hpp"
89
#include "forward_declarations.hpp"
910
#include "source_region.hpp"
1011
#include "header_start.hpp"
12+
#include "preprocessor.hpp"
13+
#include "trivia_piece.hpp"
1114

1215
TOML_NAMESPACE_START
1316
{
@@ -22,6 +25,8 @@ TOML_NAMESPACE_START
2225

2326
friend class TOML_PARSER_TYPENAME;
2427
source_region source_{};
28+
std::optional<std::vector<trivia_piece>> leading_trivia_;
29+
std::optional<std::vector<trivia_piece>> trailing_trivia_;
2530

2631
template <typename T>
2732
TOML_NODISCARD
@@ -728,6 +733,34 @@ TOML_NAMESPACE_START
728733

729734
/// @}
730735

736+
/// \brief Returns the leading trivia attached to this node.
737+
TOML_PURE_INLINE_GETTER
738+
const optional<std::vector<trivia_piece>>& leading_trivia() const noexcept
739+
{
740+
return leading_trivia_;
741+
}
742+
743+
/// \brief Returns the trailing trivia attached to this node.
744+
TOML_PURE_INLINE_GETTER
745+
const optional<std::vector<trivia_piece>>& trailing_trivia() const noexcept
746+
{
747+
return trailing_trivia_;
748+
}
749+
750+
/// \brief Sets the leading trivia attached to this node.
751+
TOML_EXPORTED_MEMBER_FUNCTION
752+
void set_leading_trivia(optional<std::vector<trivia_piece>> leading_trivia) noexcept
753+
{
754+
leading_trivia_ = leading_trivia;
755+
}
756+
757+
/// \brief Sets the trailing trivia attached to this node.
758+
TOML_EXPORTED_MEMBER_FUNCTION
759+
void set_trailing_trivia(optional<std::vector<trivia_piece>> trailing_trivia) noexcept
760+
{
761+
trailing_trivia_ = trailing_trivia;
762+
}
763+
731764
private:
732765
/// \cond
733766

include/toml++/impl/node.inl

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,31 @@ TOML_NAMESPACE_START
2929

3030
TOML_EXTERNAL_LINKAGE
3131
node::node(node && other) noexcept //
32-
: source_{ std::exchange(other.source_, {}) }
32+
: source_{ std::exchange(other.source_, {}) },
33+
leading_trivia_(other.leading_trivia_),
34+
trailing_trivia_(other.trailing_trivia_)
3335
{}
3436

3537
TOML_EXTERNAL_LINKAGE
36-
node::node(const node& /*other*/) noexcept
38+
node::node(const node& other) noexcept
39+
: leading_trivia_(other.leading_trivia_),
40+
trailing_trivia_(other.trailing_trivia_)
3741
{
3842
// does not copy source information - this is not an error
3943
//
4044
// see https://github.com/marzer/tomlplusplus/issues/49#issuecomment-665089577
4145
}
4246

4347
TOML_EXTERNAL_LINKAGE
44-
node& node::operator=(const node& /*rhs*/) noexcept
48+
node& node::operator=(const node& rhs) noexcept
4549
{
4650
// does not copy source information - this is not an error
4751
//
4852
// see https://github.com/marzer/tomlplusplus/issues/49#issuecomment-665089577
4953

5054
source_ = {};
55+
leading_trivia_ = rhs.leading_trivia_;
56+
trailing_trivia_ = rhs.trailing_trivia_;
5157
return *this;
5258
}
5359

@@ -56,6 +62,8 @@ TOML_NAMESPACE_START
5662
{
5763
if (&rhs != this)
5864
source_ = std::exchange(rhs.source_, {});
65+
leading_trivia_ = rhs.leading_trivia_;
66+
trailing_trivia_ = rhs.trailing_trivia_;
5967
return *this;
6068
}
6169

0 commit comments

Comments
 (0)