Skip to content

Commit

Permalink
Add invoke and apply to TaggedContainers.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsdeppe committed Feb 15, 2023
1 parent a7fdeee commit f37d6ac
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/DataStructures/TaggedContainers.hpp
Expand Up @@ -78,3 +78,50 @@ gsl::not_null<typename Tag::type*> get(
}
}
/// @}

namespace detail {
template <typename Callable, typename T, typename... Args,
typename... ReturnTags, typename... ArgumentTags>
auto apply_impl(const gsl::not_null<T*> return_args,
tmpl::list<ReturnTags...> /*meta*/,
tmpl::list<ArgumentTags...> /*meta*/, Callable&& fn,
const Args&... args) {
return fn.apply(get<ReturnTags>(return_args)...,
get<ArgumentTags>(args...)...);
}

template <typename Callable, typename T, typename... Args,
typename... ReturnTags, typename... ArgumentTags>
auto invoke_impl(const gsl::not_null<T*> return_args,
tmpl::list<ReturnTags...> /*meta*/,
tmpl::list<ArgumentTags...> /*meta*/, Callable&& fn,
const Args&... args) {
return fn(get<ReturnTags>(return_args)..., get<ArgumentTags>(args...)...);
}
} // namespace detail

/*!
* \brief Call
* `fn.apply(get<Callable::return_tags>(return_args)...,
* get<Callable::argument_tags>(args...))`
*/
template <typename Callable, typename T, typename... Args>
auto apply(const gsl::not_null<T*> return_args, Callable&& fn,
const Args&... args) {
return detail::apply_impl(return_args, typename Callable::return_tags{},
typename Callable::argument_tags{},
std::forward<Callable>(fn), args...);
}

/*!
* \brief Call
* `fn(get<Callable::return_tags>(return_args)...,
* get<Callable::argument_tags>(args...))`
*/
template <typename Callable, typename T, typename... Args>
auto invoke(const gsl::not_null<T*> return_args, Callable&& fn,
const Args&... args) {
return detail::invoke_impl(return_args, typename Callable::return_tags{},
typename Callable::argument_tags{},
std::forward<Callable>(fn), args...);
}
22 changes: 22 additions & 0 deletions tests/Unit/DataStructures/Test_TaggedContainers.cpp
Expand Up @@ -27,6 +27,21 @@ struct MyDouble2 : db::SimpleTag {
};
} // namespace Tags

struct Function {
using return_tags = tmpl::list<Tags::MyDouble2>;
using argument_tags = tmpl::list<Tags::MyDouble>;

static double apply(const gsl::not_null<double*> result, const double input) {
*result = input;
return 2.0 * input;
}

double operator()(const gsl::not_null<double*> result, const double input) {
*result = 3.0 * input;
return input;
}
};

// Test that desired tags are retrieved.
void test_tagged_containers() {
const auto box = db::create<db::AddSimpleTags<Tags::MyDouble>>(1.2);
Expand Down Expand Up @@ -63,6 +78,13 @@ void test_tagged_containers() {
CHECK(get<Tags::MyDouble>(box, vars, tuple) == 1.2);
CHECK(get<Tags::MyDouble2>(tuple, box, vars) == 4.4);
CHECK(get<Tags::MyScalar>(vars, tuple, box).get() == 3.2);

CHECK(invoke(make_not_null(&tuple), Function{}, box) ==
get<Tags::MyDouble>(box));
CHECK(get<Tags::MyDouble2>(tuple) == 3.0 * get<Tags::MyDouble>(box));
CHECK(apply(make_not_null(&tuple), Function{}, box) ==
2.0 * get<Tags::MyDouble>(box));
CHECK(get<Tags::MyDouble2>(tuple) == get<Tags::MyDouble>(box));
}
} // namespace

Expand Down

0 comments on commit f37d6ac

Please sign in to comment.