chromium/third_party/blink/renderer/platform/wtf/functional.h

/*
 * Copyright (C) 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_FUNCTIONAL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_FUNCTIONAL_H_

#include <concepts>
#include <utility>

#include "base/dcheck_is_on.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"

namespace WTF {

// Functional.h provides a very simple way to bind a function pointer and
// arguments together into a function object that can be stored, copied and
// invoked, similar to boost::bind and std::bind in C++11.

// To create a same-thread callback, use WTF::BindOnce() or
// WTF::BindRepeating(). Use the former to create a callback that's called only
// once, and use the latter for a callback that may be called multiple times.
//
// WTF::BindOnce() and WTF::BindRepeating() returns base::OnceCallback and
// base::RepeatingCallback respectively. See //docs/callback.md for how to use
// those types.

// Thread Safety:
//
// WTF::BindOnce(), WTF::BindRepeating and base::{Once,Repeating}Callback should
// be used for same-thread closures only, i.e. the closures must be created,
// executed and destructed on the same thread.
//
// Use CrossThreadBindOnce() and CrossThreadBindRepeating() if the function/task
// is called or destructed on a (potentially) different thread from the current
// thread. See cross_thread_functional.h for more details.

// WTF::BindOnce() / WTF::BindRepeating() and move semantics
// =====================================================
//
// For unbound parameters, there are two ways to pass movable arguments:
//
//     1) Pass by rvalue reference.
//
//            void YourFunction(Argument&& argument) { ... }
//            base::OnceCallback<void(Argument&&)> functor =
//                BindOnce(&YourFunction);
//
//     2) Pass by value.
//
//            void YourFunction(Argument argument) { ... }
//            base::OnceCallback<void(Argument)> functor =
//            BindOnce(&YourFunction);
//
// Note that with the latter there will be *two* move constructions happening,
// because there needs to be at least one intermediary function call taking an
// argument of type "Argument" (i.e. passed by value). The former case does not
// require any move constructions inbetween.
//
// Move-only types can be bound to the created callback by using `std::move()`.
// Note that a parameter bound by `std::move()` is *always* moved-from when
// invoking a `base::OnceCallback`, and *never* moved-from when invoking a
// base::RepeatingCallback.
//
// Note: Legacy callback supported transferring move-only arguments to the bound
// functor of a base::RepeatingCallback using the `Passed()` helper; however,
// once the bound arguments are moved-from after the first invocation, the bound
// arguments are (for most movable types) in an undefined but valid state for
// subsequent invocations of the bound functor. This is generally undesirable
// and thus no longer allowed. Callbacks that want to transfer move-only
// arguments to the bound functor *must* be a base::OnceCallback.

template <typename T>
class RetainedRefWrapper final {};

template <typename T>
RetainedRefWrapper<T> RetainedRef(T* ptr) {}

template <typename T>
RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> ptr) {}

template <typename T>
class UnretainedWrapper final {};

template <typename T>
class CrossThreadUnretainedWrapper final {};

template <typename T>
UnretainedWrapper<T> Unretained(T* value) {}

template <typename T>
UnretainedWrapper<T> Unretained(const raw_ptr<T>& value) {}

template <typename T>
CrossThreadUnretainedWrapper<T> CrossThreadUnretained(T* value) {}

template <typename T>
CrossThreadUnretainedWrapper<T> CrossThreadUnretained(const raw_ptr<T>& value) {}

namespace internal {

template <size_t, typename T>
struct CheckGCedTypeRestriction {};

template <typename Index, typename... Args>
struct CheckGCedTypeRestrictions;

CheckGCedTypeRestrictions<std::index_sequence<Ns...>, Args...>;

}  // namespace internal

#if DCHECK_IS_ON()

template <typename CallbackType,
          typename RunType = typename CallbackType::RunType>
class ThreadCheckingCallbackWrapper;

// This class wraps a callback and applies thread checking on its construction,
// destruction and invocation (on Run()).
ThreadCheckingCallbackWrapper<CallbackType, R (Args...)>;

}  // namespace WTF

namespace base {

CallbackCancellationTraits<R (WTF::ThreadCheckingCallbackWrapper<CallbackType>::*)(Args...), std::tuple<std::unique_ptr<WTF::ThreadCheckingCallbackWrapper<CallbackType>>, BoundArgs...>>;

}  // namespace base

namespace WTF {

#endif

template <typename Signature>
class CrossThreadFunction;

CrossThreadFunction<R (Args...)>;

template <typename Signature>
class CrossThreadOnceFunction;

CrossThreadOnceFunction<R (Args...)>;

// Note: now there is WTF::BindOnce() and WTF::BindRepeating(). See the comment
// block above for the correct usage of those.
template <typename FunctionType, typename... BoundParameters>
// `auto` here deduces to an appropriate `base::OnceCallback<>`.
auto BindOnce(FunctionType&& function, BoundParameters&&... bound_parameters) {}

template <typename FunctionType, typename... BoundParameters>
// `auto` here deduces to an appropriate `base::RepeatingCallback<>`.
auto BindRepeating(FunctionType function,
                   BoundParameters&&... bound_parameters) {}

CrossThreadRepeatingFunction;
CrossThreadRepeatingClosure;
CrossThreadClosure;

CrossThreadOnceClosure;

CrossThreadCopier<RetainedRefWrapper<T>>;

CrossThreadCopier<CrossThreadUnretainedWrapper<T>>;

CrossThreadCopier<CrossThreadFunction<Signature>>;

CrossThreadCopier<CrossThreadOnceFunction<Signature>>;

}  // namespace WTF

namespace base {

BindUnwrapTraits<WTF::RetainedRefWrapper<T>>;

BindUnwrapTraits<WTF::UnretainedWrapper<T>>;

BindUnwrapTraits<WTF::CrossThreadUnretainedWrapper<T>>;

}  // namespace base

CrossThreadUnretained;

CrossThreadFunction;
CrossThreadClosure;

CrossThreadOnceClosure;
CrossThreadOnceFunction;

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_FUNCTIONAL_H_