Skip to content

Commit dbdb781

Browse files
committed
Avoid using lambdas for require_type
1 parent 6b41972 commit dbdb781

2 files changed

Lines changed: 43 additions & 49 deletions

File tree

include/openPMD/backend/ScientificDefaults_internal.hpp

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
8382
struct 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>;

src/backend/ScientificDefaults.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ namespace
6161
}
6262

6363
// Helper function to set geometry based on string value
64-
inline void setMeshGeometryFromString(Mesh &mesh, std::string val)
64+
inline auto setMeshGeometryFromString(Mesh &mesh, std::string val)
65+
-> std::optional<error::ReadError>
6566
{
6667
if ("cartesian" == val)
6768
mesh.setGeometry(Mesh::Geometry::cartesian);
@@ -73,6 +74,7 @@ namespace
7374
mesh.setGeometry(Mesh::Geometry::spherical);
7475
else
7576
mesh.setGeometry(std::move(val));
77+
return std::nullopt;
7678
}
7779

7880
// Helper function to set data order based on char value
@@ -506,11 +508,15 @@ namespace
506508
std::shared_ptr<ProcessAttribute> require_vector =
507509
std::make_shared<RequireVector>();
508510

509-
template <typename T, typename Fun>
510-
auto require_type(Fun &&fun) -> std::shared_ptr<ProcessAttribute>
511+
template <typename T, typename RecordType>
512+
auto require_type(
513+
RecordType &&record,
514+
std::optional<error::ReadError> (*handler)(
515+
std::remove_reference_t<RecordType> &, T))
516+
-> std::shared_ptr<ProcessAttribute>
511517
{
512518
return std::make_shared<RequireType<T>>(
513-
constructor_tag_v, std::forward<Fun>(fun));
519+
std::forward<RecordType>(record), handler);
514520
}
515521

516522
template <typename T>
@@ -551,8 +557,6 @@ template <typename Child>
551557
template <bool write>
552558
void ScientificDefaults<Child>::defaults_impl(OpenpmdStandard standard)
553559
{
554-
using maybe_read_error = std::optional<error::ReadError>;
555-
556560
auto float_types = get_float_types();
557561
auto string_types = get_string_types();
558562

@@ -597,17 +601,13 @@ void ScientificDefaults<Child>::defaults_impl(OpenpmdStandard standard)
597601
Mesh::Geometry::cartesian, &Mesh::setGeometry)
598602
.withReader(
599603
string_types,
600-
require_type<std::string>([this](std::string val) {
601-
setMeshGeometryFromString(asChild(), std::move(val));
602-
}))(wor);
604+
require_type(asChild(), &setMeshGeometryFromString))(wor);
603605

604606
defaultAttribute("dataOrder")
605607
.template withSetter<Mesh>(Mesh::DataOrder::C, &Mesh::setDataOrder)
606608
.withReader(
607609
string_types,
608-
require_type<char>([this](char val) -> maybe_read_error {
609-
return setMeshDataOrderFromChar(asChild(), val);
610-
}))(wor);
610+
require_type(asChild(), &setMeshDataOrderFromChar))(wor);
611611

612612
defaultAttribute("axisLabels")
613613
.template withSetter<Mesh, std::vector<std::string> const &>(

0 commit comments

Comments
 (0)