Skip to content

Commit a344de0

Browse files
Separated out Parser_basic_type
1 parent 8914fb9 commit a344de0

4 files changed

Lines changed: 113 additions & 51 deletions

File tree

include/rfl/internal/is_basic_type.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
#include <string>
55
#include <type_traits>
66

7-
namespace rfl {
8-
namespace internal {
7+
namespace rfl::internal {
98

109
template <class T>
1110
constexpr bool is_basic_type_v =
@@ -14,7 +13,6 @@ constexpr bool is_basic_type_v =
1413
std::is_same<std::remove_cvref_t<T>, std::string>() ||
1514
std::is_same<std::remove_cvref_t<T>, bool>();
1615

17-
} // namespace internal
18-
} // namespace rfl
16+
} // namespace rfl::internal
1917

2018
#endif

include/rfl/parsing/Parser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "Parser_array.hpp"
55
#include "Parser_base.hpp"
6+
#include "Parser_basic_type.hpp"
67
#include "Parser_box.hpp"
78
#include "Parser_bytestring.hpp"
89
#include "Parser_c_array.hpp"
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#ifndef RFL_PARSING_PARSER_BASIC_TYPE_HPP_
2+
#define RFL_PARSING_PARSER_BASIC_TYPE_HPP_
3+
4+
#include <map>
5+
#include <type_traits>
6+
7+
#include "../Result.hpp"
8+
#include "../always_false.hpp"
9+
#include "../enums.hpp"
10+
#include "../from_named_tuple.hpp"
11+
#include "../internal/has_default_val_v.hpp"
12+
#include "../internal/has_reflection_method_v.hpp"
13+
#include "../internal/has_reflection_type_v.hpp"
14+
#include "../internal/has_reflector.hpp"
15+
#include "../internal/is_basic_type.hpp"
16+
#include "../internal/is_description.hpp"
17+
#include "../internal/is_literal.hpp"
18+
#include "../internal/is_underlying_enums_v.hpp"
19+
#include "../internal/is_validator.hpp"
20+
#include "../internal/processed_t.hpp"
21+
#include "../internal/ptr_cast.hpp"
22+
#include "../internal/to_ptr_named_tuple.hpp"
23+
#include "../thirdparty/enchantum/enchantum.hpp"
24+
#include "../to_view.hpp"
25+
#include "AreReaderAndWriter.hpp"
26+
#include "Parent.hpp"
27+
#include "Parser_base.hpp"
28+
#include "call_destructors_where_necessary.hpp"
29+
#include "is_tagged_union_wrapper.hpp"
30+
#include "make_type_name.hpp"
31+
#include "schema/Type.hpp"
32+
#include "schemaful/IsSchemafulReader.hpp"
33+
#include "schemaful/IsSchemafulWriter.hpp"
34+
35+
namespace rfl::parsing {
36+
37+
/// Default case - anything that cannot be explicitly matched.
38+
template <class R, class W, class T, class ProcessorsType>
39+
requires internal::is_basic_type_v<T> && AreReaderAndWriter<R, W, T>
40+
struct Parser<R, W, T, ProcessorsType> {
41+
public:
42+
using InputVarType = typename R::InputVarType;
43+
44+
using ParentType = Parent<W>;
45+
46+
/// Expresses the variables as type T.
47+
static Result<T> read(const R& _r, const InputVarType& _var) noexcept {
48+
return _r.template to_basic_type<std::remove_cvref_t<T>>(_var);
49+
}
50+
51+
template <class P>
52+
static void write(const W& _w, const T& _var, const P& _parent) {
53+
ParentType::add_value(_w, _var, _parent);
54+
}
55+
56+
/// Generates a schema for the underlying type.
57+
static schema::Type to_schema(
58+
std::map<std::string, schema::Type>* _definitions) {
59+
using U = std::remove_cvref_t<T>;
60+
using Type = schema::Type;
61+
if constexpr (std::is_same<U, bool>()) {
62+
return Type{Type::Boolean{}};
63+
64+
} else if constexpr (std::is_same<U, std::int32_t>()) {
65+
return Type{Type::Int32{}};
66+
67+
} else if constexpr (std::is_same<U, std::int64_t>()) {
68+
return Type{Type::Int64{}};
69+
70+
} else if constexpr (std::is_same<U, std::uint32_t>()) {
71+
return Type{Type::UInt32{}};
72+
73+
} else if constexpr (std::is_same<U, std::uint64_t>()) {
74+
return Type{Type::UInt64{}};
75+
76+
} else if constexpr (std::is_integral<U>()) {
77+
return Type{Type::Integer{}};
78+
79+
} else if constexpr (std::is_same<U, float>()) {
80+
return Type{Type::Float{}};
81+
82+
} else if constexpr (std::is_floating_point_v<U>) {
83+
return Type{Type::Double{}};
84+
85+
} else if constexpr (std::is_same<U, std::string>()) {
86+
return Type{Type::String{}};
87+
88+
} else {
89+
static_assert(rfl::always_false_v<U>, "Unsupported type.");
90+
}
91+
}
92+
};
93+
94+
} // namespace rfl::parsing
95+
96+
#endif

