Fixes for map (#27079)

* fixes for map

* fix bad merge

* Automated change: Fix sanity tests

* Automated change: Fix sanity tests

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/27156/head
Craig Tiller 3 years ago committed by GitHub
parent 8605020195
commit 764232fa13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      build_autogenerated.yaml
  2. 9
      src/core/lib/promise/detail/promise_factory.h
  3. 4
      src/core/lib/promise/detail/promise_like.h
  4. 23
      src/core/lib/promise/map.h
  5. 6
      test/core/promise/map_test.cc

@ -4224,6 +4224,7 @@ targets:
- src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/gpr/alloc.h
- src/core/lib/gpr/env.h
- src/core/lib/gpr/log_internal.h
- src/core/lib/gpr/murmur_hash.h
- src/core/lib/gpr/spinlock.h
- src/core/lib/gpr/string.h

@ -62,10 +62,6 @@ struct IsVoidCallable<F, absl::void_t<decltype(std::declval<F>()())>> {
static constexpr bool value = true;
};
// T -> T, const T& -> T
template <typename T>
using RemoveCVRef = absl::remove_cv_t<absl::remove_reference_t<T>>;
// Given F(A,B,C,...), what's the return type?
template <typename T, typename Ignored = void>
struct ResultOfT;
@ -86,6 +82,7 @@ class Curried {
public:
Curried(F&& f, Arg&& arg)
: f_(std::forward<F>(f)), arg_(std::forward<Arg>(arg)) {}
Curried(const F& f, Arg&& arg) : f_(f), arg_(std::forward<Arg>(arg)) {}
using Result = decltype(std::declval<F>()(std::declval<Arg>()));
Result operator()() { return f_(arg_); }
@ -98,9 +95,9 @@ class Curried {
// capturing A.
template <typename A, typename F>
absl::enable_if_t<!IsVoidCallable<ResultOf<F(A)>>::value,
PromiseLike<Curried<F, A>>>
PromiseLike<Curried<RemoveCVRef<F>, A>>>
PromiseFactoryImpl(F&& f, A&& arg) {
return Curried<F, A>(std::forward<F>(f), std::forward<A>(arg));
return Curried<RemoveCVRef<F>, A>(std::forward<F>(f), std::forward<A>(arg));
}
// Promote a callable() -> T|Poll<T> to a PromiseFactory(A) -> Promise<T>

@ -74,6 +74,10 @@ class PromiseLike {
using Result = typename PollTraits<decltype(WrapInPoll(f_()))>::Type;
};
// T -> T, const T& -> T
template <typename T>
using RemoveCVRef = absl::remove_cv_t<absl::remove_reference_t<T>>;
} // namespace promise_detail
} // namespace grpc_core

@ -17,6 +17,8 @@
#include <grpc/impl/codegen/port_platform.h>
#include <tuple>
#include "absl/types/variant.h"
#include "src/core/lib/promise/detail/promise_like.h"
#include "src/core/lib/promise/poll.h"
@ -34,10 +36,12 @@ class Map {
Map(Promise promise, Fn fn)
: promise_(std::move(promise)), fn_(std::move(fn)) {}
using Result = typename PromiseLike<Promise>::Result;
using PromiseResult = typename PromiseLike<Promise>::Result;
using Result =
RemoveCVRef<decltype(std::declval<Fn>()(std::declval<PromiseResult>()))>;
Poll<Result> operator()() {
Poll<Result> r = promise_();
Poll<PromiseResult> r = promise_();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
return fn_(std::move(*p));
}
@ -59,6 +63,21 @@ promise_detail::Map<Promise, Fn> Map(Promise promise, Fn fn) {
return promise_detail::Map<Promise, Fn>(std::move(promise), std::move(fn));
}
// Callable that takes a tuple and returns one element
template <size_t kElem>
struct JustElem {
template <typename... A>
auto operator()(std::tuple<A...>&& t) const
-> decltype(std::get<kElem>(std::forward<std::tuple<A...>>(t))) {
return std::get<kElem>(std::forward<std::tuple<A...>>(t));
}
template <typename... A>
auto operator()(const std::tuple<A...>& t) const
-> decltype(std::get<kElem>(t)) {
return std::get<kElem>(t);
}
};
} // namespace grpc_core
#endif // GRPC_CORE_LIB_PROMISE_MAP_H

@ -23,6 +23,12 @@ TEST(MapTest, Works) {
EXPECT_EQ(x(), Poll<int>(21));
}
TEST(MapTest, JustElem) {
std::tuple<int, double> t(1, 3.2);
EXPECT_EQ(JustElem<1>()(t), 3.2);
EXPECT_EQ(JustElem<0>()(t), 1);
}
} // namespace grpc_core
int main(int argc, char** argv) {

Loading…
Cancel
Save