Skip to content

Commit 6b82c10

Browse files
Started developing comments
1 parent cf3c93b commit 6b82c10

4 files changed

Lines changed: 255 additions & 0 deletions

File tree

include/rfl/Commented.hpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#ifndef RFL_COMMENTED_HPP_
2+
#define RFL_COMMENTED_HPP_
3+
4+
#include <optional>
5+
#include <string>
6+
#include <type_traits>
7+
#include <utility>
8+
9+
namespace rfl {
10+
11+
template <class T>
12+
class Commented {
13+
public:
14+
using Type = std::remove_cvref_t<T>;
15+
16+
Commented() : value_(Type()) {}
17+
18+
Commented(const Type& _value) : value_(_value) {}
19+
20+
Commented(Type&& _value) noexcept : value_(std::move(_value)) {}
21+
22+
Commented(const Type& _value, std::optional<std::string> _comment)
23+
: comment_(std::move(_comment)), value_(_value) {}
24+
25+
Commented(Type&& _value, std::optional<std::string> _comment) noexcept
26+
: comment_(std::move(_comment)), value_(std::move(_value)) {}
27+
28+
Commented(Commented&& _commented) noexcept = default;
29+
30+
Commented(const Commented& _commented) = default;
31+
32+
template <class U>
33+
Commented(const Commented<U>& _commented)
34+
: comment_(_commented.comment()), value_(_commented.get()) {}
35+
36+
template <class U>
37+
Commented(Commented<U>&& _commented) noexcept(
38+
noexcept(Type(std::move(_commented.value()))))
39+
: comment_(std::move(_commented.comment())),
40+
value_(std::move(_commented.value())) {}
41+
42+
template <class U>
43+
requires(std::is_convertible_v<U, Type>)
44+
Commented(const U& _value) : value_(_value) {}
45+
46+
template <class U>
47+
requires(std::is_convertible_v<U, Type>)
48+
Commented(U&& _value) noexcept : value_(std::forward<U>(_value)) {}
49+
50+
template <class U>
51+
requires(std::is_convertible_v<U, Type>)
52+
Commented(const Commented<U>& _commented) : value_(_commented.value()) {}
53+
54+
/// Assigns the underlying object to its default value.
55+
template <class U = Type>
56+
requires(std::is_default_constructible_v<U>)
57+
Commented(const Default&) : value_(Type()) {}
58+
59+
~Commented() = default;
60+
61+
/// Sets the comment associated with the field.
62+
void add_comment(std::string _comment) { comment_ = std::move(_comment); }
63+
64+
/// Returns the comment associated with the field, if any.
65+
const std::optional<std::string>& comment() const { return comment_; }
66+
67+
/// Returns the underlying object.
68+
Type& get() { return value_; }
69+
70+
/// Returns the underlying object.
71+
const Type& get() const { return value_; }
72+
73+
/// Returns the underlying object.
74+
Type& operator()() { return value_; }
75+
76+
/// Returns the underlying object.
77+
const Type& operator()() const { return value_; }
78+
79+
/// Assigns the underlying object.
80+
auto& operator=(const Type& _value) {
81+
value_ = _value;
82+
return *this;
83+
}
84+
85+
/// Assigns the underlying object.
86+
auto& operator=(Type&& _value) noexcept {
87+
value_ = std::move(_value);
88+
return *this;
89+
}
90+
91+
/// Assigns the underlying object.
92+
template <class U>
93+
requires std::is_convertible_v<U, Type>
94+
auto& operator=(const U& _value) {
95+
value_ = _value;
96+
return *this;
97+
}
98+
99+
/// Assigns the underlying object to its default value.
100+
template <class U = Type>
101+
requires std::is_default_constructible_v<U>
102+
auto& operator=(const Default&) {
103+
value_ = Type();
104+
return *this;
105+
}
106+
107+
/// Assigns the underlying object.
108+
Commented& operator=(const Commented& _commented) = default;
109+
110+
/// Assigns the underlying object.
111+
Commented& operator=(Commented&& _commented) = default;
112+
113+
/// Assigns the underlying object.
114+
template <class U>
115+
auto& operator=(const Commented<U>& _commented) {
116+
value_ = _commented.get();
117+
return *this;
118+
}
119+
120+
/// Assigns the underlying object.
121+
template <class U>
122+
auto& operator=(Commented<U>&& _commented) {
123+
value_ = std::forward<U>(_commented.value_);
124+
return *this;
125+
}
126+
127+
/// Assigns the underlying object.
128+
void set(const Type& _value) { value_ = _value; }
129+
130+
/// Assigns the underlying object.
131+
void set(Type&& _value) { value_ = std::move(_value); }
132+
133+
/// Returns the underlying object.
134+
Type& value() { return value_; }
135+
136+
/// Returns the underlying object.
137+
const Type& value() const { return value_; }
138+
139+
private:
140+
/// The comment associated with the field.
141+
std::optional<std::string> comment_;
142+
143+
/// The underlying value.
144+
Type value_;
145+
};
146+
147+
} // namespace rfl
148+
149+
#endif

