PLCnext API Documentation 23.0.2.9
Future.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6
7#pragma once
8
9#include "Arp/System/Core/Exception.hpp"
10#include "Arp/System/Core/TypeName.hxx"
11#include <atomic>
12#include <memory>
13
14
15namespace Arp { namespace System { namespace Nm { namespace Internal
16{
17template<typename T>
20class Promise;
21} // namespace Internal
22
23
24// <summary>Proxy for the result of an asynchronous function call</summary>
27{
28protected:
31 class IExceptionWrapper
32 {
33 public:
34 virtual ~IExceptionWrapper() = default;
35 virtual void ReThrowException() = 0;
36 };
37
38
41 template<typename ExceptionType>
42 class ExceptionWrapper : public IExceptionWrapper
43 {
44 public:
45 explicit ExceptionWrapper(const ExceptionType& e) : exception(e)
46 {
47 }
48
49 ~ExceptionWrapper() override = default;
50
51 void ReThrowException() override
52 {
53 throw this->exception;
54 }
55
56 private:
57 ExceptionType exception;
58 };
59
60
63 struct ImplBase
64 {
65 bool isCreatedByPromise = false;
66 std::atomic<bool> valueHasBeenSet;
67 std::unique_ptr<IExceptionWrapper> exception;
68 };
69
70public:
71 FutureBase() = default;
72 FutureBase(const FutureBase& other) = default;
73 FutureBase(FutureBase&& other) noexcept = default;
74 virtual ~FutureBase();
75
76 FutureBase& operator=(const FutureBase& other) = default;
77 FutureBase& operator=(FutureBase&& other) noexcept = default;
78
80 const bool IsValid() const;
81
83 const bool HasValue() const;
84
86 const bool HasException() const;
87
88protected:
89 virtual ImplBase& GetPImpl() = 0;
90 virtual const ImplBase& GetPImpl() const = 0;
91 void CheckForValueAndException() const;
92
93 template<typename ExceptionType>
94 void SetException(const ExceptionType& e);
95
96 void Clear(bool isValid);
97};
98
99
100template<typename ExceptionType>
101void FutureBase::SetException(const ExceptionType& e)
102{
103 this->GetPImpl().exception = std::make_unique<ExceptionWrapper<ExceptionType>>(e);
104 this->GetPImpl().valueHasBeenSet.store(true);
105}
106
107
108// -----------------------------------------------------------------------------
109
110
112template<typename T>
113class Future : public FutureBase
114{
115private:
116 friend Internal::Promise<T>;
117
118 struct Impl : public ImplBase
119 {
120 T value = T{};
121 };
122
123 static Future CreateByPromise();
124
125public:
129 Future() = default;
130 Future(const Future& other) = default;
131 Future(Future&& other) noexcept = default;
132 ~Future() override = default;
133
134 Future& operator=(const Future& other) = default;
135 Future& operator=(Future&& other) noexcept = default;
136
140 const T GetValue() const;
141
142private:
143 void SetValue(const T& value);
144
145 Impl& GetPImpl() override
146 {
147 return *(this->pImpl);
148 }
149
150 const Impl& GetPImpl() const override
151 {
152 return *(this->pImpl);
153 }
154
155private:
156 std::shared_ptr<Impl> pImpl{std::make_shared<Impl>()};
157};
158
159
160template<typename T>
161Future<T> Future<T>::CreateByPromise()
162{
163 Future result;
164 result.pImpl->isCreatedByPromise = true;
165 return result;
166}
167
168
169template<typename T>
170const T Future<T>::GetValue() const
171{
172 this->CheckForValueAndException();
173 return this->GetPImpl().value;
174}
175
176
177template<typename T>
178void Future<T>::SetValue(const T& value)
179{
180 this->GetPImpl().value = value;
181 this->GetPImpl().valueHasBeenSet.store(true);
182}
183
184
185// -----------------------------------------------------------------------------
186
187
189template<>
190class Future<void> : public FutureBase
191{
192private:
193 friend Internal::Promise<void>;
194 using Impl = ImplBase;
195
196 static Future CreateByPromise();
197
198public:
203
204 Future(const Future& other) = default;
205 Future(Future&& other) = default;
206 ~Future() override = default;
207
208 Future& operator=(const Future& other) = default;
209 Future& operator=(Future&& other) = default;
210
215 void GetValue() const;
216
217private:
218 void SetValue();
219
220 Impl& GetPImpl() override;
221 const Impl& GetPImpl() const override;
222
223private:
224 std::shared_ptr<Impl> pImpl;
225};
226
227
228}}} // end of namespace Arp::System::Nm
Base class with common behavior for Future<T> and Future<void>
Definition: Future.hpp:27
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:114
const T GetValue() const
Returns the value set by the associated Promise
Definition: Future.hpp:170
Future()=default
Constructs an invalid Future
@ System
System components used by the System, Device, Plc or Io domains.
Root namespace for the PLCnext API