include/rfl/parsing/Parser_default.hpp

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,12 @@ struct Parser {
7979
return Parser<R, W, ReflectionType, ProcessorsType>::read(_r, _var)
8080
.and_then(wrap_in_t);
8181

82-
} else if constexpr (std::is_class_v<T> && std::is_aggregate_v<T>) {
83-
if constexpr (ProcessorsType::default_if_missing_ ||
84-
internal::has_default_val_v<T>) {
85-
return read_struct_with_default(_r, _var);
86-
} else {
87-
return read_struct(_r, _var);
88-
}
82+
} else if constexpr (ProcessorsType::default_if_missing_ ||
83+
internal::has_default_val_v<T>) {
84+
return read_struct_with_default(_r, _var);
8985

9086
} else {
91-
return _r.template to_basic_type<std::remove_cvref_t<T>>(_var);
87+
return read_struct(_r, _var);
9288
}
9389
}
9490
}
@@ -113,15 +109,12 @@ struct Parser {
113109
Parser<R, W, ReflectionType, ProcessorsType>::write(_w, r, _parent);
114110
}
115111

116-
} else if constexpr (std::is_class_v<T> && std::is_aggregate_v<T>) {
112+
} else {
117113
const auto ptr_named_tuple = ProcessorsType::template process<T>(
118114
internal::to_ptr_named_tuple(_var));
119115
using PtrNamedTupleType = std::remove_cvref_t<decltype(ptr_named_tuple)>;
120116
Parser<R, W, PtrNamedTupleType, ProcessorsType>::write(
121117
_w, ptr_named_tuple, _parent);
122-
123-
} else {
124-
ParentType::add_value(_w, _var, _parent);
125118
}
126119
}
127120

@@ -130,34 +123,8 @@ struct Parser {
130123
std::map<std::string, schema::Type>* _definitions) {
131124
using U = std::remove_cvref_t<T>;
132125
using Type = schema::Type;
133-
if constexpr (std::is_same<U, bool>()) {
134-
return Type{Type::Boolean{}};
135-
136-
} else if constexpr (std::is_same<U, std::int32_t>()) {
137-
return Type{Type::Int32{}};
138-
139-
} else if constexpr (std::is_same<U, std::int64_t>()) {
140-
return Type{Type::Int64{}};
141-
142-
} else if constexpr (std::is_same<U, std::uint32_t>()) {
143-
return Type{Type::UInt32{}};
144-
145-
} else if constexpr (std::is_same<U, std::uint64_t>()) {
146-
return Type{Type::UInt64{}};
147-
148-
} else if constexpr (std::is_integral<U>()) {
149-
return Type{Type::Integer{}};
150-
151-
} else if constexpr (std::is_same<U, float>()) {
152-
return Type{Type::Float{}};
153-
154-
} else if constexpr (std::is_floating_point_v<U>) {
155-
return Type{Type::Double{}};
156-
157-
} else if constexpr (std::is_same<U, std::string>()) {
158-
return Type{Type::String{}};
159126

160-
} else if constexpr (rfl::internal::is_description_v<U>) {
127+
if constexpr (rfl::internal::is_description_v<U>) {
161128
return make_description<U>(_definitions);
162129

163130
} else if constexpr (std::is_class_v<U> && std::is_aggregate_v<U>) {
@@ -234,10 +201,10 @@ struct Parser {
234201
.validation_ = ValidationType::template to_schema<ReflectionType>()}};
235202
}
236203

237-
/// The way this works is that we allocate space on the stack in this size of
238-
/// the struct in which we then write the individual fields using
239-
/// views and placement new. This is how we deal with the fact that some
240-
/// fields might not be default-constructible.
204+
/// The way this works is that we allocate space on the stack in this size
205+
/// of the struct in which we then write the individual fields using views
206+
/// and placement new. This is how we deal with the fact that some fields
207+
/// might not be default-constructible.
241208
static Result<T> read_struct(const R& _r, const InputVarType& _var) {
242209
alignas(T) unsigned char buf[sizeof(T)]{};
243210
auto ptr = internal::ptr_cast<T*>(&buf);
@@ -254,10 +221,10 @@ struct Parser {
254221
return res;
255222
}
256223

257-
/// This is actually more straight-forward than the standard case - we just
258-
/// allocate a struct and then fill it. But it is less efficient and it
259-
/// assumes that all values on the struct have a default constructor, so we
260-
/// only use it when the DefaultIfMissing preprocessor is added.
224+
/// This is actually more straight-forward than the standard case - we
225+
/// just allocate a struct and then fill it. But it is less efficient and
226+
/// it assumes that all values on the struct have a default constructor,
227+
/// so we only use it when the DefaultIfMissing preprocessor is added.
261228
static Result<T> read_struct_with_default(const R& _r,
262229
const InputVarType& _var) {
263230
auto t = T{};

0 commit comments

Comments
 (0)