43 void Notify() { m_resultCv.notify_all(); }
46 void Wait(std::unique_lock<wpi::util::mutex>& lock) { m_resultCv.wait(lock); }
49 template <
class Clock,
class Duration>
50 bool WaitUntil(std::unique_lock<wpi::util::mutex>& lock,
51 const std::chrono::time_point<Clock, Duration>& timeout_time) {
52 return m_resultCv.wait_until(lock, timeout_time) ==
53 std::cv_status::no_timeout;
70 std::atomic_bool m_active{
true};
74 std::vector<uint64_t> m_requests;
77template <
typename To,
typename From>
84template <
typename From>
101 template <
typename F>
168 void SetValue(uint64_t request, T&& value);
175 template <
class Clock,
class Duration>
178 const std::chrono::time_point<Clock, Duration>& timeout_time);
184 Then(uint64_t request_, uint64_t outRequest_,
ThenFunction func_)
185 : request(request_), outRequest(outRequest_), func(
std::move(func_)) {}
191 std::vector<Then> m_thens;
192 std::vector<std::pair<uint64_t, T>> m_results;
200 friend class future<void>;
242 template <
class Clock,
class Duration>
245 const std::chrono::time_point<Clock, Duration>& timeout_time);
251 Then(uint64_t request_, uint64_t outRequest_,
ThenFunction func_)
252 : request(request_), outRequest(outRequest_), func(
std::move(func_)) {}
258 std::vector<Then> m_thens;
259 std::vector<uint64_t> m_results;
281 this->m_request = oth.m_request;
282 this->m_promises = oth.m_promises;
284 oth.m_promises =
nullptr;
288 template <
typename R>
290 :
future(oth.then([](R&& val) -> T { return val; })) {}
297 m_promises->IgnoreResult(m_request);
302 this->m_request = oth.m_request;
303 this->m_promises = oth.m_promises;
305 oth.m_promises =
nullptr;
318 return m_promises->GetResult(m_request);
324 template <
typename R,
typename F>
327 auto promises = m_promises;
328 m_promises =
nullptr;
336 template <
typename F,
typename R =
typename std::invoke_result_t<F&&, T&&>>
342 return m_promises && m_promises->IsReady(m_request);
351 bool valid() const noexcept {
return m_promises; }
361 m_promises->WaitResult(m_request);
371 template <
class Clock,
class Duration>
373 const std::chrono::time_point<Clock, Duration>& timeout_time)
const {
374 return m_promises && m_promises->WaitResultUntil(m_request, timeout_time);
383 template <
class Rep,
class Period>
385 const std::chrono::duration<Rep, Period>& timeout_duration)
const {
386 return wait_until(std::chrono::steady_clock::now() + timeout_duration);
391 : m_request(request), m_promises(promises) {}
393 uint64_t m_request = 0;
412 m_request = oth.m_request;
413 m_promises = oth.m_promises;
415 oth.m_promises =
nullptr;
424 m_promises->IgnoreResult(m_request);
429 m_request = oth.m_request;
430 m_promises = oth.m_promises;
432 oth.m_promises =
nullptr;
443 m_promises->GetResult(m_request);
447 template <
typename R,
typename F>
450 auto promises = m_promises;
451 m_promises =
nullptr;
459 template <
typename F,
typename R =
typename std::invoke_result_t<F&&>>
465 return m_promises && m_promises->IsReady(m_request);
474 bool valid() const noexcept {
return m_promises; }
483 m_promises->WaitResult(m_request);
493 template <
class Clock,
class Duration>
495 const std::chrono::time_point<Clock, Duration>& timeout_time)
const {
496 return m_promises && m_promises->WaitResultUntil(m_request, timeout_time);
505 template <
class Rep,
class Period>
507 const std::chrono::duration<Rep, Period>& timeout_duration)
const {
508 return wait_until(std::chrono::steady_clock::now() + timeout_duration);
513 : m_request(request), m_promises(promises) {}
515 uint64_t m_request = 0;
535 m_request = m_promises->CreateRequest();
539 : m_request(oth.m_request), m_promises(oth.m_promises) {
541 oth.m_promises =
nullptr;
551 m_promises->SetValue(m_request, T());
556 m_request = oth.m_request;
557 m_promises = oth.m_promises;
559 oth.m_promises =
nullptr;
588 m_promises->SetValue(m_request, value);
590 m_promises =
nullptr;
601 m_promises->SetValue(m_request, std::move(value));
603 m_promises =
nullptr;
608 : m_request(request), m_promises(promises) {}
610 uint64_t m_request = 0;
626 m_request = m_promises->CreateRequest();
630 : m_request(oth.m_request), m_promises(oth.m_promises) {
632 oth.m_promises =
nullptr;
642 m_promises->SetValue(m_request);
647 m_request = oth.m_request;
648 m_promises = oth.m_promises;
650 oth.m_promises =
nullptr;
679 m_promises->SetValue(m_request);
681 m_promises =
nullptr;
686 : m_request(request), m_promises(promises) {}
688 uint64_t m_request = 0;
689 PromiseFactory<void>* m_promises =
nullptr;
698 std::forward<T>(value));
717 m_results.emplace_back(std::piecewise_construct, std::forward_as_tuple(req),
718 std::forward_as_tuple(std::move(value)));
733 auto it = std::find_if(m_thens.begin(), m_thens.end(),
734 [=](
const auto& x) { return x.request == request; });
735 if (it != m_thens.end()) {
736 uint64_t outRequest = it->outRequest;
740 return func(outRequest, value);
742 m_results.emplace_back(std::piecewise_construct,
743 std::forward_as_tuple(request),
744 std::forward_as_tuple(value));
754 auto it = std::find_if(m_thens.begin(), m_thens.end(),
755 [=](
const auto& x) { return x.request == request; });
756 if (it != m_thens.end()) {
757 uint64_t outRequest = it->outRequest;
761 return func(outRequest, std::move(value));
763 m_results.emplace_back(std::piecewise_construct,
764 std::forward_as_tuple(request),
765 std::forward_as_tuple(std::move(value)));
773 auto it = std::find_if(m_results.begin(), m_results.end(),
774 [=](
const auto& r) { return r.first == request; });
775 if (it != m_results.end()) {
776 auto val = std::move(it->second);
779 return func(outRequest, std::move(val));
781 m_thens.emplace_back(request, outRequest, func);
787 auto it = std::find_if(m_results.begin(), m_results.end(),
788 [=](
const auto& r) { return r.first == request; });
789 return it != m_results.end();
798 auto it = std::find_if(m_results.begin(), m_results.end(),
799 [=](
const auto& r) { return r.first == request; });
800 if (it != m_results.end()) {
802 auto rv = std::move(it->second);
818 auto it = std::find_if(m_results.begin(), m_results.end(),
819 [=](
const auto& r) { return r.first == request; });
820 if (it != m_results.end()) {
829template <
class Clock,
class Duration>
832 const std::chrono::time_point<Clock, Duration>& timeout_time) {
834 bool timeout =
false;
837 auto it = std::find_if(m_results.begin(), m_results.end(),
838 [=](
const auto& r) { return r.first == request; });
839 if (it != m_results.end()) {
867template <
class Clock,
class Duration>
870 const std::chrono::time_point<Clock, Duration>& timeout_time) {
872 bool timeout =
false;
875 auto it = std::find_if(m_results.begin(), m_results.end(),
876 [=](
const auto& r) { return r == request; });
877 if (it != m_results.end()) {
891template <
typename To,
typename From>
897 fromFactory.
SetThen(request, req, [&factory, func](uint64_t r, From value) {
898 factory.
SetValue(r, func(std::move(value)));
903template <
typename From>
909 fromFactory.
SetThen(request, req, [&factory, func](uint64_t r, From value) {
910 func(std::move(value));
916template <
typename To>
922 fromFactory.
SetThen(request, req, [&factory, func](uint64_t r) {
933 fromFactory.
SetThen(request, req, [&factory, func](uint64_t r) {
void WaitResult(uint64_t request)
void GetResult(uint64_t request)
void SetValue(uint64_t request)
Sets a value directly for a future without creating a promise object.
void SetThen(uint64_t request, uint64_t outRequest, ThenFunction func)
std::function< void(uint64_t)> ThenFunction
Definition future.hpp:204
future< void > MakeReadyFuture()
Creates a future and makes it immediately ready.
static PromiseFactory & GetInstance()
bool IsReady(uint64_t request) noexcept
A promise factory for lightweight futures.
Definition future.hpp:122
future< T > MakeReadyFuture(T &&value)
Creates a future and makes it immediately ready.
Definition future.hpp:714
std::function< void(uint64_t, T)> ThenFunction
Definition future.hpp:127
static PromiseFactory & GetInstance()
Definition future.hpp:854
bool IsReady(uint64_t request) noexcept
Definition future.hpp:785
T GetResult(uint64_t request)
Definition future.hpp:793
void WaitResult(uint64_t request)
Definition future.hpp:813
void SetThen(uint64_t request, uint64_t outRequest, ThenFunction func)
Definition future.hpp:770
future< T > CreateFuture(uint64_t request)
Creates a future.
Definition future.hpp:709
void SetValue(uint64_t request, const T &value)
Sets a value directly for a future without creating a promise object.
Definition future.hpp:728
promise< T > CreatePromise(uint64_t request)
Creates a promise.
Definition future.hpp:723
void Notify()
Definition future.hpp:43
bool WaitResultUntil(uint64_t request, const std::chrono::time_point< Clock, Duration > &timeout_time)
Definition future.hpp:830
wpi::util::mutex & GetResultMutex()
Definition future.hpp:41
uint64_t CreateErasedRequest()
Definition future.hpp:66
void Wait(std::unique_lock< wpi::util::mutex > &lock)
Definition future.hpp:46
void IgnoreResult(uint64_t request)
void Notify()
Definition future.hpp:43
bool EraseRequest(uint64_t request)
bool IsActive() const
Definition future.hpp:39
bool WaitUntil(std::unique_lock< wpi::util::mutex > &lock, const std::chrono::time_point< Clock, Duration > &timeout_time)
Definition future.hpp:50
bool wait_for(const std::chrono::duration< Rep, Period > &timeout_duration) const
Waits for the promise to provide a value, or the specified amount of time has elapsed.
Definition future.hpp:506
bool is_ready() const noexcept
Definition future.hpp:464
void wait() const
Waits for the promise to provide a value.
Definition future.hpp:481
future & operator=(future &&oth) noexcept
Definition future.hpp:428
future & operator=(const future &)=delete
void get()
Gets the value.
Definition future.hpp:441
future() noexcept=default
Constructs an empty (invalid) future.
~future()
Ignores the result of the future if it has not been retrieved.
Definition future.hpp:422
future(const future &)=delete
bool wait_until(const std::chrono::time_point< Clock, Duration > &timeout_time) const
Waits for the promise to provide a value, or the specified time has been reached.
Definition future.hpp:494
bool valid() const noexcept
Checks if the future is valid.
Definition future.hpp:474
future< R > then(PromiseFactory< R > &factory, F &&func)
Definition future.hpp:448
future< R > then(F &&func)
Definition future.hpp:460
A lightweight version of std::future.
Definition future.hpp:270
future & operator=(const future &)=delete
future & operator=(future &&oth) noexcept
Definition future.hpp:301
future< R > then(F &&func)
Definition future.hpp:337
T get()
Gets the value.
Definition future.hpp:316
bool valid() const noexcept
Checks if the future is valid.
Definition future.hpp:351
future< R > then(PromiseFactory< R > &factory, F &&func)
Definition future.hpp:325
~future()
Ignores the result of the future if it has not been retrieved.
Definition future.hpp:295
bool wait_for(const std::chrono::duration< Rep, Period > &timeout_duration) const
Waits for the promise to provide a value, or the specified amount of time has elapsed.
Definition future.hpp:384
future(future< R > &&oth) noexcept
Definition future.hpp:289
bool wait_until(const std::chrono::time_point< Clock, Duration > &timeout_time) const
Waits for the promise to provide a value, or the specified time has been reached.
Definition future.hpp:372
future() noexcept=default
Constructs an empty (invalid) future.
void wait() const
Waits for the promise to provide a value.
Definition future.hpp:359
bool is_ready() const noexcept
Definition future.hpp:341
future(const future &)=delete
promise(const promise &)=delete
promise()
Constructs an empty promise.
Definition future.hpp:625
promise(promise &&oth) noexcept
Definition future.hpp:629
promise & operator=(const promise &)=delete
promise & operator=(promise &&oth) noexcept
Definition future.hpp:646
~promise()
Sets the promised value if not already set.
Definition future.hpp:640
void swap(promise &oth) noexcept
Swaps this promise with another one.
Definition future.hpp:659
future< void > get_future() noexcept
Gets a future for this promise.
Definition future.hpp:669
void set_value()
Sets the promised value.
Definition future.hpp:677
A lightweight version of std::promise.
Definition future.hpp:527
promise(const promise &)=delete
~promise()
Sets the promised value to a default-constructed T if not already set.
Definition future.hpp:549
promise(promise &&oth) noexcept
Definition future.hpp:538
promise & operator=(promise &&oth) noexcept
Definition future.hpp:555
future< T > get_future() noexcept
Gets a future for this promise.
Definition future.hpp:578
promise & operator=(const promise &)=delete
void swap(promise &oth) noexcept
Swaps this promise with another one.
Definition future.hpp:568
void set_value(const T &value)
Sets the promised value.
Definition future.hpp:586
void set_value(T &&value)
Sets the promised value.
Definition future.hpp:599
promise()
Constructs an empty promise.
Definition future.hpp:534
Definition StringMap.hpp:773
void swap(wpi::util::StringMap< T > &lhs, wpi::util::StringMap< T > &rhs)
Definition StringMap.hpp:775
These are wrappers over isa* function that allow them to be used in generic algorithms such as wpi::u...
Definition type_traits.hpp:71
Definition raw_os_ostream.hpp:19
::std::condition_variable condition_variable
Definition condition_variable.hpp:16
future< void > make_ready_future()
Constructs a valid future with the value set.
Definition future.hpp:704
::std::mutex mutex
Definition mutex.hpp:17
void Wait(wpi::units::second_t seconds)
Pause the task for a specified time.
static future< To > Create(PromiseFactory< From > &fromFactory, uint64_t request, PromiseFactory< To > &factory, F &&func)
Definition future.hpp:893