PLCnext API Documentation 25.0.2.69
Future.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6
7#pragma once
8
10#include "Arp/System/Core/Exception.hpp"
11#include "Arp/System/Core/TypeName.hxx"
12#include <atomic>
13#include <memory>
14
15
16namespace Arp { namespace System { namespace Nm { namespace Internal
17{
18template<typename T>
21class Promise;
22} // namespace Internal
23
24
25// <summary>Proxy for the result of an asynchronous function call</summary>
27class ARP_CXX_SYMBOL_EXPORT FutureBase
28{
29protected:
32 struct ImplBase
33 {
34 bool isCreatedByPromise = false;
35 std::atomic<bool> valueHasBeenSet;
36 std::exception_ptr exception;
37 };
38
39public:
40 FutureBase() = default;
41 FutureBase(const FutureBase& other) = default;
42 FutureBase(FutureBase&& other) noexcept = default;
43 virtual ~FutureBase();
44
45 FutureBase& operator=(const FutureBase& other) = default;
46 FutureBase& operator=(FutureBase&& other) noexcept = default;
47
48 bool IsValid() const;
49 bool HasValue() const;
50 bool HasException() const;
51
52protected:
53 virtual ImplBase& GetPImpl() = 0;
54 virtual const ImplBase& GetPImpl() const = 0;
55 void CheckForValueAndException() const;
56
57 void SetException(std::exception_ptr e);
58 void Clear(bool isValid);
59};
60
61
62// -----------------------------------------------------------------------------
63
64
66template<typename T>
67class ARP_CXX_SYMBOL_EXPORT Future : public FutureBase
68{
69private:
70 friend Internal::Promise<T>;
71
72 struct Impl : public ImplBase
73 {
74 T value = T{};
75 };
76
77 static Future CreateByPromise();
78
79public:
83 Future() = default;
84 Future(const Future& other) = default;
85 Future(Future&& other) noexcept = default;
86 ~Future() override = default;
87
88 Future& operator=(const Future& other) = default;
89 Future& operator=(Future&& other) noexcept = default;
90
91 T GetValue() const;
92
93private:
94 void SetValue(const T& value);
95
96 Impl& GetPImpl() override
97 {
98 return *(this->pImpl);
99 }
100
101 const Impl& GetPImpl() const override
102 {
103 return *(this->pImpl);
104 }
105
106private:
107 std::shared_ptr<Impl> pImpl{std::make_shared<Impl>()};
108};
109
110
111template<typename T>
112Future<T> Future<T>::CreateByPromise()
113{
114 Future result;
115 result.pImpl->isCreatedByPromise = true;
116 return result;
117}
118
122template<typename T>
124{
125 this->CheckForValueAndException();
126 return this->GetPImpl().value;
127}
128
129
130template<typename T>
131void Future<T>::SetValue(const T& value)
132{
133 this->GetPImpl().value = value;
134 this->GetPImpl().valueHasBeenSet.store(true);
135}
136
137
138// -----------------------------------------------------------------------------
139
140
142template<>
143class ARP_CXX_SYMBOL_EXPORT Future<void> : public FutureBase
144{
145private:
146 friend Internal::Promise<void>;
147 using Impl = ImplBase;
148
149 static Future CreateByPromise();
150
151public:
152 Future();
153 Future(const Future& other) = default;
154 Future(Future&& other) = default;
155 ~Future() override = default;
156
157 Future& operator=(const Future& other) = default;
158 Future& operator=(Future&& other) = default;
159
160 void GetValue() const;
161
162private:
163 void SetValue();
164
165 Impl& GetPImpl() override;
166 const Impl& GetPImpl() const override;
167
168private:
169 std::shared_ptr<Impl> pImpl;
170};
171
172
173}}} // end of namespace Arp::System::Nm
Base class with common behavior for Future<T> and Future<void>
Definition: Future.hpp:28
Future object as proxy for return value an asynchronous function call
Definition: Future.hpp:68
T GetValue() const
Returns the value set by the associated Promise
Definition: Future.hpp:123
Future()=default
Constructs an invalid Future
Root namespace for the PLCnext API