chromium/third_party/grpc/src/src/core/lib/promise/arena_promise.h

// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GRPC_SRC_CORE_LIB_PROMISE_ARENA_PROMISE_H
#define GRPC_SRC_CORE_LIB_PROMISE_ARENA_PROMISE_H

#include <grpc/support/port_platform.h>

#include <stdlib.h>

#include <memory>
#include <type_traits>
#include <utility>

#include "absl/meta/type_traits.h"

#include "src/core/lib/gprpp/construct_destruct.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/resource_quota/arena.h"

namespace grpc_core {

namespace arena_promise_detail {

ArgType;
template <typename T>
T*& ArgAsPtr(ArgType* arg) {}

template <typename T>
struct Vtable {};

template <typename T>
struct VtableAndArg {};

// Implementation of Vtable for an empty object.
// Used when an empty ArenaPromise is created, or when the ArenaPromise is moved
// from. Since in either case these objects should not be polled, we simply
// crash if it is.
template <typename T>
struct Null {};

template <typename T>
const Vtable<T> Null<T>::vtable =;

// Implementation of ImplInterface for a callable object.
template <typename T, typename Callable>
struct AllocatedCallable {};

template <typename T, typename Callable>
const Vtable<T> AllocatedCallable<T, Callable>::vtable =;

// Implementation of ImplInterface for a small callable object (one that fits
// within the ArgType arg)
template <typename T, typename Callable>
struct Inlined {};

template <typename T, typename Callable>
const Vtable<T> Inlined<T, Callable>::vtable =;

// If a callable object is empty we can substitute any instance of that callable
// for the one we call (for how could we tell the difference)?
// Since this corresponds to a lambda with no fields, and we expect these to be
// reasonably common, we can elide the arena allocation entirely and simply poll
// a global shared instance.
// (this comes up often when the promise only accesses context data from the
// containing activity).
template <typename T, typename Callable>
struct SharedCallable {};

template <typename T, typename Callable>
const Vtable<T> SharedCallable<T, Callable>::vtable =;

// Redirector type: given a callable type, expose a Make() function that creates
// the appropriate underlying implementation.
template <typename T, typename Callable, typename Ignored = void>
struct ChooseImplForCallable;

ChooseImplForCallable<T, Callable, absl::enable_if_t<!std::is_empty<Callable>::value && (sizeof(Callable) > sizeof(ArgType))>>;

ChooseImplForCallable<T, Callable, absl::enable_if_t<!std::is_empty<Callable>::value && (sizeof(Callable) <= sizeof(ArgType))>>;

ChooseImplForCallable<T, Callable, absl::enable_if_t<std::is_empty<Callable>::value>>;

// Wrap ChooseImplForCallable with a friend approachable syntax.
template <typename T, typename Callable>
void MakeImplForCallable(Callable&& callable, VtableAndArg<T>* out) {}

}  // namespace arena_promise_detail

// A promise for which the state memory is allocated from an arena.
template <typename T>
class ArenaPromise {};

}  // namespace grpc_core

#endif  // GRPC_SRC_CORE_LIB_PROMISE_ARENA_PROMISE_H