Skip to content

Commit b2a390d

Browse files
authored
Simplify evaluation dispatch using constexpr and templates (#669)
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 79b05fe commit b2a390d

7 files changed

Lines changed: 475 additions & 963 deletions

File tree

src/evaluator/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME evaluator
22
FOLDER "Blaze/Evaluator"
33
PRIVATE_HEADERS error.h value.h instruction.h string_set.h dispatch.h
4-
complete.h dynamic.h fast.h track.h
54
SOURCES evaluator_json.cc evaluator_describe.cc)
65

76
if(BLAZE_INSTALL)

src/evaluator/include/sourcemeta/blaze/evaluator.h

Lines changed: 36 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT Evaluator {
110110

111111
if (schema.track && schema.dynamic) [[unlikely]] {
112112
this->evaluated_.clear();
113-
static const Callback null_callback{nullptr};
114-
return this->evaluate_complete(schema, instance, null_callback);
113+
return this->evaluate_impl<true, true, false>(schema, instance, nullptr);
115114
} else if (schema.track) [[unlikely]] {
116115
this->evaluated_.clear();
117-
return this->evaluate_track(schema, instance);
116+
return this->evaluate_impl<true, false, false>(schema, instance, nullptr);
118117
} else if (schema.dynamic) [[unlikely]] {
119-
return this->evaluate_dynamic(schema, instance);
118+
return this->evaluate_impl<false, true, false>(schema, instance, nullptr);
120119
} else {
121-
return this->evaluate_fast(schema, instance);
120+
return this->evaluate_impl<false, false, false>(schema, instance,
121+
nullptr);
122122
}
123123
}
124124

@@ -180,19 +180,14 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT Evaluator {
180180
assert(this->instance_location.empty());
181181
assert(this->resources.empty());
182182
this->evaluated_.clear();
183-
return this->evaluate_complete(schema, instance, callback);
183+
return this->evaluate_impl<true, true, true>(schema, instance, &callback);
184184
}
185185

186186
#ifndef DOXYGEN
187-
auto evaluate_fast(const Template &schema,
188-
const sourcemeta::core::JSON &instance) -> bool;
189-
auto evaluate_track(const Template &schema,
190-
const sourcemeta::core::JSON &instance) -> bool;
191-
auto evaluate_dynamic(const Template &schema,
192-
const sourcemeta::core::JSON &instance) -> bool;
193-
auto evaluate_complete(const Template &schema,
194-
const sourcemeta::core::JSON &instance,
195-
const Callback &callback) -> bool;
187+
template <bool Track, bool Dynamic, bool HasCallback>
188+
auto evaluate_impl(const Template &schema,
189+
const sourcemeta::core::JSON &instance,
190+
const Callback *callback) -> bool;
196191

197192
// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
198193
static inline const sourcemeta::core::JSON null{nullptr};
@@ -264,74 +259,40 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT Evaluator {
264259

265260
#ifndef DOXYGEN
266261

267-
namespace sourcemeta::blaze {
268-
269-
inline auto
270-
resolve_target(const sourcemeta::core::JSON::String *property_target,
271-
const sourcemeta::core::JSON &instance) noexcept
272-
-> const sourcemeta::core::JSON & {
273-
if (property_target) [[unlikely]] {
274-
return Evaluator::empty_string;
262+
#include <sourcemeta/blaze/evaluator_dispatch.h>
263+
264+
template <bool Track, bool Dynamic, bool HasCallback>
265+
auto sourcemeta::blaze::Evaluator::evaluate_impl(
266+
const Template &schema, const sourcemeta::core::JSON &instance,
267+
const Callback *callback) -> bool {
268+
assert(!schema.targets.empty());
269+
dispatch::DispatchContext<Track, Dynamic, HasCallback> context{
270+
.schema = &schema,
271+
.callback = callback,
272+
.evaluator = this,
273+
.property_target = nullptr};
274+
bool overall{true};
275+
for (const auto &instruction : schema.targets[0]) {
276+
if (!dispatch::evaluate_instruction(instruction, instance, 0, context))
277+
[[unlikely]] {
278+
overall = false;
279+
break;
280+
}
275281
}
276282

277-
// NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
278-
return instance;
279-
}
280-
281-
inline auto
282-
resolve_instance(const sourcemeta::core::JSON &instance,
283-
const sourcemeta::core::Pointer &relative_instance_location)
284-
-> const sourcemeta::core::JSON & {
285-
if (relative_instance_location.empty()) {
286-
// NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
287-
return instance;
283+
if constexpr (Track || HasCallback) {
284+
assert(this->evaluate_path.empty());
288285
}
289-
290-
return sourcemeta::core::get(instance, relative_instance_location);
291-
}
292-
293-
inline auto resolve_string_target(
294-
const sourcemeta::core::JSON::String *property_target,
295-
const sourcemeta::core::JSON &instance,
296-
const sourcemeta::core::Pointer &relative_instance_location) noexcept
297-
-> const sourcemeta::core::JSON::String * {
298-
if (property_target) [[unlikely]] {
299-
return property_target;
286+
if constexpr (HasCallback) {
287+
assert(this->instance_location.empty());
300288
}
301-
302-
const auto &target{resolve_instance(instance, relative_instance_location)};
303-
if (!target.is_string()) [[unlikely]] {
304-
return nullptr;
305-
} else {
306-
return &target.to_string();
289+
if constexpr (Dynamic) {
290+
assert(this->resources.empty());
307291
}
308-
}
309292

310-
inline auto
311-
effective_type_strict_real(const sourcemeta::core::JSON &instance) noexcept
312-
-> sourcemeta::core::JSON::Type {
313-
const auto real_type{instance.type()};
314-
switch (real_type) {
315-
case sourcemeta::core::JSON::Type::Decimal:
316-
return instance.to_decimal().is_integer()
317-
? sourcemeta::core::JSON::Type::Integer
318-
: sourcemeta::core::JSON::Type::Real;
319-
default:
320-
return real_type;
321-
}
293+
return overall;
322294
}
323295

324-
} // namespace sourcemeta::blaze
325-
326-
#define SOURCEMETA_STRINGIFY(x) #x
327-
328-
#include <sourcemeta/blaze/evaluator_complete.h>
329-
#include <sourcemeta/blaze/evaluator_dynamic.h>
330-
#include <sourcemeta/blaze/evaluator_fast.h>
331-
#include <sourcemeta/blaze/evaluator_track.h>
332-
333-
#undef SOURCEMETA_STRINGIFY
334-
335296
#endif // !DOXYGEN
336297

337298
#endif

0 commit comments

Comments
 (0)