chromium/base/test/rectify_callback_internal.h

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_RECTIFY_CALLBACK_INTERNAL_H_
#define BASE_TEST_RECTIFY_CALLBACK_INTERNAL_H_

#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/types/is_instantiation.h"

namespace base::internal {

// RectifyCallbackWrapper binds a wrapper around the actual callback that
// discards the ignored arguments and forwards the remaining arguments to the
// wrapped callback.

template <template <typename> typename CallbackType,
          typename PartialSignature,
          typename IgnoreSignature>
struct RectifyCallbackWrapper;

RectifyCallbackWrapper<CallbackType, R (PartialArgs...), void (IgnoredArgs...)>;

// RectifyCallbackSplitter is a helper that returns the first N args of
// `Signature` as the type `void(Args...)`. These are the arguments that need
// to be ignored when rectifying a callback.

template <size_t count, typename Signature, typename Result = void()>
struct RectifyCallbackSplitter;

RectifyCallbackSplitter<0, void (Arg, Args...), void (Results...)>;

RectifyCallbackSplitter<0, void (Args...), void (Results...)>;

RectifyCallbackSplitter<count, void (Arg, Args...), void (Results...)>;

// Given a desired type and an actual type, RectifyCallbackImpl provides a
// Rectify() method that adapts the input callback to be callable using the
// arguments from desired type.

template <typename DesiredType, typename ActualType, typename SFINAE = void>
struct RectifyCallbackImpl;

// Main specialization that handles the case where the desired and actual types
// have already been normalized into callback types. The other specializations
// allow additional flexibility for callers, but eventually all delegate here.
RectifyCallbackImpl<DesiredCallbackType<R (DesiredArgs...)>, ActualCallbackType<R (ActualArgs...)>>;

// Specialization that handles a type signature as the desired type. The output
// in this case will be based on the type of callback passed in.
RectifyCallbackImpl<R (Args...), ActualCallbackType<ActualSignature>>;

// Fallback for things like DoNothing(), NullCallback(), etc. where a specific
// callback return type is provided.
RectifyCallbackImpl<DesiredCallbackType<R (Args...)>, T>;

// Fallback for things like DoNothing(), NullCallback(), etc. where only the
// signature of the return type is provided. In this case, `RepeatingCallback`
// is implicitly generated, as it can be used as both a `OnceCallback` or
// `RepeatingCallback`.
RectifyCallbackImpl<R (Args...), T>;

}  // namespace base::internal

#endif  // BASE_TEST_RECTIFY_CALLBACK_INTERNAL_H_