include/rfl/parsing/Parser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Parser_box.hpp"
1010
#include "Parser_bytestring.hpp"
1111
#include "Parser_c_array.hpp"
12+
#include "Parser_commented.hpp"
1213
#include "Parser_default.hpp"
1314
#include "Parser_default_val.hpp"
1415
#include "Parser_duration.hpp"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#ifndef RFL_PARSING_PARSER_COMMENTED_HPP_
2+
#define RFL_PARSING_PARSER_COMMENTED_HPP_
3+
4+
#include <map>
5+
#include <optional>
6+
#include <type_traits>
7+
8+
#include "../Commented.hpp"
9+
#include "../Ref.hpp"
10+
#include "../Result.hpp"
11+
#include "../always_false.hpp"
12+
#include "Parent.hpp"
13+
#include "Parser_base.hpp"
14+
#include "schema/Type.hpp"
15+
#include "schemaful/IsSchemafulReader.hpp"
16+
#include "schemaful/IsSchemafulWriter.hpp"
17+
#include "schemaful/OptionalReader.hpp"
18+
#include "supports_comments.hpp"
19+
20+
namespace rfl::parsing {
21+
22+
template <class R, class W, class T, class ProcessorsType>
23+
requires AreReaderAndWriter<R, W, Commented<T>>
24+
struct Parser<R, W, Commented<T>, ProcessorsType> {
25+
using InputVarType = typename R::InputVarType;
26+
27+
using ParentType = Parent<W>;
28+
29+
static Result<Commented<T>> read(const R& _r,
30+
const InputVarType& _var) noexcept {
31+
if constexpr (supports_comments<R>) {
32+
return Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r,
33+
_var)
34+
.transform([&](auto&& _t) {
35+
return Commented<T>(std::move(_t), _r.get_comment(_var));
36+
});
37+
} else {
38+
return Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r,
39+
_var)
40+
.transform([](auto&& _t) {
41+
return Commented<T>(std::forward<decltype(_t)>(_t));
42+
});
43+
}
44+
}
45+
46+
template <class P>
47+
static void write(const W& _w, const Commented<T>& _c, const P& _parent) {
48+
if constexpr (supports_comments<W>) {
49+
if (_c.comment()) {
50+
_w.add_comment(_parent, *_c.comment());
51+
}
52+
}
53+
Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::write(_w, _c.get(),
54+
_parent);
55+
}
56+
57+
static schema::Type to_schema(
58+
std::map<std::string, schema::Type>* _definitions) {
59+
using U = std::remove_cvref_t<T>;
60+
return schema::Type{schema::Type::Optional{Ref<schema::Type>::make(
61+
Parser<R, W, U, ProcessorsType>::to_schema(_definitions))}};
62+
}
63+
};
64+
65+
} // namespace rfl::parsing
66+
67+
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef RFL_PARSING_SUPPORTSCOMMENTS_HPP_
2+
#define RFL_PARSING_SUPPORTSCOMMENTS_HPP_
3+
4+
#include <concepts>
5+
#include <optional>
6+
#include <string>
7+
#include <string_view>
8+
9+
#include "../Result.hpp"
10+
#include "IsReader.hpp"
11+
#include "IsWriter.hpp"
12+
13+
namespace rfl::parsing {
14+
15+
/// Determines whether a reader supports comments.
16+
template <class R>
17+
concept reader_supports_comments =
18+
requires(R r, typename R::InputVarType var, std::string_view comment) {
19+
{ r.get_comment(var) } -> std::same_as<std::optional<std::string>>;
20+
};
21+
22+
/// Determines whether a writer supports comments.
23+
template <class W>
24+
concept writer_supports_comments =
25+
requires(W w, Parent<W> parent, std::string_view comment) {
26+
{
27+
w.add_comment(parent, comment)
28+
} -> std::same_as<typename W::OutputVarType>;
29+
};
30+
31+
template <class RorW>
32+
concept supports_comments =
33+
(IsReader<RorW, int> && reader_supports_comments<RorW>) ||
34+
(IsWriter<RorW, int> && writer_supports_comments<RorW>);
35+
36+
} // namespace rfl::parsing
37+
38+
#endif

0 commit comments

Comments
 (0)