ORIGINAL
Loading...
Searching...
No Matches
async.h
1#ifndef ORIGINAL_ASYNC_H
2#define ORIGINAL_ASYNC_H
3
4#include "atomic.h"
5#include "condition.h"
6#include "optional.h"
7#include "refCntPtr.h"
8#include "thread.h"
9#include <exception>
10#include <functional>
11#include <utility>
12
13namespace original {
14
21 class async {
22 // ==================== Async Wrapper (Internal) ====================
23
30 template<typename TYPE>
31 class asyncWrapper {
32 atomic<bool> ready_{makeAtomic(false)};
33 strongPtr<TYPE> result_;
34 mutable pCondition cond_{};
35 mutable pMutex mutex_{};
36 std::exception_ptr e_{};
37
38 public:
39 asyncWrapper();
40
45 void setValue(TYPE&& v);
46
51 void setException(std::exception_ptr e);
52
57 [[nodiscard]] bool ready() const;
58
62 void wait() const;
63
69 bool waitFor(time::duration timeout) const;
70
76 TYPE get();
77
83 const TYPE& peek() const;
84
89 strongPtr<TYPE> getPtr() const;
90
94 void rethrowIfException() const;
95
100 [[nodiscard]] std::exception_ptr exception() const;
101 };
102
103 public:
118 public:
123 [[nodiscard]] virtual bool valid() const noexcept = 0;
124
128 virtual void wait() const = 0;
129
135 [[nodiscard]] virtual bool waitFor(time::duration timeout) const = 0;
136
142
147 [[nodiscard]] virtual bool ready() const = 0;
148
150 };
151
152 // ==================== Future Class ====================
153
156
167
168 friend class async;
170
171 public:
172 future() = default;
173
174 // Disable copying
175 future(const future&) = delete;
176 future& operator=(const future&) = delete;
177
178 // Allow moving
179 future(future&&) = default;
180 future& operator=(future&&) = default;
181
186 [[nodiscard]] bool valid() const noexcept override;
187
192 sharedFuture<TYPE> share();
193
199 TYPE result();
200
205 [[nodiscard]] bool ready() const override;
206
211 [[nodiscard]] std::exception_ptr exception() const noexcept override;
212
216 void wait() const override;
217
223 [[nodiscard]] bool waitFor(time::duration timeout) const override;
224 };
225
234 template<typename TYPE>
235 class sharedFuture final : public futureBase, public hashable<sharedFuture<TYPE>> {
237
238 friend class async;
240
241 public:
242 sharedFuture() = default;
243
244 // Allow copying and moving
245 sharedFuture(const sharedFuture&) = default;
246 sharedFuture& operator=(const sharedFuture&) = default;
247 sharedFuture(sharedFuture&&) = default;
248 sharedFuture& operator=(sharedFuture&&) = default;
249
254 [[nodiscard]] bool valid() const noexcept override;
255
261 TYPE result() const;
262
275 [[nodiscard]] strongPtr<const TYPE> strongPointer() const;
276
281 [[nodiscard]] bool ready() const override;
282
287 [[nodiscard]] std::exception_ptr exception() const noexcept override;
288
294 bool operator==(const sharedFuture& other) const noexcept;
295
301 bool operator!=(const sharedFuture& other) const noexcept;
302
306 void wait() const override;
307
313 [[nodiscard]] bool waitFor(time::duration timeout) const override;
314
319 [[nodiscard]] u_integer toHash() const noexcept override;
320
326 bool equals(const sharedFuture& other) const noexcept override;
327
328 ~sharedFuture() override = default;
329 };
330
331 // ==================== Promise Class ====================
332
348 template<typename TYPE, typename Callback>
349 class promise {
350 std::function<TYPE()> c_{};
352 bool valid_{false};
353
354 public:
355 // Disable copying to prevent multiple executions of the same computation
356 promise(const promise&) = delete;
357 promise& operator=(const promise&) = delete;
358
359 // Allow moving to transfer ownership of the computation
360 promise(promise&& other) noexcept;
361
362 promise& operator=(promise&& other) noexcept;
363
369 promise() = default;
370
377 explicit promise(Callback&& c);
378
386
396
407 std::function<TYPE()> function();
408
418 void run();
419 };
420
421 // ==================== Static Factory Methods ====================
422
434 static auto makePromise(Callback&& c, Args&&... args);
435
446 };
447
461 auto operator|(async::future<T> f, Callback&& c);
462
475 auto operator|(async::future<void> f, Callback&& c);
476
491
505
528
547 auto operator|(async::promise<void, Callback1> p, Callback2&& c);
548
549
550 // ==================== Void Specializations ====================
551
555 template <>
556 class async::asyncWrapper<void> {
557 atomic<bool> ready_{makeAtomic(false)};
558 alternative<void> result_;
559 mutable pCondition cond_{};
560 mutable pMutex mutex_{};
561 std::exception_ptr e_{};
562
563 public:
564 asyncWrapper() = default;
565
569 void setValue();
570
575 void setException(std::exception_ptr e);
576
581 [[nodiscard]] bool ready() const;
582
586 void wait() const;
587
593 bool waitFor(const time::duration& timeout) const;
594
599 void get();
600
605 void peek() const;
606
611 void rethrowIfException() const;
612
617 [[nodiscard]] std::exception_ptr exception() const noexcept;
618 };
619
623 template <>
626
627 friend class async;
629
630 public:
631 future() = default;
632
633 // Disable copying
634 future(const future&) = delete;
635 future& operator=(const future&) = delete;
636
637 // Allow moving
638 future(future&&) = default;
639 future& operator=(future&&) = default;
640
645 [[nodiscard]] bool valid() const noexcept override;
646
651 sharedFuture<void> share();
652
657 void result();
658
663 [[nodiscard]] bool ready() const override;
664
669 [[nodiscard]] std::exception_ptr exception() const noexcept override;
670
674 void wait() const override;
675
681 [[nodiscard]] bool waitFor(time::duration timeout) const override;
682 };
683
684 template <>
685 class async::sharedFuture<void> final : public futureBase, public hashable<sharedFuture<void>> {
687
688 friend class async;
690
691 public:
692 sharedFuture() = default;
693
694 // Allow copying and moving
695 sharedFuture(const sharedFuture&) = default;
696 sharedFuture& operator=(const sharedFuture&) = default;
697 sharedFuture(sharedFuture&&) = default;
698 sharedFuture& operator=(sharedFuture&&) = default;
699
704 [[nodiscard]] bool valid() const noexcept override;
705
710 void result() const;
711
716 [[nodiscard]] bool ready() const override;
717
722 [[nodiscard]] std::exception_ptr exception() const noexcept override;
723
729 bool operator==(const sharedFuture& other) const noexcept;
730
736 bool operator!=(const sharedFuture& other) const noexcept;
737
741 void wait() const override;
742
748 [[nodiscard]] bool waitFor(time::duration timeout) const override;
749
754 [[nodiscard]] u_integer toHash() const noexcept override;
755
761 [[nodiscard]] bool equals(const sharedFuture& other) const noexcept override;
762
763 ~sharedFuture() override = default;
764 };
765
771 template <typename Callback>
773 std::function<void()> c_{};
775 bool valid_{false};
776
777 public:
778 // Disable copying to prevent multiple executions of the same computation
779 promise(const promise&) = delete;
780 promise& operator=(const promise&) = delete;
781
782 // Allow moving to transfer ownership of the computation
783 promise(promise&& other) noexcept;
784
785 promise& operator=(promise&& other) noexcept;
786
790 promise() = default;
791
796 explicit promise(Callback&& c);
797
802 [[nodiscard]] future<void> getFuture() const;
803
808 [[nodiscard]] bool valid() const noexcept;
809
815 std::function<void()> function();
816
822 void run();
823 };
824} // namespace original
825
827original::async::asyncWrapper<TYPE>::asyncWrapper() = default;
828
830void original::async::asyncWrapper<TYPE>::setValue(TYPE&& v)
831{
832 {
833 uniqueLock lock{this->mutex_};
834 this->result_ = makeStrongPtr<TYPE>(std::move(v));
835 this->ready_.store(true);
836 }
837 this->cond_.notifyAll();
838}
839
840template <typename TYPE>
841void original::async::asyncWrapper<TYPE>::setException(std::exception_ptr e)
842{
843 {
844 uniqueLock lock{this->mutex_};
845 this->e_ = std::move(e);
846 this->ready_.store(true);
847 }
848 this->cond_.notifyAll();
849}
850
851template <typename TYPE>
852bool original::async::asyncWrapper<TYPE>::ready() const
853{
854 return *this->ready_;
855}
856
857template <typename TYPE>
858void original::async::asyncWrapper<TYPE>::wait() const
859{
860 uniqueLock lock{this->mutex_};
861 this->cond_.wait(this->mutex_, [this]
862 {
863 return this->ready();
864 });
865}
866
867template <typename TYPE>
868bool original::async::asyncWrapper<TYPE>::waitFor(time::duration timeout) const
869{
870 uniqueLock lock{this->mutex_};
871 return this->cond_.waitFor(this->mutex_, timeout, [this]
872 {
873 return this->ready();
874 });
875}
876
877template <typename TYPE>
878TYPE original::async::asyncWrapper<TYPE>::get()
879{
880 uniqueLock lock{this->mutex_};
881 this->cond_.wait(this->mutex_, [this]{
882 return this->ready();
883 });
884
885 this->rethrowIfException();
886
887 TYPE result = std::move(*this->result_);
888 this->result_.reset();
889 return result;
890}
891
892template <typename TYPE>
893const TYPE& original::async::asyncWrapper<TYPE>::peek() const
894{
895 uniqueLock lock{this->mutex_};
896 this->cond_.wait(this->mutex_, [this]{
897 return this->ready();
898 });
899
900 this->rethrowIfException();
901 return *this->result_;
902}
903
904template <typename TYPE>
905original::strongPtr<TYPE> original::async::asyncWrapper<TYPE>::getPtr() const
906{
907 this->rethrowIfException();
908 return this->result_;
909}
910
911template <typename TYPE>
912void original::async::asyncWrapper<TYPE>::rethrowIfException() const
913{
914 if (this->e_)
915 std::rethrow_exception(this->e_);
916}
917
918template <typename TYPE>
919std::exception_ptr
920original::async::asyncWrapper<TYPE>::exception() const
921{
922 uniqueLock lock{this->mutex_};
923 return this->e_;
924}
925
926template <typename TYPE>
927original::async::future<TYPE>::future(strongPtr<asyncWrapper<TYPE>> awr)
928 : awr_(std::move(awr)) {}
929
930template <typename TYPE>
932{
933 return this->awr_ != nullptr;
934}
935
936template <typename TYPE>
941
942
943template <typename TYPE>
945{
946 if (!this->valid()) {
947 throw sysError("Access an invalid future");
948 }
949 return this->awr_->get();
950}
951
952template <typename TYPE>
954{
955 if (!this->valid()) {
956 throw sysError("Access an invalid future");
957 }
958 return this->awr_->ready();
959}
960
961template <typename TYPE>
963{
964 if (!this->valid()) {
965 return {};
966 }
967 return this->awr_->exception();
968}
969
970template <typename TYPE>
972{
973 if (!this->valid()) {
974 throw sysError("Access an invalid future");
975 }
976 this->awr_->wait();
977}
978
979template <typename TYPE>
981{
982 if (!this->valid()) {
983 throw sysError("Access an invalid future");
984 }
985 return this->awr_->waitFor(timeout);
986}
987
988template <typename TYPE>
990 : awr_(std::move(awr)) {}
991
992template <typename TYPE>
994{
995 return this->awr_ != nullptr;
996}
997
998template <typename TYPE>
1000{
1001 if (!this->valid()) {
1002 throw sysError("Access an invalid sharedFuture");
1003 }
1004 return this->awr_->peek();
1005}
1006
1007template <typename TYPE>
1009{
1010 if (!this->valid()) {
1011 throw sysError("Access an invalid sharedFuture");
1012 }
1013 if (!this->ready()) {
1014 throw sysError("Cannot get a strongPtr from a sharedFuture that is not ready");
1015 }
1016 return this->awr_->getPtr().template constCastTo<const TYPE>();
1017}
1018
1019template <typename TYPE>
1021{
1022 if (!this->valid()) {
1023 throw sysError("Access an invalid sharedFuture");
1024 }
1025 return this->awr_->ready();
1026}
1027
1028template <typename TYPE>
1030{
1031 if (!this->valid()) {
1032 return {};
1033 }
1034 return this->awr_->exception();
1035}
1036
1037template <typename TYPE>
1039{
1040 return this->awr_ == other.awr_;
1041}
1042
1043template <typename TYPE>
1045{
1046 return this->awr_ != other.awr_;
1047}
1048
1049template <typename TYPE>
1051{
1052 if (!this->valid()) {
1053 throw sysError("Access an invalid sharedFuture");
1054 }
1055 this->awr_->wait();
1056}
1057
1058template <typename TYPE>
1060{
1061 if (!this->valid()) {
1062 throw sysError("Access an invalid sharedFuture");
1063 }
1064 return this->awr_->waitFor(timeout);
1065}
1066
1067template <typename TYPE>
1072
1073template <typename TYPE>
1075{
1076 return *this == other;
1077}
1078
1079template <typename TYPE, typename Callback>
1081{
1082 if (!other.valid()){
1083 return;
1084 }
1085 this->valid_ = true;
1086 this->c_ = std::move(other.c_);
1087 this->awr_ = std::move(other.awr_);
1088 other.valid_ = false;
1089}
1090
1091template <typename TYPE, typename Callback>
1094{
1095 if (this == &other || !other.valid()) {
1096 return *this;
1097 }
1098 this->valid_ = true;
1099 this->c_ = std::move(other.c_);
1100 this->awr_ = std::move(other.awr_);
1101 other.valid_ = false;
1102 return *this;
1103}
1104
1105template <typename TYPE, typename Callback>
1108
1109template <typename TYPE, typename Callback>
1115
1116template <typename TYPE, typename Callback>
1118{
1119 return this->valid_;
1120}
1121
1122template <typename TYPE, typename Callback>
1124{
1125 if (!this->valid_) {
1126 throw sysError("Try to get an invalid task");
1127 }
1128 this->valid_ = false;
1129 return std::move(this->c_);
1130}
1131
1132template <typename TYPE, typename Callback>
1134{
1135 if (!this->valid_) {
1136 throw sysError("Try to run an invalid task");
1137 }
1138 try {
1139 this->awr_->setValue(this->c_());
1140 } catch (...) {
1141 this->awr_->setException(std::current_exception());
1142 }
1143 this->valid_ = false;
1144}
1145
1146template <typename Callback, typename... Args>
1148 using Return = std::invoke_result_t<Callback, Args...>;
1149 auto bound = [c = std::forward<Callback>(c),
1150 ... args = std::forward<Args>(args)]() mutable -> Return {
1151 return c(args...);
1152 };
1153
1154 return promise<Return, decltype(bound)>{std::move(bound)};
1155}
1156
1157template <typename Callback, typename ... Args>
1159 -> future<std::invoke_result_t<std::decay_t<Callback>, std::decay_t<Args>...>>
1160{
1161 auto p = makePromise(std::forward<Callback>(c), std::forward<Args>(args)...);
1162 auto fut = p.getFuture();
1163
1164 auto p_shared = makeStrongPtr<decltype(p)>(std::move(p));
1165 thread t{
1166 [p_shared]() mutable {
1167 p_shared->run();
1168 },
1170 };
1171
1172 return fut;
1173}
1174
1175template <typename T, typename Callback>
1177{
1178 using ResultType = std::invoke_result_t<Callback, T>;
1180 return async::get([shared_f, c = std::forward<Callback>(c)] mutable -> ResultType {
1181 return c(shared_f->result());
1182 });
1183}
1184
1185template <typename Callback>
1187{
1188 using ResultType = std::invoke_result_t<Callback>;
1190 return async::get([shared_f, c = std::forward<Callback>(c)]() mutable -> ResultType {
1191 shared_f->result();
1192 return c();
1193 });
1194}
1195
1196template <typename T, typename Callback>
1198{
1199 using ResultType = std::invoke_result_t<Callback, T>;
1200 return async::get([sf, c = std::forward<Callback>(c)] mutable -> ResultType {
1201 return c(sf.result());
1202 }).share();
1203}
1204
1205template <typename Callback>
1207{
1208 using ResultType = std::invoke_result_t<Callback>;
1209 return async::get([sf, c = std::forward<Callback>(c)]() mutable -> ResultType {
1210 sf.result();
1211 return c();
1212 }).share();
1213}
1214
1215template <typename T, typename Callback1, typename Callback2>
1217{
1218 if (!p.valid()) {
1219 throw sysError("Try to build a lazy pipeline from an invalid promise");
1220 }
1221 using ResultType = decltype(c(std::declval<T>()));
1223 return async::makePromise([shared_p, c = std::forward<Callback2>(c)]() mutable -> ResultType {
1224 return c(shared_p->function()());
1225 });
1226}
1227
1228template <typename Callback1, typename Callback2>
1230{
1231 if (!p.valid()) {
1232 throw sysError("Try to build a lazy pipeline from an invalid promise");
1233 }
1234 using ResultType = decltype(c());
1236 return async::makePromise([shared_p, c = std::forward<Callback2>(c)]() mutable -> ResultType {
1237 shared_p->function()();
1238 return c();
1239 });
1240}
1241
1242inline void original::async::asyncWrapper<void>::setValue()
1243{
1244 {
1245 uniqueLock lock{this->mutex_};
1246 this->result_.set();
1247 this->ready_.store(true);
1248 }
1249 this->cond_.notifyAll();
1250}
1251
1252inline void original::async::asyncWrapper<void>::setException(std::exception_ptr e)
1253{
1254 {
1255 uniqueLock lock{this->mutex_};
1256 this->e_ = std::move(e);
1257 this->ready_.store(true);
1258 }
1259 this->cond_.notifyAll();
1260}
1261
1262inline bool original::async::asyncWrapper<void>::ready() const
1263{
1264 return *this->ready_;
1265}
1266
1267inline void original::async::asyncWrapper<void>::wait() const
1268{
1269 uniqueLock lock{this->mutex_};
1270 this->cond_.wait(this->mutex_, [this]
1271 {
1272 return this->ready();
1273 });
1274}
1275
1276inline bool original::async::asyncWrapper<void>::waitFor(const time::duration& timeout) const
1277{
1278 uniqueLock lock{this->mutex_};
1279 return this->cond_.waitFor(this->mutex_, timeout, [this]
1280 {
1281 return this->ready();
1282 });
1283}
1284
1285inline void original::async::asyncWrapper<void>::get()
1286{
1287 uniqueLock lock{this->mutex_};
1288 this->cond_.wait(this->mutex_, [this] {
1289 return this->ready();
1290 });
1291
1292 this->rethrowIfException();
1293 this->result_.reset();
1294}
1295
1296inline void original::async::asyncWrapper<void>::peek() const
1297{
1298 uniqueLock lock{this->mutex_};
1299 this->cond_.wait(this->mutex_, [this] {
1300 return this->ready();
1301 });
1302
1303 this->rethrowIfException();
1304}
1305
1306inline void original::async::asyncWrapper<void>::rethrowIfException() const
1307{
1308 if (this->e_)
1309 std::rethrow_exception(this->e_);
1310}
1311
1312inline std::exception_ptr
1313original::async::asyncWrapper<void>::exception() const noexcept
1314{
1315 uniqueLock lock{this->mutex_};
1316 return this->e_;
1317}
1318
1320 : awr_(std::move(awr)) {}
1321
1323{
1324 return this->awr_ != nullptr;
1325}
1326
1328{
1329 return sharedFuture(std::move(this->awr_));
1330}
1331
1333{
1334 if (!this->valid()) {
1335 throw sysError("Access an invalid future");
1336 }
1337 this->awr_->get();
1338}
1339
1341{
1342 if (!this->valid()) {
1343 throw sysError("Access an invalid future");
1344 }
1345 return this->awr_->ready();
1346}
1347
1349{
1350 if (!this->valid()) {
1351 return {};
1352 }
1353 return this->awr_->exception();
1354}
1355
1357{
1358 if (!this->valid()) {
1359 throw sysError("Access an invalid future");
1360 }
1361 this->awr_->wait();
1362}
1363
1365{
1366 if (!this->valid()) {
1367 throw sysError("Access an invalid future");
1368 }
1369 return this->awr_->waitFor(timeout);
1370}
1371
1373 : awr_(std::move(awr)) {}
1374
1376{
1377 return this->awr_ != nullptr;
1378}
1379
1381{
1382 if (!this->valid()) {
1383 throw sysError("Access an invalid sharedFuture");
1384 }
1385 this->awr_->peek();
1386}
1387
1389{
1390 if (!this->valid()) {
1391 throw sysError("Access an invalid sharedFuture");
1392 }
1393 return this->awr_->ready();
1394}
1395
1397{
1398 if (!this->valid()) {
1399 return {};
1400 }
1401 return this->awr_->exception();
1402}
1403
1405{
1406 return this->awr_ == other.awr_;
1407}
1408
1410{
1411 return this->awr_ != other.awr_;
1412}
1413
1414
1416{
1417 if (!this->valid()) {
1418 throw sysError("Access an invalid sharedFuture");
1419 }
1420 this->awr_->wait();
1421}
1422
1424{
1425 if (!this->valid()) {
1426 throw sysError("Access an invalid sharedFuture");
1427 }
1428 return this->awr_->waitFor(timeout);
1429}
1430
1435
1437{
1438 return *this == other;
1439}
1440
1441template <typename Callback>
1443{
1444 if (!other.valid()){
1445 return;
1446 }
1447 this->valid_ = true;
1448 this->c_ = std::move(other.c_);
1449 this->awr_ = std::move(other.awr_);
1450 other.valid_ = false;
1451}
1452
1453template <typename Callback>
1455{
1456 if (this == &other || !other.valid()) {
1457 return *this;
1458 }
1459 this->valid_ = true;
1460 this->c_ = std::move(other.c_);
1461 this->awr_ = std::move(other.awr_);
1462 other.valid_ = false;
1463 return *this;
1464}
1465
1466template <typename Callback>
1469
1470template <typename Callback>
1475
1476template <typename Callback>
1478{
1479 return this->valid_;
1480}
1481
1482template <typename Callback>
1484{
1485 if (!this->valid_) {
1486 throw sysError("Try to get an invalid task");
1487 }
1488 this->valid_ = false;
1489 return std::move(this->c_);
1490}
1491
1492template <typename Callback>
1494{
1495 if (!this->valid_) {
1496 throw sysError("Try to run an invalid task");
1497 }
1498 try {
1499 this->c_();
1500 this->awr_->setValue();
1501 } catch (...) {
1502 this->awr_->setException(std::current_exception());
1503 }
1504 this->valid_ = false;
1505}
1506
1507#endif // ORIGINAL_ASYNC_H
Abstract base interface for asynchronous consumers.
Definition async.h:117
virtual bool waitFor(time::duration timeout) const =0
Waits for the result with a timeout.
virtual void wait() const =0
Waits until the result becomes ready.
virtual bool ready() const =0
Checks if the result is ready.
virtual std::exception_ptr exception() const noexcept=0
Gets the stored exception if computation failed.
virtual bool valid() const noexcept=0
Checks if the future is valid (has an associated async wrapper)
Represents a one-shot future result of an asynchronous computation.
Definition async.h:165
bool ready() const override
Checks if the result is ready.
Definition async.h:953
std::exception_ptr exception() const noexcept override
Gets the exception if computation failed.
Definition async.h:962
sharedFuture< TYPE > share()
Converts this future to a shared future.
Definition async.h:937
bool valid() const noexcept override
Checks if the future is valid (has an associated async wrapper)
Definition async.h:931
TYPE result()
Gets the result (blocks until ready)
Definition async.h:944
bool waitFor(time::duration timeout) const override
Waits for the result with a timeout.
Definition async.h:980
void wait() const override
Waits until the result becomes ready.
Definition async.h:971
promise()=default
Default constructor creates an invalid promise.
Represents a one-time asynchronous producer with result setting capability.
Definition async.h:349
promise()=default
Default constructor creates an invalid promise.
bool valid() const noexcept
Checks if the promise is still valid (can be executed or have function extracted)
Definition async.h:1117
std::function< TYPE()> function()
Extracts the computation function from the promise.
Definition async.h:1123
promise(Callback &&c)
Constructs a promise with a computation callback.
Definition async.h:1106
future< TYPE > getFuture()
Gets the future associated with this promise.
Definition async.h:1111
void run()
Executes the computation and sets the result in the associated future.
Definition async.h:1133
Represents a sharable asynchronous result.
Definition async.h:235
bool valid() const noexcept override
Checks if the shared future is valid (has an associated async wrapper)
Definition async.h:993
TYPE result() const
Gets the result value (blocks until ready)
Definition async.h:999
u_integer toHash() const noexcept override
Generates a hash value for the shared future.
Definition async.h:1068
std::exception_ptr exception() const noexcept override
Gets the exception if computation failed.
Definition async.h:1029
bool equals(const sharedFuture &other) const noexcept override
Checks if two shared futures are equal.
Definition async.h:1074
void wait() const override
Waits until the result becomes ready.
Definition async.h:1050
strongPtr< const TYPE > strongPointer() const
Gets a strong pointer to the result value.
Definition async.h:1008
bool ready() const override
Checks if the result is ready.
Definition async.h:1020
bool waitFor(time::duration timeout) const override
Waits for the result with a timeout.
Definition async.h:1059
bool operator!=(const sharedFuture &other) const noexcept
Inequality comparison operator.
Definition async.h:1044
bool operator==(const sharedFuture &other) const noexcept
Equality comparison operator.
Definition async.h:1038
Asynchronous programming utilities with future/promise pattern.
Definition async.h:21
static auto get(Callback &&c, Args &&... args) -> future< std::invoke_result_t< std::decay_t< Callback >, std::decay_t< Args >... > >
Executes a callable asynchronously and returns a future for the result.
Definition async.h:1158
static auto makePromise(Callback &&c, Args &&... args)
Creates a promise from a callable and arguments.
Definition async.h:1147
u_integer toHash() const noexcept override
Compute hash value for the pointer.
Definition autoPtr.h:735
Forward declaration of hashable interface template.
Definition hash.h:220
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
POSIX condition variable implementation.
Definition condition.h:129
POSIX thread mutex implementation.
Definition mutex.h:153
Shared ownership smart pointer with strong references.
Definition refCntPtr.h:108
Exception for generic system failure.
Definition error.h:413
High-level thread wrapper.
Definition thread.h:263
static constexpr auto AUTO_DETACH
Alias for joinPolicy::AUTO_DETACH.
Definition thread.h:305
Represents a time duration with nanosecond precision.
Definition zeit.h:134
Namespace-like class containing time-related utilities.
Definition zeit.h:40
RAII wrapper for single mutex locking.
Definition mutex.h:216
Condition variable implementation for thread synchronization.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:263
Main namespace for the project Original.
Definition algorithms.h:21
bool operator!=(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Inequality comparison with nullptr.
Definition autoPtr.h:755
bool operator==(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Equality comparison with nullptr.
Definition autoPtr.h:750
strongPtr< T, DEL > makeStrongPtr(Args &&... args)
Creates a new strongPtr managing a shared object.
Definition refCntPtr.h:633
bitSet< ALLOC_ > operator|(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Bitwise OR operator for two bitSets.
Standard namespace extensions for original::alternative.
Definition allocator.h:351
Type-safe optional value container.
Reference-counted smart pointer hierarchy.
Thread management utilities.