Skip to content

Commit

Permalink
Add CPP_lambda macro
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysztof-tyb committed Feb 12, 2025
1 parent 707f5bf commit 90b077e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
45 changes: 44 additions & 1 deletion src/backports/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
// resolution.
//
// `QL_CONCEPT_OR_TYPENAME(arg)`: expands to `arg` in C++20 mode, and to
// `typename` in C++17 mode. Example usage:
// `typename` in C++17 mode.
//
// `CPP_lambda(capture)(arg)(requires ...)`: Expands lambda to use
// `requires` in C++20 mode and `std::enable_if_t` in C++17 mode.
//
// Example usages:
//
Expand All @@ -29,15 +32,55 @@
//
// `template <QL_CONCEPT_OR_TYPENAME(ql::same_as<int>) T> void f(){...}`
//
// `auto myLambda = CPP_lambda(someCapture)(someArg)(requires
// ranges::same_as<decltype(someArg), int>) {...}`
//
// NOTE: The macros are variadic to allow for commas in the argument, like in
// the second example above.

#ifdef QLEVER_CPP_17
#define QL_CONCEPT_OR_NOTHING(...)
#define QL_CONCEPT_OR_TYPENAME(...) typename

#define CPP_lambda CPP_lambda_sfinae

#define CPP_LAMBDA_SFINAE_ARGS(...) \
(__VA_ARGS__ CPP_LAMBDA_SFINAE_AUX_

#define CPP_LAMBDA_SFINAE_AUX_WHICH_(FIRST, ...) \
CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT(CPP_LAMBDA_SFINAE_PROBE_CONCEPT_, FIRST))

#define CPP_LAMBDA_SFINAE_AUX_(...) \
CPP_PP_CAT(CPP_LAMBDA_SFINAE_AUX_, \
CPP_LAMBDA_SFINAE_AUX_WHICH_(__VA_ARGS__, )) \
(__VA_ARGS__)

#define CPP_LAMBDA_SFINAE_AUX_0(...) , \
std::enable_if_t< \
CPP_PP_CAT(CPP_LAMBDA_SFINAE_AUX_3_, __VA_ARGS__) \
>* = nullptr)

#define CPP_lambda_sfinae(...) \
CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \
[__VA_ARGS__] CPP_LAMBDA_SFINAE_ARGS

#define CPP_LAMBDA_SFINAE_AUX_3_requires

#else
#define QL_CONCEPT_OR_NOTHING(...) __VA_ARGS__
#define QL_CONCEPT_OR_TYPENAME(...) __VA_ARGS__

#define CPP_lambda(...) [__VA_ARGS__] CPP_LAMBDA_ARGS

#define CPP_LAMBDA_ARGS(...) (__VA_ARGS__) CPP_LAMBDA_AUX_

#define CPP_LAMBDA_AUX_(...) \
CPP_PP_CAT(CPP_LAMBDA_AUX_, CPP_LAMBDA_AUX_WHICH_(__VA_ARGS__, ))(__VA_ARGS__)

#define CPP_LAMBDA_AUX_WHICH_(FIRST, ...) CPP_PP_EVAL(CPP_PP_CHECK, FIRST)

#define CPP_LAMBDA_AUX_0(...) __VA_ARGS__

#endif

// The namespace `ql::concepts` includes concepts that are contained in the
Expand Down
20 changes: 9 additions & 11 deletions src/engine/sparqlExpressions/SparqlExpressionGenerators.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,18 @@ CPP_template(typename Input, typename Transformation = std::identity)(

/// Generate `numItems` many values from the `input` and apply the
/// `valueGetter` to each of the values.
inline auto valueGetterGenerator = []<typename ValueGetter, typename Input>(
size_t numElements,
EvaluationContext* context,
Input&& input,
ValueGetter&& valueGetter) {
CPP_assert(SingleExpressionResult<Input>);
auto transformation = [context, valueGetter]<typename I>(I&& i)
-> CPP_ret(decltype(valueGetter(AD_FWD(i), context)))(
requires ranges::invocable<ValueGetter, I&&, EvaluationContext*>) {
inline auto valueGetterGenerator = CPP_lambda()(
size_t numElements, EvaluationContext* context, auto&& input,
auto&& valueGetter)(requires SingleExpressionResult<decltype(input)>) {
auto transformation = CPP_lambda(context, valueGetter)(auto&& i)(
requires ranges::invocable<decltype(valueGetter), decltype(i),
EvaluationContext*>) {
context->cancellationHandle_->throwIfCancelled();
return valueGetter(AD_FWD(i), context);
};
return makeGenerator(std::forward<Input>(input), numElements, context,
transformation);

return makeGenerator(std::forward<decltype(input)>(input), numElements,
context, transformation);
};

/// Do the following `numItems` times: Obtain the next elements e_1, ..., e_n
Expand Down

0 comments on commit 90b077e

Please sign in to comment.