PLCnext API Documentation 24.0.0.71
Future.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
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 class IExceptionWrapper
33 {
34 public:
35 virtual ~IExceptionWrapper() = default;
36 virtual void ReThrowException() = 0;
37 };
38
39
42 template<typename ExceptionType>
43 class ExceptionWrapper : public IExceptionWrapper
44 {
45 public:
46 explicit ExceptionWrapper(const ExceptionType& e) : exception(e)
47 {
48 }
49
50 ~ExceptionWrapper() override = default;
51
52 void ReThrowException() override
53 {
54 throw this->exception;
55 }
56
57 private:
58 ExceptionType exception;
59 };
60
61
64 struct ImplBase
65 {
66 bool isCreatedByPromise = false;
67 std::atomic<bool> valueHasBeenSet;
68 std::unique_ptr<IExceptionWrapper> exception;
69 };
70
71public:
72 FutureBase() = default;
73 FutureBase(const FutureBase& other) = default;
74 FutureBase(FutureBase&& other) noexcept = default;
75 virtual ~FutureBase();
76
77 FutureBase& operator=(const FutureBase& other) = default;
78 FutureBase& operator=(FutureBase&& other) noexcept = default;
79
81 const bool IsValid() const;
82
84 const bool HasValue() const;
85
87 const bool HasException() const;
88
89protected:
90 virtual ImplBase& GetPImpl() = 0;
91 virtual const ImplBase& GetPImpl() const = 0;
92 void CheckForValueAndException() const;
93
94 template<typename ExceptionType>
95 void SetException(const ExceptionType& e);
96
97 void Clear(bool isValid);
98};
99
100
101template<typename ExceptionType>
102void FutureBase::SetException(const ExceptionType& e)
103{
104 this->GetPImpl().exception = std::make_unique<ExceptionWrapper<ExceptionType>>(e);
105 this->GetPImpl().valueHasBeenSet.store(true);
106}
107
108
109// -----------------------------------------------------------------------------
110
111
113template<typename T>
114class ARP_CXX_SYMBOL_EXPORT Future : public FutureBase
115{
116private:
117 friend Internal::Promise<T>;
118
119 struct Impl : public ImplBase
120 {
121 T value = T{};
122 };
123
124 static Future CreateByPromise();
125
126public:
130 Future() = default;
131 Future(const Future& other) = default;
132 Future(Future&& other) noexcept = default;
133 ~Future() override = default;
134
135 Future& operator=(const Future& other) = default;
136 Future& operator=(Future&& other) noexcept = default;
137
141 const T GetValue() const;
142
143private:
144 void SetValue(const T& value);
145
146 Impl& GetPImpl() override
147 {
148 return *(this->pImpl);
149 }
150
151 const Impl& GetPImpl() const override
152 {
153 return *(this->pImpl);
154 }
155
156private:
157 std::shared_ptr<Impl> pImpl{std::make_shared<Impl>()};
158};
159
160
161template<typename T>
162Future<T> Future<T>::CreateByPromise()
163{
164 Future result;
165 result.pImpl->isCreatedByPromise = true;
166 return result;
167}
168
169
170template<typename T>
171const T Future<T>::GetValue() const
172{
173 this->CheckForValueAndException();
174 return this->GetPImpl().value;
175}
176
177
178template<typename T>
179void Future<T>::SetValue(const T& value)
180{
181 this->GetPImpl().value = value;
182 this->GetPImpl().valueHasBeenSet.store(true);
183}
184
185
186// -----------------------------------------------------------------------------
187
188
190template<>
191class ARP_CXX_SYMBOL_EXPORT Future<void> : public FutureBase
192{
193private:
194 friend Internal::Promise<void>;
195 using Impl = ImplBase;
196
197 static Future CreateByPromise();
198
199public:
204
205 Future(const Future& other) = default;
206 Future(Future&& other) = default;
207 ~Future() override = default;
208
209 Future& operator=(const Future& other) = default;
210 Future& operator=(Future&& other) = default;
211
216 void GetValue() const;
217
218private:
219 void SetValue();
220
221 Impl& GetPImpl() override;
222 const Impl& GetPImpl() const override;
223
224private:
225 std::shared_ptr<Impl> pImpl;
226};
227
228
229}}} // end of namespace Arp::System::Nm
Base class with common behavior for Future<T> and Future<void>
Definition: Future.hpp:28
const bool HasValue() const
Returns true, if a value or an exception has been set
const bool HasException() const
Returns true, if an exception has been set
const bool IsValid() const
Returns true, if this Future has an assiciated Promise
Future()
Constructs an invalid Future
void GetValue() const
Gets the void result of the asynchronous function call
Future object as proxy for return value an asynchronous function call
Definition: Future.hpp:115
const T GetValue() const
Returns the value set by the associated Promise
Definition: Future.hpp:171
Future()=default
Constructs an invalid Future
Root namespace for the PLCnext API