@@ -75,49 +75,37 @@ struct PostProcessConvertedAttribute
7575 virtual ~PostProcessConvertedAttribute () = default ;
7676};
7777
78- struct constructor_tag
79- {};
80- static constexpr constructor_tag constructor_tag_v = {};
81-
82- template <typename T, typename Functor>
78+ /*
79+ * Defer validation to a function pointer of type handler_t.
80+ */
81+ template <typename T, typename RecordType>
8382struct PostProcessConvertedAttributeImpl : PostProcessConvertedAttribute<T>
8483{
85- template < typename T_, typename Functor_>
86- friend auto makePostProcessConvertedAttribute (Functor_ &&fun)
87- -> std::shared_ptr<PostProcessConvertedAttribute<T_>> ;
84+ RecordType record;
85+ using handler_t = std::optional<error::ReadError> (*)(RecordType &, T);
86+ handler_t reader ;
8887
89- template <typename Fun>
90- PostProcessConvertedAttributeImpl (constructor_tag, Fun &&f)
91- : fun{std::forward<Fun>(f)}
88+ PostProcessConvertedAttributeImpl (RecordType record_in, handler_t reader_in)
89+ : record(std::move(record_in)), reader(reader_in)
9290 {}
9391
94- Functor fun;
9592 auto operator ()(T val) -> std::optional<error::ReadError> override
9693 {
97- return fun ( std::move (val));
94+ return (*reader)(record, std::move (val));
9895 }
9996};
10097
101- // 4, 0.152344
102- template <typename T, typename Fun>
103- auto makePostProcessConvertedAttribute (Fun &&fun)
98+ template <typename T, typename RecordType>
99+ auto makePostProcessConvertedAttribute (
100+ RecordType &&record,
101+ std::optional<error::ReadError> (*handler)(
102+ std::remove_reference_t <RecordType> &, T))
104103 -> std::shared_ptr<PostProcessConvertedAttribute<T>>
105104{
106- auto functor = [fun_lambda = std::forward<Fun>(fun)](
107- T val) -> std::optional<error::ReadError> {
108- if constexpr (!std::is_void_v<std::invoke_result<Fun &&, T>>)
109- {
110- std::move (fun_lambda)(std::move (val));
111- return std::nullopt ;
112- }
113- else
114- {
115- return std::move (fun_lambda)(std::move (val));
116- }
117- };
118- return std::make_shared<
119- PostProcessConvertedAttributeImpl<T, decltype (functor)>>(
120- constructor_tag_v, std::move (functor));
105+ return std::make_shared<PostProcessConvertedAttributeImpl<
106+ T,
107+ std::remove_reference_t <RecordType>>>(
108+ std::forward<RecordType>(record), handler);
121109}
122110
123111/*
@@ -132,10 +120,13 @@ struct RequireType : ProcessAttribute
132120
133121 explicit RequireType () = default;
134122
135- template <typename Functor>
136- RequireType (constructor_tag, Functor &&fun)
137- : postProcess(
138- makePostProcessConvertedAttribute<T>(std::forward<Functor>(fun)))
123+ template <typename RecordType>
124+ RequireType (
125+ RecordType &&record,
126+ std::optional<error::ReadError> (*handler)(
127+ std::remove_reference_t <RecordType> &, T))
128+ : postProcess(makePostProcessConvertedAttribute(
129+ std::forward<RecordType>(record), handler))
139130 {}
140131
141132 auto operator ()(Attributable &, char const *, Attribute const &)
@@ -251,8 +242,11 @@ namespace
251242 extern std::shared_ptr<ProcessAttribute> require_scalar;
252243 // try converting to vectors (e.g. when a scalar or an array is given)
253244 extern std::shared_ptr<ProcessAttribute> require_vector;
254- template <typename T, typename Fun>
255- auto require_type (Fun &&) -> std::shared_ptr<ProcessAttribute>;
245+ template <typename T, typename RecordType>
246+ auto require_type (
247+ std::optional<error::ReadError> (*)(
248+ std::remove_reference_t <RecordType> &, T))
249+ -> std::shared_ptr<ProcessAttribute>;
256250 // common case: directly use setAttribute
257251 template <typename T>
258252 auto require_type () -> std::shared_ptr<ProcessAttribute>;
0 commit comments