dispenso 1.5.1
A library for task parallelism
Loading...
Searching...
No Matches
once_function.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
15#pragma once
16
17#include <utility>
18
19#include <dispenso/detail/once_callable_impl.h>
20#include <dispenso/platform.h>
21
22namespace dispenso {
23
24#if DISPENSO_HAS_CONCEPTS
33template <typename F>
34concept OnceCallableFunc = std::invocable<F>;
35#endif // DISPENSO_HAS_CONCEPTS
36
37namespace detail {
38template <typename Result>
39class FutureBase;
40template <typename Result>
41class FutureImplBase;
42} // namespace detail
43
54 public:
59#if defined DISPENSO_DEBUG
60 : data_(nullptr),
61 invoke_(nullptr)
62#endif // DISPENSO_DEBUG
63 {
64 }
65
73 template <typename F>
74 DISPENSO_REQUIRES(OnceCallableFunc<F>)
75 OnceFunction(F&& f) {
76 auto callable = detail::createOnceCallable(std::forward<F>(f));
77 data_ = callable.data;
78 invoke_ = callable.invoke;
79 }
80
81 OnceFunction(const OnceFunction& other) = delete;
82
84 OnceFunction(OnceFunction&& other) noexcept : data_(other.data_), invoke_(other.invoke_) {
85#if defined DISPENSO_DEBUG
86 other.data_ = nullptr;
87 other.invoke_ = nullptr;
88#endif // DISPENSO_DEBUG
89 }
90
91 OnceFunction& operator=(OnceFunction&& other) noexcept {
92 data_ = other.data_;
93 invoke_ = other.invoke_;
94#if defined DISPENSO_DEBUG
95 if (&other != this) {
96 other.data_ = nullptr;
97 other.invoke_ = nullptr;
98 }
99#endif // DISPENSO_DEBUG
100 return *this;
101 }
102
108 void cleanupNotRun() const {
109#if defined DISPENSO_DEBUG
110 assert(data_ != nullptr && "Must not cleanup an invalid OnceFunction!");
111 invoke_(data_, false);
112 data_ = nullptr;
113 invoke_ = nullptr;
114#else
115 invoke_(data_, false);
116#endif // DISPENSO_DEBUG
117 }
118
123 void operator()() const {
124#if defined DISPENSO_DEBUG
125 assert(data_ != nullptr && "Must not use OnceFunction more than once!");
126#endif // DISPENSO_DEBUG
127
128 invoke_(data_, true);
129
130#if defined DISPENSO_DEBUG
131 data_ = nullptr;
132 invoke_ = nullptr;
133#endif // DISPENSO_DEBUG
134 }
135
136 private:
137 OnceFunction(detail::OnceCallable* func, bool) : data_(func), invoke_(&detail::runOnceCallable) {}
138
139 mutable void* data_;
140 void (*invoke_)(void*, bool);
141
142 template <typename Result>
143 friend class detail::FutureBase;
144 template <typename Result>
145 friend class detail::FutureImplBase;
146};
147
148} // namespace dispenso
OnceFunction(OnceFunction &&other) noexcept