// 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_