nlib
Future.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_THREADING_FUTURE_H_
17 #define INCLUDE_NN_NLIB_THREADING_FUTURE_H_
18 
19 #include <utility>
20 
21 #include "nn/nlib/Swap.h"
22 #include "nn/nlib/UniquePtr.h"
23 #include "nn/nlib/DateTime.h"
24 #include "nn/nlib/TypeTraits.h"
26 #include "nn/nlib/threading/LimitedSharedPtr.h"
28 
29 NLIB_NAMESPACE_BEGIN
30 class TimeSpan;
31 class DateTime;
32 namespace threading {
33 
34 template<class FutureResult>
35 inline errno_t GetFutureError(FutureResult& result) NLIB_NOEXCEPT {
36  NLIB_UNUSED(result);
37  return 0;
38 }
39 
40 template<class R>
41 class Future;
42 template<class R>
43 class Promise;
44 
45 namespace detail {
46 
47 class NLIB_VIS_PUBLIC FutureContinuationBase {
48  public:
49  FutureContinuationBase() NLIB_NOEXCEPT {}
50  virtual ~FutureContinuationBase() NLIB_NOEXCEPT {}
51  virtual void DoContinuation() {}
52 
53  private:
54  NLIB_DISALLOW_COPY_AND_ASSIGN(FutureContinuationBase);
55 };
56 
57 template<class FUTURE, class R, typename CONT>
58 class FutureContinuation;
59 
60 template<class Derived>
61 class FutureBase {
62  public:
63  FutureBase() NLIB_NOEXCEPT {}
64 #ifdef __cpp_rvalue_references
65 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
66  FutureBase(FutureBase&& rhs) = default;
67  FutureBase& operator=(FutureBase&& rhs) = default;
68 #endif
69 #endif
70  FutureBase(FutureBase&, move_tag) NLIB_NOEXCEPT {}
71  FutureBase& assign(FutureBase&, move_tag) NLIB_NOEXCEPT { return *this; }
72  errno_t Wait() NLIB_NOEXCEPT;
73  NLIB_CHECK_RESULT errno_t WaitFor(const TimeSpan& span) NLIB_NOEXCEPT;
74  NLIB_CHECK_RESULT errno_t WaitUntil(const DateTime& datetime) NLIB_NOEXCEPT;
75  bool IsValid() const NLIB_NOEXCEPT {
76  const Derived& ref = static_cast<const Derived&>(*this);
77  return !!ref.value_; // for explicit operator bool
78  }
79  bool IsReady() const NLIB_NOEXCEPT;
80  errno_t MakeSharedFrom(const Derived& f) NLIB_NOEXCEPT {
81  Derived& ref = static_cast<Derived&>(*this);
82  return ref.value_.MakeSharedFrom(f.value_);
83  }
84  template<class R>
85  errno_t Then(Future<R>* next, R (*cont)(Derived&)) NLIB_NOEXCEPT;
86 
87  private:
88  bool IsReady_() const NLIB_NOEXCEPT {
89  return static_cast<const Derived&>(*this).value_->common.IsReady();
90  }
91 };
92 
93 template<class Derived>
94 bool FutureBase<Derived>::IsReady() const NLIB_NOEXCEPT {
95  const Derived& ref = static_cast<const Derived&>(*this);
96  if (ref.value_) {
97  ref.value_->common.Lock();
98  bool rval = IsReady_();
99  ref.value_->common.Unlock();
100  return rval;
101  } else {
102  return false;
103  }
104 }
105 
106 template<class Derived>
107 errno_t FutureBase<Derived>::Wait() NLIB_NOEXCEPT {
108  Derived& ref = static_cast<Derived&>(*this);
109  NLIB_ASSERT(ref.value_);
110  if (!ref.value_) return EINVAL;
111  ref.value_->common.Lock();
112  while (!IsReady_()) {
113  errno_t e = ref.value_->common.Wait();
114  if (e != 0) {
115  ref.value_->common.Unlock();
116  NLIB_ASSERT_NOERR(e);
117  return e;
118  }
119  }
120  ref.value_->common.Unlock();
121  return 0;
122 }
123 
124 template<class Derived>
125 errno_t FutureBase<Derived>::WaitFor(const TimeSpan& span) NLIB_NOEXCEPT {
126  Derived& ref = static_cast<Derived&>(*this);
127  NLIB_ASSERT(ref.value_);
128  if (!ref.value_) return EINVAL;
129  DateTime abstime;
130  errno_t e = DateTime::GetNow(&abstime);
131  abstime += span;
132  if (e != 0) return e;
133  ref.value_->common.Lock();
134  while (!IsReady_()) {
135  // NOTE:
136  // Because of spurious wakeup, WaitUntil is better than WaitFor.
137  // Also note that CAFE's nlib_cond_wait_for
138  // always makes spurious wakeup and returns 0 if duration >= 0.
139  // CAFE's nlib_cond_wait_until can return ETIMEDOUT on the other hand.
140  e = nlib_cond_wait_until(&ref.value_->common.cond, &ref.value_->common.lock,
141  abstime.ToTimeValue().tick);
142  if (e != 0) {
143  ref.value_->common.Unlock();
144  return e;
145  }
146  }
147  ref.value_->common.Unlock();
148  return 0;
149 }
150 
151 template<class Derived>
152 errno_t FutureBase<Derived>::WaitUntil(const DateTime& datetime) NLIB_NOEXCEPT {
153  Derived& ref = static_cast<Derived&>(*this);
154  NLIB_ASSERT(ref.value_);
155  if (!ref.value_) return EINVAL;
156  ref.value_->common.Lock();
157  while (!IsReady_()) {
158  errno_t e = nlib_cond_wait_until(&ref.value_->common.cond, &ref.value_->common.lock,
159  datetime.ToTimeValue().tick);
160  if (e != 0) {
161  ref.value_->common.Unlock();
162  return e;
163  }
164  }
165  ref.value_->common.Unlock();
166  return 0;
167 }
168 
169 } // namespace detail
170 
171 namespace detail {
172 template<class Derived>
173 class PromiseBase {
174  public:
175  PromiseBase() NLIB_NOEXCEPT {}
176 #ifdef __cpp_rvalue_references
177 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
178  PromiseBase(PromiseBase&& /* rhs */) = default;
179  PromiseBase& operator=(PromiseBase&&) = default;
180 #endif
181 #endif
182  errno_t Init() NLIB_NOEXCEPT;
183 
184  bool IsValid() const NLIB_NOEXCEPT {
185  const Derived& ref = static_cast<const Derived&>(*this);
186  return !!ref.value_;
187  }
188  errno_t SetError(errno_t e) NLIB_NOEXCEPT;
189  template<class F>
190  errno_t GetFuture(F* p) NLIB_NOEXCEPT;
191 
192  protected:
193  struct NLIB_CAPABILITY("mutex") CommonStatus {
194  int32_t status;
195  detail::FutureContinuationBase* cont;
196  errno_t err;
197  nlib_mutex lock;
198  nlib_cond cond;
199  CommonStatus() NLIB_NOEXCEPT : status(0), cont(NULL), err(0) {
200  errno_t e;
201  NLIB_UNUSED(e);
202  e = nlib_mutex_init(&lock);
203  NLIB_ASSERT_NOERR(e);
204  e = nlib_cond_init(&cond);
205  NLIB_ASSERT_NOERR(e);
206  }
207  ~CommonStatus() NLIB_NOEXCEPT {
208  if (cont) delete cont;
209  errno_t e;
210  NLIB_UNUSED(e);
211  e = nlib_mutex_destroy(&lock);
212  NLIB_ASSERT_NOERR(e);
213  e = nlib_cond_destroy(&cond);
214  NLIB_ASSERT_NOERR(e);
215  }
216  void Lock() NLIB_NOEXCEPT NLIB_ACQUIRE() NLIB_NO_THREAD_SAFETY_ANALYSIS {
217  errno_t e;
218  NLIB_UNUSED(e);
219  e = nlib_mutex_lock(&lock);
220  NLIB_ASSERT_NOERR(e);
221  }
222  void Unlock() NLIB_NOEXCEPT NLIB_RELEASE() NLIB_NO_THREAD_SAFETY_ANALYSIS {
223  errno_t e;
224  NLIB_UNUSED(e);
225  e = nlib_mutex_unlock(&lock);
226  NLIB_ASSERT_NOERR(e);
227  }
228  errno_t Wait() NLIB_NOEXCEPT NLIB_REQUIRES(*this) NLIB_NO_THREAD_SAFETY_ANALYSIS {
229  return nlib_cond_wait(&cond, &lock);
230  }
231  bool IsReady() NLIB_NOEXCEPT { return status == 20120915L; }
232  bool SetReady() NLIB_NOEXCEPT {
233  if (status != 20120915L) {
234  status = 20120915L;
235  return true;
236  } else {
237  return false;
238  }
239  }
240  void NotifyAndContinuation() NLIB_NOEXCEPT {
241  // have to notify all the threads waiting
242  errno_t e = nlib_cond_broadcast(&cond);
243  NLIB_ASSERT_NOERR(e);
244  NLIB_UNUSED(e);
245  if (cont) cont->DoContinuation();
246  }
247  };
248  void NotifyAndContinuation() NLIB_NOEXCEPT {
249  static_cast<Derived&>(*this).value_->common.NotifyAndContinuation();
250  }
251 
252  private:
253  NLIB_DISALLOW_COPY_AND_ASSIGN(PromiseBase);
254 };
255 
256 template<class Derived>
257 errno_t PromiseBase<Derived>::Init() NLIB_NOEXCEPT {
258  // NOTE:
259  // This is not thread safe
260  // Note that Promise<R> itself is not thread safe.
261  Derived& ref = static_cast<Derived&>(*this);
262  if (ref.value_) return EALREADY;
263  ref.value_.reset(new (std::nothrow) typename Derived::Status());
264  if (!ref.value_) return ENOMEM;
265  return 0;
266 }
267 
268 template<class Derived>
269 errno_t PromiseBase<Derived>::SetError(errno_t e) NLIB_NOEXCEPT {
270  if (e == 0) return 0;
271  Derived& ref = static_cast<Derived&>(*this);
272  if (!ref.value_) {
273  errno_t ee = ref.Init();
274  if (ee != 0) return ee;
275  }
276  {
277  ref.value_->common.Lock();
278  if (ref.value_->common.SetReady()) {
279  ref.value_->common.err = e;
280  ref.value_->common.Unlock();
281  } else {
282  ref.value_->common.Unlock();
283  return EALREADY;
284  }
285  }
286  this->NotifyAndContinuation();
287  return 0;
288 }
289 
290 template<class Derived>
291 template<class F>
292 errno_t PromiseBase<Derived>::GetFuture(F* p) NLIB_NOEXCEPT {
293  if (!p) return EINVAL;
294  Derived& ref = static_cast<Derived&>(*this);
295  if (!ref.value_) {
296  errno_t e = this->Init();
297  if (e != 0) return e;
298  }
299  errno_t e = p->value_.MakeSharedFrom(ref.value_);
300  if (e != 0) return e;
301  return 0;
302 }
303 
304 } // namespace detail
305 
306 template<class R>
307 class Promise : public detail::PromiseBase<Promise<R> > {
308  typedef detail::PromiseBase<Promise<R> > BaseType;
309 
310  public:
313  ~Promise() NLIB_NOEXCEPT {}
314 #ifdef __cpp_rvalue_references
315 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
316  Promise(Promise&& rhs) = default;
317  Promise& operator=(Promise&& rhs) = default;
318 #else
319  Promise(Promise&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
320  Promise& operator=(Promise&& rhs) NLIB_NOEXCEPT {
321  value_ = std::move(rhs.value_);
322  return *this;
323  }
324 #endif
325 #endif
326  Promise(Promise& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
328  value_.assign(rhs.value_, move_tag());
329  return *this;
330  }
331  errno_t SetValue(const R& value);
332 
333  // for doxygen :(
334  errno_t Init() NLIB_NOEXCEPT { return BaseType::Init(); }
335  errno_t SetError(errno_t e) NLIB_NOEXCEPT { return BaseType::SetError(e); }
336  errno_t GetFuture(Future<R>* p) NLIB_NOEXCEPT { return BaseType::GetFuture(p); }
337 
338  private:
339  struct Status {
340  typename BaseType::CommonStatus common;
341  R data;
342  };
343  LimitedSharedPtr<Status> value_;
345  template<class RR>
346  friend class Future;
347  template<class RR>
348  friend class detail::PromiseBase;
349 };
350 
351 template<class R>
352 errno_t Promise<R>::SetValue(const R& value) {
353  if (!value_) {
354  errno_t e = this->Init();
355  if (e != 0) return e;
356  }
357  {
358  ScopedLock<nlib_mutex> lock(value_->common.lock);
359  if (value_->common.SetReady()) {
360  NLIB_TRY {
361  value_->data = value; // may throw
362  }
363 #ifdef __cpp_exceptions
364  NLIB_RETHROW_UNWIND {
365  this->SetError(ECANCELED);
366  throw;
367  }
368  NLIB_CATCH(...) { return this->SetError(EINVAL); }
369 #endif
370  } else {
371  return EALREADY;
372  }
373  }
374  this->NotifyAndContinuation();
375  return 0;
376 }
377 
378 template<class T, class DEL>
379 class Promise<UniquePtr<T, DEL> > : public detail::PromiseBase<Promise<UniquePtr<T, DEL> > > {
380  typedef detail::PromiseBase<Promise<UniquePtr<T, DEL> > > BaseType;
381 
382  public:
383  typedef Future<UniquePtr<T, DEL> > FutureType;
385 #ifdef __cpp_rvalue_references
386 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
387  Promise(Promise&& rhs) = default;
388  Promise& operator=(Promise&& rhs) = default;
389 #else
390  Promise(Promise&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
391  Promise& operator=(Promise&& rhs) NLIB_NOEXCEPT {
392  value_ = std::move(rhs.value_);
393  return *this;
394  }
395 #endif
396 #endif
397  Promise(Promise& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
398  Promise& assign(Promise& rhs, move_tag) NLIB_NOEXCEPT {
399  value_.assign(rhs.value_, move_tag());
400  return *this;
401  }
402  errno_t SetValue(T* value) NLIB_NOEXCEPT;
403 
404  private:
405  struct Status {
406  typename BaseType::CommonStatus common;
407  UniquePtr<T, DEL> data;
408  };
409  LimitedSharedPtr<Status> value_;
411  template<class RR>
412  friend class Future;
413  template<class RR>
414  friend class detail::PromiseBase;
415 };
416 
417 template<class T, class DEL>
418 inline errno_t Promise<UniquePtr<T, DEL> >::SetValue(T* value) NLIB_NOEXCEPT {
419  if (!value_) {
420  errno_t e = this->Init();
421  if (e != 0) return e;
422  }
423  {
424  value_->common.Lock();
425  if (value_->common.SetReady()) {
426  value_->data.reset(value);
427  value_->common.Unlock();
428  } else {
429  value_->common.Unlock();
430  return EALREADY;
431  }
432  }
433  this->NotifyAndContinuation();
434  return 0;
435 }
436 
437 template<class T, class DEL>
438 class Promise<UniquePtr<T[], DEL> > : public detail::PromiseBase<Promise<UniquePtr<T[], DEL> > > {
439  typedef detail::PromiseBase<Promise<UniquePtr<T[], DEL> > > BaseType;
440 
441  public:
442  typedef Future<UniquePtr<T[], DEL> > FutureType;
443  Promise() NLIB_NOEXCEPT {}
444 #ifdef __cpp_rvalue_references
445 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
446  Promise(Promise&& rhs) = default;
447  Promise& operator=(Promise&& rhs) = default;
448 #else
449  Promise(Promise&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
450  Promise& operator=(Promise&& rhs) NLIB_NOEXCEPT {
451  value_ = std::move(rhs.value_);
452  return *this;
453  }
454 #endif
455 #endif
456  Promise(Promise& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
457  Promise& assign(Promise& rhs, move_tag) NLIB_NOEXCEPT {
458  value_.assign(rhs.value_, move_tag());
459  return *this;
460  }
461  errno_t SetValue(T* value) NLIB_NOEXCEPT;
462 
463  private:
464  struct Status {
465  typename BaseType::CommonStatus common;
466  UniquePtr<T[], DEL> data;
467  };
468  LimitedSharedPtr<Status> value_;
470  template<class RR>
471  friend class Future;
472  template<class RR>
473  friend class detail::PromiseBase;
474 };
475 
476 template<class T, class DEL>
477 inline errno_t Promise<UniquePtr<T[], DEL> >::SetValue(T* value) NLIB_NOEXCEPT {
478  if (!value_) {
479  errno_t e = this->Init();
480  if (e != 0) return e;
481  }
482  {
483  value_->common.Lock();
484  if (value_->common.SetReady()) {
485  value_->data.reset(value);
486  value_->common.Unlock();
487  } else {
488  value_->common.Unlock();
489  return EALREADY;
490  }
491  }
492  this->NotifyAndContinuation();
493  return 0;
494 }
495 
496 template<>
497 class Promise<void> : public detail::PromiseBase<Promise<void> > {
498  typedef detail::PromiseBase<Promise<void> > BaseType;
499 
500  public:
501  typedef Future<void> FutureType;
502  Promise() NLIB_NOEXCEPT {}
503 #ifdef __cpp_rvalue_references
504 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
505  Promise(Promise&& rhs) = default;
506  Promise& operator=(Promise&& rhs) = default;
507 #else
508  Promise(Promise&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
509  Promise& operator=(Promise&& rhs) NLIB_NOEXCEPT {
510  value_ = std::move(rhs.value_);
511  return *this;
512  }
513 #endif
514 #endif
515  Promise(Promise& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
516  Promise& assign(Promise& rhs, move_tag) NLIB_NOEXCEPT {
517  value_.assign(rhs.value_, move_tag());
518  return *this;
519  }
521 
522  private:
523  struct Status {
524  BaseType::CommonStatus common;
525  };
526  LimitedSharedPtr<Status> value_;
528  template<class RR>
529  friend class Future;
530  template<class RR>
531  friend class detail::PromiseBase;
532 };
533 
534 template<class R>
535 class Promise<Future<R> > : public detail::PromiseBase<Promise<Future<R> > > {
536  typedef detail::PromiseBase<Promise<Future<R> > > BaseType;
537 
538  public:
539  typedef Future<Future<R> > FutureType;
540  Promise() NLIB_NOEXCEPT {}
541 #ifdef __cpp_rvalue_references
542 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
543  Promise(Promise&& rhs) = default;
544  Promise& operator=(Promise&& rhs) = default;
545 #else
546  Promise(Promise&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
547  Promise& operator=(Promise&& rhs) NLIB_NOEXCEPT {
548  value_ = std::move(rhs.value_);
549  return *this;
550  }
551 #endif
552 #endif
553  Promise(Promise& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
554  Promise& assign(Promise& rhs, move_tag) NLIB_NOEXCEPT {
555  value_.assign(rhs.value_, move_tag());
556  return *this;
557  }
558  errno_t SetValue(const Future<R>& value) NLIB_NOEXCEPT;
559 
560  private:
561  struct Status {
562  typename BaseType::CommonStatus common;
563  Future<R> data;
564  };
565  LimitedSharedPtr<Status> value_;
567  template<class RR>
568  friend class Future;
569  template<class RR>
570  friend class detail::PromiseBase;
571 };
572 
573 template<class R>
574 inline errno_t Promise<Future<R> >::SetValue(const Future<R>& value) NLIB_NOEXCEPT {
575  if (!value_) {
576  errno_t e = this->Init();
577  if (e != 0) return e;
578  }
579  {
580  value_->common.Lock();
581  if (value_->common.SetReady()) {
582  errno_t e = value_->data.MakeSharedFrom(value);
583  value_->common.Unlock();
584  if (e != 0) {
585  return e;
586  }
587  } else {
588  value_->common.Unlock();
589  return EALREADY;
590  }
591  }
592  this->NotifyAndContinuation();
593  return 0;
594 }
595 
596 template<class R>
597 class Future : public detail::FutureBase<Future<R> > {
598  typedef detail::FutureBase<Future<R> > BaseType;
599 
600  public:
602 #ifdef __cpp_rvalue_references
603 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
604  Future(Future&& rhs) = default;
605  Future& operator=(Future&& rhs) = default;
606 #else
607  Future(Future&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
608  Future& operator=(Future&& rhs) NLIB_NOEXCEPT {
609  value_ = std::move(rhs.value_);
610  return *this;
611  }
612 #endif
613 #endif
614  Future(Future& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
616  value_.assign(rhs.value_, move_tag());
617  return *this;
618  }
619  R Get() {
620  R tmp = R(); // may throw
621  errno_t e = this->Get(&tmp);
622  NLIB_UNUSED(e);
623  NLIB_ASSERT_NOERR(e);
624  return tmp;
625  }
626  errno_t Get(R* ptr) {
627  if (!ptr) return EINVAL;
628  BaseType::Wait();
629  errno_t e = value_->common.err;
630  if (e == 0) {
631  NLIB_TRY {
632  *ptr = value_->data; // may throw
633  }
634 #ifdef __cpp_exceptions
635  NLIB_RETHROW_UNWIND { throw; }
636  NLIB_CATCH(...) { return ENOMEM; }
637 #endif
638  }
639  return e;
640  }
641  // for doxygen :(
642  bool IsValid() const NLIB_NOEXCEPT { return BaseType::IsValid(); }
643  bool IsReady() const NLIB_NOEXCEPT { return BaseType::IsReady(); }
644  errno_t Wait() NLIB_NOEXCEPT { return BaseType::Wait(); }
646  return BaseType::WaitFor(span);
647  }
649  return BaseType::WaitUntil(datetime);
650  }
651  template<class RNEXT>
653  return BaseType::Then(next, cont);
654  }
655  errno_t MakeSharedFrom(const Future& f) NLIB_NOEXCEPT { return BaseType::MakeSharedFrom(f); }
656 
657  private:
658  LimitedSharedPtr<typename Promise<R>::Status> value_;
660  template<class RR>
661  friend class Promise;
662  template<class RR>
663  friend class detail::FutureBase;
664  template<class RR>
665  friend class detail::PromiseBase;
666 };
667 
668 template<class T, class DEL>
669 class Future<UniquePtr<T, DEL> > : public detail::FutureBase<Future<UniquePtr<T, DEL> > > {
670  typedef detail::FutureBase<Future<UniquePtr<T, DEL> > > BaseType;
671 
672  public:
673  Future() NLIB_NOEXCEPT {}
674 #ifdef __cpp_rvalue_references
675 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
676  Future(Future&& rhs) = default;
677  Future& operator=(Future&& rhs) = default;
678 #else
679  Future(Future&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
680  Future& operator=(Future&& rhs) NLIB_NOEXCEPT {
681  value_ = std::move(rhs.value_);
682  return *this;
683  }
684 #endif
685 #endif
686  Future(Future& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
687  Future& assign(Future& rhs, move_tag) NLIB_NOEXCEPT {
688  value_.assign(rhs.value_, move_tag());
689  return *this;
690  }
691  T* Get() NLIB_NOEXCEPT {
692  BaseType::Wait();
693  return value_->data.get();
694  }
695  errno_t Get(T** ptr) NLIB_NOEXCEPT {
696  if (!ptr) return EINVAL;
697  BaseType::Wait();
698  errno_t e = value_->common.err;
699  if (e == 0) *ptr = value_->data.get();
700  return e;
701  }
702  T* Release() NLIB_NOEXCEPT {
703  BaseType::Wait();
704  return value_->data.release();
705  }
706 
707  private:
708  LimitedSharedPtr<typename Promise<UniquePtr<T, DEL> >::Status> value_;
710  template<class RR>
711  friend class Promise;
712  template<class RR>
713  friend class detail::FutureBase;
714  template<class RR>
715  friend class detail::PromiseBase;
716 };
717 
718 template<class T, class DEL>
719 class Future<UniquePtr<T[], DEL> > : public detail::FutureBase<Future<UniquePtr<T[], DEL> > > {
720  typedef detail::FutureBase<Future<UniquePtr<T[], DEL> > > BaseType;
721 
722  public:
723  Future() NLIB_NOEXCEPT {}
724 #ifdef __cpp_rvalue_references
725 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
726  Future(Future&& rhs) = default;
727  Future& operator=(Future&& rhs) = default;
728 #else
729  Future(Future&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
730  Future& operator=(Future&& rhs) NLIB_NOEXCEPT {
731  value_ = std::move(rhs.value_);
732  return *this;
733  }
734 #endif
735 #endif
736  Future(Future& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
737  Future& assign(Future& rhs, move_tag) NLIB_NOEXCEPT {
738  value_.assign(rhs.value_, move_tag());
739  return *this;
740  }
741  T* Get() NLIB_NOEXCEPT {
742  BaseType::Wait();
743  return value_->data.get();
744  }
745  errno_t Get(T** ptr) NLIB_NOEXCEPT {
746  if (!ptr) return EINVAL;
747  BaseType::Wait();
748  errno_t e = value_->common.err;
749  if (e == 0) *ptr = value_->data.get();
750  return e;
751  }
752  T* Release() NLIB_NOEXCEPT {
753  BaseType::Wait();
754  return value_->common.data.release();
755  }
756 
757  private:
758  LimitedSharedPtr<typename Promise<UniquePtr<T[], DEL> >::Status> value_;
760  template<class RR>
761  friend class Promise;
762  template<class RR>
763  friend class detail::FutureBase;
764  template<class RR>
765  friend class detail::PromiseBase;
766 };
767 
768 template<>
769 class Future<void> : public detail::FutureBase<Future<void> > {
770  typedef detail::FutureBase<Future<void> > BaseType;
771 
772  public:
773  Future() NLIB_NOEXCEPT {}
774 #ifdef __cpp_rvalue_references
775 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
776  Future(Future&& rhs) = default;
777  Future& operator=(Future&& rhs) = default;
778 #else
779  Future(Future&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
780  Future& operator=(Future&& rhs) NLIB_NOEXCEPT {
781  value_ = std::move(rhs.value_);
782  return *this;
783  }
784 #endif
785 #endif
786  Future(Future& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
787  Future& assign(Future& rhs, move_tag) NLIB_NOEXCEPT {
788  value_.assign(rhs.value_, move_tag());
789  return *this;
790  }
791  errno_t Get() NLIB_NOEXCEPT {
792  BaseType::Wait();
793  return value_->common.err;
794  }
795 
796  private:
797  LimitedSharedPtr<Promise<void>::Status> value_;
799  template<class RR>
800  friend class Promise;
801  template<class RR>
802  friend class detail::FutureBase;
803  template<class RR>
804  friend class detail::PromiseBase;
805 };
806 
807 template<class R>
808 class Future<Future<R> > : public detail::FutureBase<Future<Future<R> > > {
809  typedef detail::FutureBase<Future<Future<R> > > BaseType;
810 
811  public:
812  Future() NLIB_NOEXCEPT {}
813 #ifdef __cpp_rvalue_references
814 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
815  Future(Future&& rhs) = default;
816  Future& operator=(Future&& rhs) = default;
817 #else
818  Future(Future&& rhs) NLIB_NOEXCEPT : value_(std::move(rhs.value_)) {}
819  Future& operator=(Future&& rhs) NLIB_NOEXCEPT {
820  value_ = std::move(rhs.value_);
821  return *this;
822  }
823 #endif
824 #endif
825  Future(Future& rhs, move_tag) NLIB_NOEXCEPT : value_(rhs.value_, move_tag()) {}
826  Future& assign(Future& rhs, move_tag) NLIB_NOEXCEPT {
827  value_.assign(rhs.value_, move_tag());
828  return *this;
829  }
830  errno_t Get(Future<R>* inner) NLIB_NOEXCEPT {
831  if (!inner) return EINVAL;
832  BaseType::Wait();
833  errno_t e = value_->common.err;
834  if (e != 0) return e;
835  return inner->MakeSharedFrom(value_->data);
836  }
837 
838  private:
839  LimitedSharedPtr<typename Promise<Future<R> >::Status> value_;
841  template<class RR>
842  friend class Promise;
843  template<class RR>
844  friend class detail::FutureBase;
845  template<class RR>
846  friend class detail::PromiseBase;
847 };
848 
849 namespace detail {
850 
851 template<class R>
852 class FuncHolderBase0 {
853  public:
854  virtual ~FuncHolderBase0() {}
855  virtual R operator()() = 0;
856 };
857 
858 template<class R, class T1>
859 class FuncHolderBase1 {
860  public:
861  virtual ~FuncHolderBase1() {}
862  virtual R operator()(T1 NLIB_RREF arg1) = 0;
863 };
864 
865 template<class R, class T1, class T2>
866 class FuncHolderBase2 {
867  public:
868  virtual ~FuncHolderBase2() {}
869  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2) = 0;
870 };
871 
872 template<class R, class T1, class T2, class T3>
873 class FuncHolderBase3 {
874  public:
875  virtual ~FuncHolderBase3() {}
876  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3) = 0;
877 };
878 
879 template<class R, class T1, class T2, class T3, class T4>
880 class FuncHolderBase4 {
881  public:
882  virtual ~FuncHolderBase4() {}
883  virtual R
884  operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4) = 0;
885 };
886 
887 template<class R, class T1, class T2, class T3, class T4, class T5>
888 class FuncHolderBase5 {
889  public:
890  virtual ~FuncHolderBase5() {}
891  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4,
892  T5 NLIB_RREF arg5) = 0;
893 };
894 
895 template<class FUNC, bool USESWAP>
896 class FuncWrap_ {
897  public:
898  FuncWrap_(FUNC& func) NLIB_NOEXCEPT : func_() {
899  using std::swap;
900  swap(func, func_);
901  }
902  FUNC& get() NLIB_NOEXCEPT { return func_; }
903 
904  protected:
905  FUNC func_;
907 };
908 
909 template<class FUNC>
910 class FuncWrap_<FUNC, false> {
911  public:
912  FuncWrap_(FUNC& func) : func_(func) {}
913  FUNC& get() NLIB_NOEXCEPT { return func_; }
914 
915  protected:
916  FUNC func_;
918 };
919 
920 template<class FUNC>
921 class FuncWrap : public FuncWrap_<FUNC, IsSwappable<FUNC>::value> {
922  typedef FuncWrap_<FUNC, IsSwappable<FUNC>::value> BaseType;
923 
924  public:
925  FuncWrap(FUNC& func) : BaseType(func) {}
926 };
927 
928 template<class R>
929 class FuncWrap<R()> {
930  public:
931  typedef R (*FUNC)();
932  explicit FuncWrap(FUNC func) : func_(func) {}
933  FUNC& get() NLIB_NOEXCEPT { return func_; }
934 
935  protected:
936  FUNC func_;
938 };
939 
940 template<class R, class T1>
941 class FuncWrap<R(T1)> {
942  public:
943  typedef R (*FUNC)(T1);
944  explicit FuncWrap(FUNC func) : func_(func) {}
945  FUNC& get() NLIB_NOEXCEPT { return func_; }
946 
947  protected:
948  FUNC func_;
950 };
951 
952 template<class R, class T1, class T2>
953 class FuncWrap<R(T1, T2)> {
954  public:
955  typedef R (*FUNC)(T1, T2);
956  explicit FuncWrap(FUNC func) : func_(func) {}
957  FUNC& get() NLIB_NOEXCEPT { return func_; }
958 
959  protected:
960  FUNC func_;
962 };
963 
964 template<class R, class T1, class T2, class T3>
965 class FuncWrap<R(T1, T2, T3)> {
966  public:
967  typedef R (*FUNC)(T1, T2, T3);
968  explicit FuncWrap(FUNC func) : func_(func) {}
969  FUNC& get() NLIB_NOEXCEPT { return func_; }
970 
971  protected:
972  FUNC func_;
974 };
975 
976 template<class R, class T1, class T2, class T3, class T4>
977 class FuncWrap<R(T1, T2, T3, T4)> {
978  public:
979  typedef R (*FUNC)(T1, T2, T3, T4);
980  explicit FuncWrap(FUNC func) : func_(func) {}
981  FUNC& get() NLIB_NOEXCEPT { return func_; }
982 
983  protected:
984  FUNC func_;
986 };
987 
988 template<class R, class T1, class T2, class T3, class T4, class T5>
989 class FuncWrap<R(T1, T2, T3, T4, T5)> {
990  public:
991  typedef R (*FUNC)(T1, T2, T3, T4, T5);
992  explicit FuncWrap(FUNC func) : func_(func) {}
993  FUNC& get() NLIB_NOEXCEPT { return func_; }
994 
995  protected:
996  FUNC func_;
998 };
999 
1000 template<class FUNC, class R>
1001 class FuncHolder0 : public FuncHolderBase0<R> {
1002  public:
1003  FuncHolder0(FUNC& f) : func_(f) {}
1004  virtual ~FuncHolder0() NLIB_OVERRIDE {}
1005  virtual R operator()() NLIB_OVERRIDE { return func_.get()(); }
1006 
1007  private:
1008  FuncWrap<FUNC> func_;
1009 };
1010 
1011 template<class FUNC, class R, class T1>
1012 class FuncHolder1 : public FuncHolderBase1<R, T1> {
1013  public:
1014  FuncHolder1(FUNC& f) : func_(f) {}
1015  virtual ~FuncHolder1() NLIB_OVERRIDE {}
1016  virtual R operator()(T1 NLIB_RREF arg1) NLIB_OVERRIDE {
1017  return func_.get()(NLIB_FWD(T1, arg1));
1018  }
1019 
1020  private:
1021  FuncWrap<FUNC> func_;
1022 };
1023 
1024 template<class FUNC, class R, class T1, class T2>
1025 class FuncHolder2 : public FuncHolderBase2<R, T1, T2> {
1026  public:
1027  FuncHolder2(FUNC& f) : func_(f) {}
1028  virtual ~FuncHolder2() NLIB_OVERRIDE {}
1029  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2) NLIB_OVERRIDE {
1030  return func_.get()(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2));
1031  }
1032 
1033  private:
1034  FuncWrap<FUNC> func_;
1035 };
1036 
1037 template<class FUNC, class R, class T1, class T2, class T3>
1038 class FuncHolder3 : public FuncHolderBase3<R, T1, T2, T3> {
1039  public:
1040  FuncHolder3(FUNC& f) : func_(f) {}
1041  virtual ~FuncHolder3() NLIB_OVERRIDE {}
1042  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3) NLIB_OVERRIDE {
1043  return func_.get()(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3));
1044  }
1045 
1046  private:
1047  FuncWrap<FUNC> func_;
1048 };
1049 
1050 template<class FUNC, class R, class T1, class T2, class T3, class T4>
1051 class FuncHolder4 : public FuncHolderBase4<R, T1, T2, T3, T4> {
1052  public:
1053  FuncHolder4(FUNC& f) : func_(f) {}
1054  virtual ~FuncHolder4() NLIB_OVERRIDE {}
1055  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3,
1056  T4 NLIB_RREF arg4) NLIB_OVERRIDE {
1057  return func_.get()(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3),
1058  NLIB_FWD(T4, arg4));
1059  }
1060 
1061  private:
1062  FuncWrap<FUNC> func_;
1063 };
1064 
1065 template<class FUNC, class R, class T1, class T2, class T3, class T4, class T5>
1066 class FuncHolder5 : public FuncHolderBase5<R, T1, T2, T3, T4, T5> {
1067  public:
1068  FuncHolder5(FUNC& f) : func_(f) {}
1069  virtual ~FuncHolder5() NLIB_OVERRIDE {}
1070  virtual R operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4,
1071  T5 NLIB_RREF arg5) NLIB_OVERRIDE {
1072  return func_.get()(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3),
1073  NLIB_FWD(T4, arg4), NLIB_FWD(T5, arg5));
1074  }
1075 
1076  private:
1077  FuncWrap<FUNC> func_;
1078 };
1079 
1080 } // namespace detail
1081 
1082 template<class T>
1083 class PackagedTask { // defined for doygen ....
1084  public:
1087  template<class FUNC>
1088  errno_t Init(FUNC& func);
1089  template<class R>
1090  errno_t GetFuture(Future<R>* p) NLIB_NOEXCEPT;
1091 };
1092 
1093 template<class R>
1094 class PackagedTask<R()> {
1095  public:
1096  typedef R ReturnType;
1099 #ifdef __cpp_rvalue_references
1100 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1101  PackagedTask(PackagedTask&& rhs) = default;
1102  PackagedTask& operator=(PackagedTask&& rhs) = default;
1103 #else
1104  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1105  promise_(std::move(rhs.promise_)) {}
1106  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1107  func_ = std::move(rhs.func_);
1108  promise_ = std::move(rhs.promise_);
1109  return *this;
1110  }
1111 #endif
1112 #endif
1113  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1114  promise_(rhs.promise_, move_tag()) {}
1116  func_.reset(rhs.func_.release());
1117  promise_.assign(rhs.promise_, move_tag());
1118  return *this;
1119  }
1120  template<class FUNC>
1121  errno_t Init(FUNC& func) {
1122  errno_t e = promise_.Init();
1123  if (e != 0) return e;
1124  func_.reset(new (std::nothrow) detail::FuncHolder0<FUNC, R>(func));
1125  return !func_ ? ENOMEM : 0;
1126  }
1127  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1128  void operator()() { Exec<R>(); }
1129 
1130  private:
1131  template<class DUMMY>
1132  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type Exec() {
1133  NLIB_TRY {
1134  R rval = (*func_)();
1135  errno_t e = GetFutureError(rval);
1136  if (e == 0) {
1137  promise_.SetValue(rval);
1138  } else {
1139  promise_.SetError(e);
1140  }
1141  }
1142 #ifdef __cpp_exceptions
1143  NLIB_RETHROW_UNWIND {
1144  promise_.SetError(ECANCELED);
1145  throw;
1146  }
1147  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1148 #endif
1149  }
1150  template<class DUMMY>
1151  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type Exec(){NLIB_TRY{(*func_)();
1152  promise_.SetValue();
1153 }
1154 #ifdef __cpp_exceptions
1155 NLIB_RETHROW_UNWIND {
1156  promise_.SetError(ECANCELED);
1157  throw;
1158 }
1159 NLIB_CATCH(...) {
1160  promise_.SetError(EINVAL);
1161 }
1162 #endif
1163 } // namespace threading
1164 
1166 Promise<R> promise_;
1168 }
1169 ;
1170 
1171 template<class R, class T1>
1172 class PackagedTask<R(T1)> {
1173  public:
1174  typedef R ReturnType;
1175  typedef PackagedTask<ReturnType(T1)> ThisType;
1177 #ifdef __cpp_rvalue_references
1178 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1179  PackagedTask(PackagedTask&& rhs) = default;
1180  PackagedTask& operator=(PackagedTask&& rhs) = default;
1181 #else
1182  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1183  promise_(std::move(rhs.promise_)) {}
1184  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1185  func_ = std::move(rhs.func_);
1186  promise_ = std::move(rhs.promise_);
1187  return *this;
1188  }
1189 #endif
1190 #endif
1191  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1192  promise_(rhs.promise_, move_tag()) {}
1193  PackagedTask& assign(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT {
1194  func_.reset(rhs.func_.release());
1195  promise_.assign(rhs.promise_, move_tag());
1196  return *this;
1197  }
1198  template<class FUNC>
1199  errno_t Init(FUNC& func) {
1200  errno_t e = promise_.Init();
1201  if (e != 0) return e;
1202  func_.reset(new (std::nothrow) detail::FuncHolder1<FUNC, R, T1>(func));
1203  return !func_ ? ENOMEM : 0;
1204  }
1205  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1206  void operator()(T1 NLIB_RREF arg1) { Exec<R>(NLIB_FWD(T1, arg1)); }
1207 
1208  private:
1209  template<class DUMMY>
1210  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type Exec(T1 NLIB_RREF arg1) {
1211  NLIB_TRY {
1212  R rval = (*func_)(NLIB_FWD(T1, arg1));
1213  errno_t e = GetFutureError(rval);
1214  if (e == 0) {
1215  promise_.SetValue(rval);
1216  } else {
1217  promise_.SetError(e);
1218  }
1219  }
1220 #ifdef __cpp_exceptions
1221  NLIB_RETHROW_UNWIND {
1222  promise_.SetError(ECANCELED);
1223  throw;
1224  }
1225  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1226 #endif
1227  }
1228  template<class DUMMY>
1229  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type
1230  Exec(T1 NLIB_RREF arg1){NLIB_TRY{(*func_)(NLIB_FWD(T1, arg1));
1231  promise_.SetValue();
1232 }
1233 #ifdef __cpp_exceptions
1234 NLIB_RETHROW_UNWIND {
1235  promise_.SetError(ECANCELED);
1236  throw;
1237 }
1238 NLIB_CATCH(...) {
1239  promise_.SetError(EINVAL);
1240 }
1241 #endif
1242 }
1243 
1244 UniquePtr<detail::FuncHolderBase1<R, T1> > func_;
1245 Promise<R> promise_;
1246 NLIB_DISALLOW_COPY_AND_ASSIGN(PackagedTask);
1247 }
1248 ;
1249 
1250 template<class R, class T1, class T2>
1251 class PackagedTask<R(T1, T2)> {
1252  public:
1253  typedef R ReturnType;
1254  typedef PackagedTask<ReturnType(T1, T2)> ThisType;
1255  PackagedTask() NLIB_NOEXCEPT {}
1256 #ifdef __cpp_rvalue_references
1257 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1258  PackagedTask(PackagedTask&& rhs) = default;
1259  PackagedTask& operator=(PackagedTask&& rhs) = default;
1260 #else
1261  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1262  promise_(std::move(rhs.promise_)) {}
1263  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1264  func_ = std::move(rhs.func_);
1265  promise_ = std::move(rhs.promise_);
1266  return *this;
1267  }
1268 #endif
1269 #endif
1270  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1271  promise_(rhs.promise_, move_tag()) {}
1272  PackagedTask& assign(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT {
1273  func_.reset(rhs.func_.release());
1274  promise_.assign(rhs.promise_, move_tag());
1275  return *this;
1276  }
1277  template<class FUNC>
1278  errno_t Init(FUNC& func) {
1279  errno_t e = promise_.Init();
1280  if (e != 0) return e;
1281  func_.reset(new (std::nothrow) detail::FuncHolder2<FUNC, R, T1, T2>(func));
1282  return !func_ ? ENOMEM : 0;
1283  }
1284  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1285  void operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2) {
1286  Exec<R>(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2));
1287  }
1288 
1289  private:
1290  template<class DUMMY>
1291  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type
1292  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2) {
1293  NLIB_TRY {
1294  R rval = (*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2));
1295  errno_t e = GetFutureError(rval);
1296  if (e == 0) {
1297  promise_.SetValue(rval);
1298  } else {
1299  promise_.SetError(e);
1300  }
1301  }
1302 #ifdef __cpp_exceptions
1303  NLIB_RETHROW_UNWIND {
1304  promise_.SetError(ECANCELED);
1305  throw;
1306  }
1307  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1308 #endif
1309  }
1310  template<class DUMMY>
1311  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type
1312  Exec(T1 NLIB_RREF arg1,
1313  T2 NLIB_RREF arg2){NLIB_TRY{(*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2));
1314  promise_.SetValue();
1315 }
1316 #ifdef __cpp_exceptions
1317 NLIB_RETHROW_UNWIND {
1318  promise_.SetError(ECANCELED);
1319  throw;
1320 }
1321 NLIB_CATCH(...) {
1322  promise_.SetError(EINVAL);
1323 }
1324 #endif
1325 }
1326 
1327 UniquePtr<detail::FuncHolderBase2<R, T1, T2> > func_;
1328 Promise<ReturnType> promise_;
1329 NLIB_DISALLOW_COPY_AND_ASSIGN(PackagedTask);
1330 }
1331 ;
1332 
1333 template<class R, class T1, class T2, class T3>
1334 class PackagedTask<R(T1, T2, T3)> {
1335  public:
1336  typedef R ReturnType;
1337  typedef PackagedTask<ReturnType(T1, T2, T3)> ThisType;
1338  PackagedTask() NLIB_NOEXCEPT {}
1339 #ifdef __cpp_rvalue_references
1340 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1341  PackagedTask(PackagedTask&& rhs) = default;
1342  PackagedTask& operator=(PackagedTask&& rhs) = default;
1343 #else
1344  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1345  promise_(std::move(rhs.promise_)) {}
1346  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1347  func_ = std::move(rhs.func_);
1348  promise_ = std::move(rhs.promise_);
1349  return *this;
1350  }
1351 #endif
1352 #endif
1353  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1354  promise_(rhs.promise_, move_tag()) {}
1355  PackagedTask& assign(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT {
1356  func_.reset(rhs.func_.release());
1357  promise_.assign(rhs.promise_, move_tag());
1358  return *this;
1359  }
1360  template<class FUNC>
1361  errno_t Init(FUNC& func) {
1362  errno_t e = promise_.Init();
1363  if (e != 0) return e;
1364  func_.reset(new (std::nothrow) detail::FuncHolder3<FUNC, R, T1, T2, T3>(func));
1365  return !func_ ? ENOMEM : 0;
1366  }
1367  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1368  void operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3) {
1369  Exec<R>(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3));
1370  }
1371 
1372  private:
1373  template<class DUMMY>
1374  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type
1375  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3) {
1376  NLIB_TRY {
1377  R rval = (*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3));
1378  errno_t e = GetFutureError(rval);
1379  if (e == 0) {
1380  promise_.SetValue(rval);
1381  } else {
1382  promise_.SetError(e);
1383  }
1384  }
1385 #ifdef __cpp_exceptions
1386  NLIB_RETHROW_UNWIND {
1387  promise_.SetError(ECANCELED);
1388  throw;
1389  }
1390  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1391 #endif
1392  }
1393  template<class DUMMY>
1394  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type
1395  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3){
1396  NLIB_TRY{(*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3));
1397  promise_.SetValue();
1398 }
1399 #ifdef __cpp_exceptions
1400 NLIB_RETHROW_UNWIND {
1401  promise_.SetError(ECANCELED);
1402  throw;
1403 }
1404 NLIB_CATCH(...) {
1405  promise_.SetError(EINVAL);
1406 }
1407 #endif
1408 }
1409 
1410 UniquePtr<detail::FuncHolderBase3<R, T1, T2, T3> > func_;
1411 Promise<ReturnType> promise_;
1412 NLIB_DISALLOW_COPY_AND_ASSIGN(PackagedTask);
1413 }
1414 ;
1415 
1416 template<class R, class T1, class T2, class T3, class T4>
1417 class PackagedTask<R(T1, T2, T3, T4)> {
1418  public:
1419  typedef R ReturnType;
1420  typedef PackagedTask<ReturnType(T1, T2, T3, T4)> ThisType;
1421  PackagedTask() NLIB_NOEXCEPT {}
1422 #ifdef __cpp_rvalue_references
1423 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1424  PackagedTask(PackagedTask&& rhs) = default;
1425  PackagedTask& operator=(PackagedTask&& rhs) = default;
1426 #else
1427  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1428  promise_(std::move(rhs.promise_)) {}
1429  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1430  func_ = std::move(rhs.func_);
1431  promise_ = std::move(rhs.promise_);
1432  return *this;
1433  }
1434 #endif
1435 #endif
1436  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1437  promise_(rhs.promise_, move_tag()) {}
1438  PackagedTask& assign(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT {
1439  func_.reset(rhs.func_.release());
1440  promise_.assign(rhs.promise_, move_tag());
1441  return *this;
1442  }
1443  template<class FUNC>
1444  errno_t Init(FUNC& func) {
1445  errno_t e = promise_.Init();
1446  if (e != 0) return e;
1447  func_.reset(new (std::nothrow) detail::FuncHolder4<FUNC, R, T1, T2, T3, T4>(func));
1448  return !func_ ? ENOMEM : 0;
1449  }
1450  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1451  void operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4) {
1452  Exec<R>(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3), NLIB_FWD(T4, arg4));
1453  }
1454 
1455  private:
1456  template<class DUMMY>
1457  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type
1458  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4) {
1459  NLIB_TRY {
1460  R rval = (*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3),
1461  NLIB_FWD(T4, arg4));
1462  errno_t e = GetFutureError(rval);
1463  if (e == 0) {
1464  promise_.SetValue(rval);
1465  } else {
1466  promise_.SetError(e);
1467  }
1468  }
1469 #ifdef __cpp_exceptions
1470  NLIB_RETHROW_UNWIND {
1471  promise_.SetError(ECANCELED);
1472  throw;
1473  }
1474  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1475 #endif
1476  }
1477  template<class DUMMY>
1478  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type
1479  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4){NLIB_TRY{
1480  (*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3), NLIB_FWD(T4, arg4));
1481  promise_.SetValue();
1482 }
1483 #ifdef __cpp_exceptions
1484 NLIB_RETHROW_UNWIND {
1485  promise_.SetError(ECANCELED);
1486  throw;
1487 }
1488 NLIB_CATCH(...) {
1489  promise_.SetError(EINVAL);
1490 }
1491 #endif
1492 }
1493 
1494 UniquePtr<detail::FuncHolderBase4<R, T1, T2, T3, T4> > func_;
1495 Promise<ReturnType> promise_;
1496 NLIB_DISALLOW_COPY_AND_ASSIGN(PackagedTask);
1497 }
1498 ;
1499 
1500 template<class R, class T1, class T2, class T3, class T4, class T5>
1501 class PackagedTask<R(T1, T2, T3, T4, T5)> {
1502  public:
1503  typedef R ReturnType;
1504  typedef PackagedTask<ReturnType(T1, T2, T3, T4, T5)> ThisType;
1505  PackagedTask() NLIB_NOEXCEPT {}
1506 #ifdef __cpp_rvalue_references
1507 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
1508  PackagedTask(PackagedTask&& rhs) = default;
1509  PackagedTask& operator=(PackagedTask&& rhs) = default;
1510 #else
1511  PackagedTask(PackagedTask&& rhs) NLIB_NOEXCEPT : func_(std::move(rhs.func_)),
1512  promise_(std::move(rhs.promise_)) {}
1513  PackagedTask& operator=(PackagedTask&& rhs) NLIB_NOEXCEPT {
1514  func_ = std::move(rhs.func_);
1515  promise_ = std::move(rhs.promise_);
1516  return *this;
1517  }
1518 #endif
1519 #endif
1520  PackagedTask(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT : func_(rhs.func_.release()),
1521  promise_(rhs.promise_, move_tag()) {}
1522  PackagedTask& assign(PackagedTask& rhs, move_tag) NLIB_NOEXCEPT {
1523  func_.reset(rhs.func_.release());
1524  promise_.assign(rhs.promise_, move_tag());
1525  return *this;
1526  }
1527  template<class FUNC>
1528  errno_t Init(FUNC& func) {
1529  errno_t e = promise_.Init();
1530  if (e != 0) return e;
1531  func_.reset(new (std::nothrow) detail::FuncHolder5<FUNC, R, T1, T2, T3, T4, T5>(func));
1532  return !func_ ? ENOMEM : 0;
1533  }
1534  errno_t GetFuture(Future<ReturnType>* p) NLIB_NOEXCEPT { return promise_.GetFuture(p); }
1535  void operator()(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4,
1536  T5 NLIB_RREF arg5) {
1537  Exec<R>(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3), NLIB_FWD(T4, arg4),
1538  NLIB_FWD(T5, arg5));
1539  }
1540 
1541  private:
1542  template<class DUMMY>
1543  typename EnableIf<!IsSame<DUMMY, void>::value, void>::type
1544  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4,
1545  T5 NLIB_RREF arg5) {
1546  NLIB_TRY {
1547  R rval = (*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3),
1548  NLIB_FWD(T4, arg4), NLIB_FWD(T5, arg5));
1549  errno_t e = GetFutureError(rval);
1550  if (e == 0) {
1551  promise_.SetValue(rval);
1552  } else {
1553  promise_.SetError(e);
1554  }
1555  }
1556 #ifdef __cpp_exceptions
1557  NLIB_RETHROW_UNWIND {
1558  promise_.SetError(ECANCELED);
1559  throw;
1560  }
1561  NLIB_CATCH(...) { promise_.SetError(EINVAL); }
1562 #endif
1563  }
1564  template<class DUMMY>
1565  typename EnableIf<IsSame<DUMMY, void>::value, DUMMY>::type
1566  Exec(T1 NLIB_RREF arg1, T2 NLIB_RREF arg2, T3 NLIB_RREF arg3, T4 NLIB_RREF arg4,
1567  T5 NLIB_RREF arg5){
1568  NLIB_TRY{(*func_)(NLIB_FWD(T1, arg1), NLIB_FWD(T2, arg2), NLIB_FWD(T3, arg3),
1569  NLIB_FWD(T4, arg4), NLIB_FWD(T5, arg5));
1570  promise_.SetValue();
1571 }
1572 #ifdef __cpp_exceptions
1573 NLIB_RETHROW_UNWIND {
1574  promise_.SetError(ECANCELED);
1575  throw;
1576 }
1577 NLIB_CATCH(...) {
1578  promise_.SetError(EINVAL);
1579 }
1580 #endif
1581 }
1582 
1583 UniquePtr<detail::FuncHolderBase5<R, T1, T2, T3, T4, T5> > func_;
1584 Promise<ReturnType> promise_;
1585 NLIB_DISALLOW_COPY_AND_ASSIGN(PackagedTask);
1586 }
1587 ;
1588 
1589 namespace detail {
1590 
1591 template<class T, bool B>
1592 struct XHolder {
1593  explicit XHolder(const T& value_) : value() {
1594  using std::swap;
1595  swap(const_cast<T&>(value_), value);
1596  }
1597  T value;
1598 };
1599 
1600 template<class T>
1601 struct XHolder<T, false> {
1602  explicit XHolder(const T& value_) : value(value_) {}
1603  T value;
1604 };
1605 
1606 template<class R>
1607 struct XHolder<R(), false> {
1608  XHolder(R (*value_)()) : value(value_) {}
1609  R (*value)();
1610 };
1611 
1612 template<class R, class T1>
1613 struct XHolder<R(T1), false> {
1614  XHolder(R (*value_)(T1)) : value(value_) {}
1615  R (*value)(T1);
1616 };
1617 
1618 template<class R, class T1, class T2>
1619 struct XHolder<R(T1, T2), false> {
1620  XHolder(R (*value_)(T1, T2)) : value(value_) {}
1621  R (*value)(T1, T2);
1622 };
1623 
1624 template<class R, class T1, class T2, class T3>
1625 struct XHolder<R(T1, T2, T3), false> {
1626  XHolder(R (*value_)(T1, T2, T3)) : value(value_) {}
1627  R (*value)(T1, T2, T3);
1628 };
1629 
1630 template<class R, class T1, class T2, class T3, class T4>
1631 struct XHolder<R(T1, T2, T3, T4), false> {
1632  XHolder(R (*value_)(T1, T2, T3, T4)) : value(value_) {}
1633  R (*value)(T1, T2, T3, T4);
1634 };
1635 
1636 template<class R, class T1, class T2, class T3, class T4, class T5>
1637 struct XHolder<R(T1, T2, T3, T4, T5), false> {
1638  XHolder(R (*value_)(T1, T2, T3, T4, T5)) : value(value_) {}
1639  R (*value)(T1, T2, T3, T4, T5);
1640 };
1641 
1642 #define NLIB_ASYNC_HOLDER(T, B) \
1643  XHolder<T, B::value && IsSwappable<T>::value && !IsArithmetic<T>::value>
1644 #ifdef __cpp_rvalue_references
1645 #define NLIB_ASYNC_HOLDER_F(FUNC, B) \
1646  XHolder<FUNC, B::value && IsSwappable<FUNC>::value && !IsPointer<FUNC>::value>
1647 #else
1648 #define NLIB_ASYNC_HOLDER_F(FUNC, B) \
1649  XHolder<FUNC, B::value && IsSwappable<FUNC>::value && !IsPointer<FUNC>::value>
1650 #endif
1651 
1652 template<class FUNC, class R, class BF>
1653 errno_t Async_(Future<R>* future, const FUNC& func, const ThreadSettings& settings, BF) {
1654  if (!future || !settings.GetDetachState()) return EINVAL;
1655  PackagedTask<R()> task;
1656  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1657  errno_t e = task.Init(func_.value);
1658  if (e != 0) return e;
1659  e = task.GetFuture(future);
1660  if (e != 0) return e;
1661  Thread th;
1662  e = th.Start(settings, task, move_tag());
1663  return e;
1664 }
1665 
1666 template<class FUNC, class R, class BF, class T1>
1667 errno_t
1668 Async_(Future<R>* future, const FUNC& func, const T1& arg1, const ThreadSettings& settings, BF) {
1669  if (!future || !settings.GetDetachState()) return EINVAL;
1670  PackagedTask<R(T1)> task;
1671  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1672  errno_t e = task.Init(func_.value);
1673  if (e != 0) return e;
1674  e = task.GetFuture(future);
1675  if (e != 0) return e;
1676  Thread th;
1677  NLIB_ASYNC_HOLDER(T1, BF) arg1_(arg1);
1678  e = th.Start(settings, task, arg1_.value, move_tag());
1679  return e;
1680 }
1681 
1682 template<class FUNC, class R, class BF, class T1, class T2>
1683 errno_t Async_(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1684  const ThreadSettings& settings, BF) {
1685  if (!future || !settings.GetDetachState()) return EINVAL;
1686  PackagedTask<R(T1, T2)> task;
1687  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1688  errno_t e = task.Init(func_.value);
1689  if (e != 0) return e;
1690  e = task.GetFuture(future);
1691  if (e != 0) return e;
1692  Thread th;
1693  NLIB_ASYNC_HOLDER(T1, BF) arg1_(arg1);
1694  NLIB_ASYNC_HOLDER(T2, BF) arg2_(arg2);
1695  e = th.Start(settings, task, arg1_.value, arg2_.value, move_tag());
1696  return e;
1697 }
1698 
1699 template<class FUNC, class R, class BF, class T1, class T2, class T3>
1700 errno_t Async_(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3,
1701  const ThreadSettings& settings, BF) {
1702  if (!future || !settings.GetDetachState()) return EINVAL;
1703  PackagedTask<R(T1, T2, T3)> task;
1704  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1705  errno_t e = task.Init(func_.value);
1706  if (e != 0) return e;
1707  e = task.GetFuture(future);
1708  if (e != 0) return e;
1709  Thread th;
1710  NLIB_ASYNC_HOLDER(T1, BF) arg1_(arg1);
1711  NLIB_ASYNC_HOLDER(T2, BF) arg2_(arg2);
1712  NLIB_ASYNC_HOLDER(T3, BF) arg3_(arg3);
1713  e = th.Start(settings, task, arg1_.value, arg2_.value, arg3_.value, move_tag());
1714  return e;
1715 }
1716 
1717 template<class FUNC, class R, class BF, class T1, class T2, class T3, class T4>
1718 errno_t Async_(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3,
1719  const T4& arg4, const ThreadSettings& settings, BF) {
1720  if (!future || !settings.GetDetachState()) return EINVAL;
1721  PackagedTask<R(T1, T2, T3, T4)> task;
1722  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1723  errno_t e = task.Init(func_.value);
1724  if (e != 0) return e;
1725  e = task.GetFuture(future);
1726  if (e != 0) return e;
1727  Thread th;
1728  NLIB_ASYNC_HOLDER(T1, BF) arg1_(arg1);
1729  NLIB_ASYNC_HOLDER(T2, BF) arg2_(arg2);
1730  NLIB_ASYNC_HOLDER(T3, BF) arg3_(arg3);
1731  NLIB_ASYNC_HOLDER(T4, BF) arg4_(arg4);
1732  e = th.Start(settings, task, arg1_.value, arg2_.value, arg3_.value, arg4_.value, move_tag());
1733  return e;
1734 }
1735 
1736 template<class FUNC, class R, class BF, class T1, class T2, class T3, class T4, class T5>
1737 errno_t Async_(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3,
1738  const T4& arg4, const T5& arg5, const ThreadSettings& settings, BF) {
1739  if (!future || !settings.GetDetachState()) return EINVAL;
1740  PackagedTask<R(T1, T2, T3, T4, T5)> task;
1741  NLIB_ASYNC_HOLDER_F(FUNC, BF) func_(func);
1742  errno_t e = task.Init(func_.value);
1743  if (e != 0) return e;
1744  e = task.GetFuture(future);
1745  if (e != 0) return e;
1746  Thread th;
1747  NLIB_ASYNC_HOLDER(T1, BF) arg1_(arg1);
1748  NLIB_ASYNC_HOLDER(T2, BF) arg2_(arg2);
1749  NLIB_ASYNC_HOLDER(T3, BF) arg3_(arg3);
1750  NLIB_ASYNC_HOLDER(T4, BF) arg4_(arg4);
1751  NLIB_ASYNC_HOLDER(T5, BF) arg5_(arg5);
1752  e = th.Start(settings, task, arg1_.value, arg2_.value, arg3_.value, arg4_.value, arg5_.value,
1753  move_tag());
1754  return e;
1755 }
1756 
1757 #undef NLIB_ASYNC_HOLDER
1758 #undef NLIB_ASYNC_HOLDER_F
1759 
1760 } // namespace detail
1761 
1762 template<class FUNC, class R>
1763 inline errno_t Async(Future<R>* future, const FUNC& func, const ThreadSettings& settings) {
1764  return detail::Async_(future, func, settings, FalseType());
1765 }
1766 
1767 template<class FUNC, class R>
1768 inline errno_t
1769 Async(Future<R>* future, const FUNC& func, const ThreadSettings& settings, move_tag) {
1770  return detail::Async_(future, func, settings, TrueType());
1771 }
1772 
1773 template<class FUNC, class R>
1774 inline errno_t Async(Future<R>* future, const FUNC& func) {
1775  ThreadSettings settings;
1776  settings.SetDetachState(true);
1777  return Async(future, func, settings);
1778 }
1779 
1780 template<class FUNC, class R>
1781 inline errno_t Async(Future<R>* future, const FUNC& func, move_tag) {
1782  ThreadSettings settings;
1783  settings.SetDetachState(true);
1784  return Async(future, func, settings, move_tag());
1785 }
1786 
1787 template<class FUNC, class R, class T1>
1788 inline errno_t
1789 Async(Future<R>* future, const FUNC& func, const T1& arg1, const ThreadSettings& settings) {
1790  return detail::Async_(future, func, arg1, settings, FalseType());
1791 }
1792 
1793 template<class FUNC, class R, class T1>
1794 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1,
1795  const ThreadSettings& settings, move_tag) {
1796  return detail::Async_(future, func, arg1, settings, TrueType());
1797 }
1798 
1799 template<class FUNC, class R, class T1>
1800 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1) {
1801  ThreadSettings settings;
1802  settings.SetDetachState(true);
1803  return Async(future, func, arg1, settings);
1804 }
1805 
1806 template<class FUNC, class R, class T1>
1807 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, move_tag) {
1808  ThreadSettings settings;
1809  settings.SetDetachState(true);
1810  return Async(future, func, arg1, settings, move_tag());
1811 }
1812 
1813 template<class FUNC, class R, class T1, class T2>
1814 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1815  const ThreadSettings& settings) {
1816  return detail::Async_(future, func, arg1, arg2, settings, FalseType());
1817 }
1818 
1819 template<class FUNC, class R, class T1, class T2>
1820 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1821  const ThreadSettings& settings, move_tag) {
1822  return detail::Async_(future, func, arg1, arg2, settings, TrueType());
1823 }
1824 
1825 template<class FUNC, class R, class T1, class T2>
1826 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2) {
1827  ThreadSettings settings;
1828  settings.SetDetachState(true);
1829  return Async(future, func, arg1, arg2, settings);
1830 }
1831 
1832 template<class FUNC, class R, class T1, class T2>
1833 inline errno_t
1834 Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, move_tag) {
1835  ThreadSettings settings;
1836  settings.SetDetachState(true);
1837  return Async(future, func, arg1, arg2, settings, move_tag());
1838 }
1839 
1840 template<class FUNC, class R, class T1, class T2, class T3>
1841 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1842  const T3& arg3, const ThreadSettings& settings) {
1843  return detail::Async_(future, func, arg1, arg2, arg3, settings, FalseType());
1844 }
1845 
1846 template<class FUNC, class R, class T1, class T2, class T3>
1847 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1848  const T3& arg3, const ThreadSettings& settings, move_tag) {
1849  return detail::Async_(future, func, arg1, arg2, arg3, settings, TrueType());
1850 }
1851 
1852 template<class FUNC, class R, class T1, class T2, class T3>
1853 inline errno_t
1854 Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3) {
1855  ThreadSettings settings;
1856  settings.SetDetachState(true);
1857  return Async(future, func, arg1, arg2, arg3, settings);
1858 }
1859 
1860 template<class FUNC, class R, class T1, class T2, class T3>
1861 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1862  const T3& arg3, move_tag) {
1863  ThreadSettings settings;
1864  settings.SetDetachState(true);
1865  return Async(future, func, arg1, arg2, arg3, settings, move_tag());
1866 }
1867 
1868 template<class FUNC, class R, class T1, class T2, class T3, class T4>
1869 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1870  const T3& arg3, const T4& arg4, const ThreadSettings& settings) {
1871  return detail::Async_(future, func, arg1, arg2, arg3, arg4, settings, FalseType());
1872 }
1873 
1874 template<class FUNC, class R, class T1, class T2, class T3, class T4>
1875 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1876  const T3& arg3, const T4& arg4, const ThreadSettings& settings, move_tag) {
1877  return detail::Async_(future, func, arg1, arg2, arg3, arg4, settings, TrueType());
1878 }
1879 
1880 template<class FUNC, class R, class T1, class T2, class T3, class T4>
1881 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1882  const T3& arg3, const T4& arg4) {
1883  ThreadSettings settings;
1884  settings.SetDetachState(true);
1885  return Async(future, func, arg1, arg2, arg3, arg4, settings);
1886 }
1887 
1888 template<class FUNC, class R, class T1, class T2, class T3, class T4>
1889 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1890  const T3& arg3, const T4& arg4, move_tag) {
1891  ThreadSettings settings;
1892  settings.SetDetachState(true);
1893  return Async(future, func, arg1, arg2, arg3, arg4, settings, move_tag());
1894 }
1895 
1896 template<class FUNC, class R, class T1, class T2, class T3, class T4, class T5>
1897 inline errno_t
1898 Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3,
1899  const T4& arg4, const T5& arg5, const ThreadSettings& settings) {
1900  return detail::Async_(future, func, arg1, arg2, arg3, arg4, arg5, settings, FalseType());
1901 }
1902 
1903 template<class FUNC, class R, class T1, class T2, class T3, class T4, class T5>
1904 inline errno_t
1905 Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2, const T3& arg3,
1906  const T4& arg4, const T5& arg5, const ThreadSettings& settings, move_tag) {
1907  return detail::Async_(future, func, arg1, arg2, arg3, arg4, arg5, settings, TrueType());
1908 }
1909 
1910 template<class FUNC, class R, class T1, class T2, class T3, class T4, class T5>
1911 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1912  const T3& arg3, const T4& arg4, const T5& arg5) {
1913  ThreadSettings settings;
1914  settings.SetDetachState(true);
1915  return Async(future, func, arg1, arg2, arg3, arg4, arg5, settings);
1916 }
1917 
1918 template<class FUNC, class R, class T1, class T2, class T3, class T4, class T5>
1919 inline errno_t Async(Future<R>* future, const FUNC& func, const T1& arg1, const T2& arg2,
1920  const T3& arg3, const T4& arg4, const T5& arg5, move_tag) {
1921  ThreadSettings settings;
1922  settings.SetDetachState(true);
1923  return Async(future, func, arg1, arg2, arg3, arg4, arg5, settings, move_tag());
1924 }
1925 
1926 template<class R>
1927 inline errno_t MakeReadyFuture(Future<R>* future, const R& value) {
1928  if (!future) return EINVAL;
1929  Promise<R> promise;
1930  errno_t e = promise.Init();
1931  if (e != 0) return e;
1932  e = promise.SetValue(value);
1933  if (e != 0) return e;
1934  e = promise.GetFuture(future);
1935  if (e != 0) return e;
1936  return 0;
1937 }
1938 
1939 namespace detail {
1940 template<class FUTURE, class R, typename CONT>
1941 class FutureContinuation : public FutureContinuationBase {
1942  public:
1943  FutureContinuation(FUTURE& f, CONT cont) NLIB_NOEXCEPT : status_(0), parent_(f), func_(cont) {}
1944  errno_t Init() NLIB_NOEXCEPT { return next_.Init(); }
1945  errno_t GetFuture(Future<R>* future) NLIB_NOEXCEPT { return next_.GetFuture(future); }
1946  virtual ~FutureContinuation() NLIB_NOEXCEPT NLIB_OVERRIDE {}
1947  virtual void DoContinuation() NLIB_OVERRIDE;
1948 
1949  private:
1950  int32_t status_;
1951  FUTURE& parent_;
1952  CONT func_;
1953  Promise<R> next_;
1954 };
1955 
1956 template<class FUTURE, class R, typename CONT>
1957 void FutureContinuation<FUTURE, R, CONT>::DoContinuation() {
1958  int32_t expected = 0;
1959  if (nlib_atomic_compare_exchange32(&status_, &expected, 20120901L, 0, NLIB_ATOMIC_ACQUIRE,
1961  NLIB_TRY {
1962  R rval = func_(parent_);
1963  errno_t e = GetFutureError(rval);
1964  if (e == 0) {
1965  (void)next_.SetValue(rval);
1966  } else {
1967  (void)next_.SetError(e);
1968  }
1969  }
1970 #ifdef __cpp_exceptions
1971  NLIB_RETHROW_UNWIND {
1972  next_.SetError(ECANCELED);
1973  throw;
1974  }
1975  NLIB_CATCH(...) { (void)next_.SetError(EINVAL); }
1976 #endif
1977  }
1978 }
1979 
1980 template<class Derived>
1981 template<class R>
1982 errno_t FutureBase<Derived>::Then(Future<R>* next, R (*cont)(Derived&)) NLIB_NOEXCEPT {
1983  Derived& ref = static_cast<Derived&>(*this);
1984  if (!ref.value_) return EINVAL;
1985 
1986  typedef R (*CONT)(Derived&);
1987  UniquePtr<FutureContinuation<Derived, R, CONT> > ptr(
1988  new (std::nothrow) FutureContinuation<Derived, R, CONT>(ref, cont));
1989  if (!ptr) return ENOMEM;
1990  errno_t e = ptr->Init();
1991  if (e != 0) return e;
1992  e = ptr->GetFuture(next);
1993  if (e != 0) return e;
1994 
1995  ref.value_->common.Lock();
1996  ref.value_->common.cont = ptr.release();
1997  bool isready = ref.IsReady_();
1998  ref.value_->common.Unlock();
1999  if (isready) {
2000  ref.value_->common.cont->DoContinuation();
2001  }
2002  return 0;
2003 }
2004 
2005 } // namespace detail
2006 
2007 template<class R1 = None, class R2 = None, class R3 = None, class R4 = None, class R5 = None>
2008 struct FutureTuple {
2009  Future<R1> f1;
2010  Future<R2> f2;
2011  Future<R3> f3;
2012  Future<R4> f4;
2013  Future<R5> f5;
2014 };
2015 
2016 template<>
2017 struct FutureTuple<None, None, None, None, None>;
2018 template<class R1>
2019 struct FutureTuple<R1, None, None, None, None>;
2020 
2021 template<class R1, class R2>
2022 struct FutureTuple<R1, R2, None, None, None> {
2023  Future<R1> f1;
2024  Future<R2> f2;
2025 };
2026 
2027 template<class R1, class R2, class R3>
2028 struct FutureTuple<R1, R2, R3, None, None> {
2029  Future<R1> f1;
2030  Future<R2> f2;
2031  Future<R3> f3;
2032 };
2033 
2034 template<class R1, class R2, class R3, class R4>
2035 struct FutureTuple<R1, R2, R3, R4, None> {
2036  Future<R1> f1;
2037  Future<R2> f2;
2038  Future<R3> f3;
2039  Future<R4> f4;
2040 };
2041 
2042 template<class R1 = None, class R2 = None, class R3 = None, class R4 = None, class R5 = None>
2044  public:
2048  Future<R4>* f4, Future<R5>* f5) {
2049  return DoWhen(f, f1, f2, f3, f4, f5, CallWhenAll);
2050  }
2052  Future<R4>* f4, Future<R5>* f5) {
2053  return DoWhen(f, f1, f2, f3, f4, f5, CallWhenAny);
2054  }
2055 
2056  private:
2057  typedef UniquePtr<WhenFutureComplete> ArgType;
2058  typedef void (*FuncType)(ArgType& ptr);
2059  static errno_t DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3,
2060  Future<R4>* f4, Future<R5>* f5, FuncType func);
2061  static void Call(ArgType& ptr) {
2062  // called from Thread::Exec()
2063  ptr->func_(ptr);
2064  }
2065  static void CallWhenAny(ArgType& ptr) {
2066  for (;;) {
2067  if (ptr->tuple_->f1.IsReady() || ptr->tuple_->f2.IsReady() ||
2068  ptr->tuple_->f3.IsReady() || ptr->tuple_->f4.IsReady() ||
2069  ptr->tuple_->f5.IsReady()) {
2070  break;
2071  }
2072  this_thread::Sleep(TimeSpan(0, 0, 0, 200));
2073  }
2074  ptr->promise_.SetValue(ptr->tuple_.release());
2075  }
2076  static void CallWhenAll(ArgType& ptr) {
2077  ptr->tuple_->f1.Wait();
2078  ptr->tuple_->f2.Wait();
2079  ptr->tuple_->f3.Wait();
2080  ptr->tuple_->f4.Wait();
2081  ptr->tuple_->f5.Wait();
2082  ptr->promise_.SetValue(ptr->tuple_.release());
2083  }
2084  explicit WhenFutureComplete(FuncType f) : func_(f) {}
2085  errno_t Init(Future<ReturnType>* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3,
2086  Future<R4>* f4, Future<R5>* f5) {
2087  errno_t e = promise_.Init();
2088  if (e != 0) return e;
2089  tuple_.reset(new (std::nothrow) FutureTuple<R1, R2, R3, R4, R5>());
2090  if (!tuple_) return ENOMEM;
2091  e = promise_.GetFuture(f);
2092  if (e != 0) return e;
2093  e = tuple_->f1.MakeSharedFrom(*f1);
2094  if (e != 0) return e;
2095  e = tuple_->f2.MakeSharedFrom(*f2);
2096  if (e != 0) return e;
2097  e = tuple_->f3.MakeSharedFrom(*f3);
2098  if (e != 0) return e;
2099  e = tuple_->f4.MakeSharedFrom(*f4);
2100  if (e != 0) return e;
2101  e = tuple_->f5.MakeSharedFrom(*f5);
2102  if (e != 0) return e;
2103  return 0;
2104  }
2105 
2106  private:
2107  FuncType func_;
2108  ReturnType tuple_;
2109  Promise<ReturnType> promise_;
2110  NLIB_DISALLOW_COPY_AND_ASSIGN(WhenFutureComplete);
2111  friend class Thread;
2112 };
2113 
2114 template<class R1, class R2, class R3, class R4, class R5>
2115 errno_t
2116 WhenFutureComplete<R1, R2, R3, R4, R5>::DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2,
2117  Future<R3>* f3, Future<R4>* f4, Future<R5>* f5,
2118  FuncType func) {
2119  if (!f1 || !f2 || !f3 || !f4 || !f5) return EINVAL;
2120  ArgType ptr(new (std::nothrow) WhenFutureComplete(func));
2121  if (!ptr) return 0;
2122  errno_t e;
2123  e = ptr->Init(f, f1, f2, f3, f4, f5);
2124  if (e != 0) return e;
2125  Thread th;
2126  e = th.StartRaw(ptr);
2127  if (e != 0) return e;
2128  return 0;
2129 }
2130 
2131 template<>
2132 class WhenFutureComplete<None, None, None, None, None>;
2133 template<class R1>
2134 class WhenFutureComplete<R1, None, None, None, None>;
2135 
2136 template<class R1, class R2>
2137 class WhenFutureComplete<R1, R2, None, None, None> {
2138  public:
2139  typedef UniquePtr<FutureTuple<R1, R2> > ReturnType;
2140  typedef Future<ReturnType> FutureType;
2141  static errno_t All(FutureType* f, Future<R1>* f1, Future<R2>* f2) {
2142  return DoWhen(f, f1, f2, CallWhenAll);
2143  }
2144  static errno_t Any(FutureType* f, Future<R1>* f1, Future<R2>* f2) {
2145  return DoWhen(f, f1, f2, CallWhenAny);
2146  }
2147 
2148  private:
2149  typedef UniquePtr<WhenFutureComplete> ArgType;
2150  typedef void (*FuncType)(ArgType& ptr);
2151  static errno_t DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2, FuncType func);
2152  static void Call(ArgType& ptr) {
2153  // called from Thread::Exec()
2154  ptr->func_(ptr);
2155  }
2156  static void CallWhenAny(ArgType& ptr) {
2157  for (;;) {
2158  if (ptr->tuple_->f1.IsReady() || ptr->tuple_->f2.IsReady()) {
2159  break;
2160  }
2161  this_thread::Sleep(TimeSpan(0, 0, 0, 200));
2162  }
2163  ptr->promise_.SetValue(ptr->tuple_.release());
2164  }
2165  static void CallWhenAll(ArgType& ptr) {
2166  ptr->tuple_->f1.Wait();
2167  ptr->tuple_->f2.Wait();
2168  ptr->promise_.SetValue(ptr->tuple_.release());
2169  }
2170  explicit WhenFutureComplete(FuncType f) : func_(f) {}
2171  errno_t Init(Future<ReturnType>* f, Future<R1>* f1, Future<R2>* f2) {
2172  errno_t e = promise_.Init();
2173  if (e != 0) return e;
2174  tuple_.reset(new (std::nothrow) FutureTuple<R1, R2>());
2175  if (!tuple_) return ENOMEM;
2176  e = promise_.GetFuture(f);
2177  if (e != 0) return e;
2178  e = tuple_->f1.MakeSharedFrom(*f1);
2179  if (e != 0) return e;
2180  e = tuple_->f2.MakeSharedFrom(*f2);
2181  if (e != 0) return e;
2182  return 0;
2183  }
2184 
2185  private:
2186  FuncType func_;
2187  ReturnType tuple_;
2188  Promise<ReturnType> promise_;
2189  NLIB_DISALLOW_COPY_AND_ASSIGN(WhenFutureComplete);
2190  friend class Thread;
2191 };
2192 
2193 template<class R1, class R2>
2194 errno_t inline WhenFutureComplete<R1, R2>::DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2,
2195  FuncType func) {
2196  if (!f1 || !f2) return EINVAL;
2197  ArgType ptr(new (std::nothrow) WhenFutureComplete(func));
2198  if (!ptr) return 0;
2199  errno_t e;
2200  e = ptr->Init(f, f1, f2);
2201  if (e != 0) return e;
2202  Thread th;
2203  e = th.StartRaw(ptr);
2204  if (e != 0) return e;
2205  return 0;
2206 }
2207 
2208 template<class R1, class R2, class R3>
2209 class WhenFutureComplete<R1, R2, R3, None, None> {
2210  public:
2211  typedef UniquePtr<FutureTuple<R1, R2, R3> > ReturnType;
2212  typedef Future<ReturnType> FutureType;
2213  static errno_t All(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3) {
2214  return DoWhen(f, f1, f2, f3, CallWhenAll);
2215  }
2216  static errno_t Any(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3) {
2217  return DoWhen(f, f1, f2, f3, CallWhenAny);
2218  }
2219 
2220  private:
2221  typedef UniquePtr<WhenFutureComplete> ArgType;
2222  typedef void (*FuncType)(ArgType& ptr);
2223  static errno_t
2224  DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3, FuncType func);
2225  static void Call(ArgType& ptr) {
2226  // called from Thread::Exec()
2227  ptr->func_(ptr);
2228  }
2229  static void CallWhenAny(ArgType& ptr) {
2230  for (;;) {
2231  if (ptr->tuple_->f1.IsReady() || ptr->tuple_->f2.IsReady() ||
2232  ptr->tuple_->f3.IsReady()) {
2233  break;
2234  }
2235  this_thread::Sleep(TimeSpan(0, 0, 0, 200));
2236  }
2237  ptr->promise_.SetValue(ptr->tuple_.release());
2238  }
2239  static void CallWhenAll(ArgType& ptr) {
2240  ptr->tuple_->f1.Wait();
2241  ptr->tuple_->f2.Wait();
2242  ptr->tuple_->f3.Wait();
2243  ptr->promise_.SetValue(ptr->tuple_.release());
2244  }
2245  explicit WhenFutureComplete(FuncType f) : func_(f) {}
2246  errno_t Init(Future<ReturnType>* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3) {
2247  errno_t e = promise_.Init();
2248  if (e != 0) return e;
2249  tuple_.reset(new (std::nothrow) FutureTuple<R1, R2, R3>());
2250  if (!tuple_) return ENOMEM;
2251  e = promise_.GetFuture(f);
2252  if (e != 0) return e;
2253  e = tuple_->f1.MakeSharedFrom(*f1);
2254  if (e != 0) return e;
2255  e = tuple_->f2.MakeSharedFrom(*f2);
2256  if (e != 0) return e;
2257  e = tuple_->f3.MakeSharedFrom(*f3);
2258  if (e != 0) return e;
2259  return 0;
2260  }
2261 
2262  private:
2263  FuncType func_;
2264  ReturnType tuple_;
2265  Promise<ReturnType> promise_;
2266  NLIB_DISALLOW_COPY_AND_ASSIGN(WhenFutureComplete);
2267  friend class Thread;
2268 };
2269 
2270 template<class R1, class R2, class R3>
2271 inline errno_t WhenFutureComplete<R1, R2, R3>::DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2,
2272  Future<R3>* f3, FuncType func) {
2273  if (!f1 || !f2 || !f3) return EINVAL;
2274  ArgType ptr(new (std::nothrow) WhenFutureComplete(func));
2275  if (!ptr) return 0;
2276  errno_t e;
2277  e = ptr->Init(f, f1, f2, f3);
2278  if (e != 0) return e;
2279  Thread th;
2280  e = th.StartRaw(ptr);
2281  if (e != 0) return e;
2282  return 0;
2283 }
2284 
2285 template<class R1, class R2, class R3, class R4>
2286 class WhenFutureComplete<R1, R2, R3, R4, None> {
2287  public:
2288  typedef UniquePtr<FutureTuple<R1, R2, R3, R4> > ReturnType;
2289  typedef Future<ReturnType> FutureType;
2290  static errno_t
2291  All(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3, Future<R4>* f4) {
2292  return DoWhen(f, f1, f2, f3, f4, CallWhenAll);
2293  }
2294  static errno_t
2295  Any(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3, Future<R4>* f4) {
2296  return DoWhen(f, f1, f2, f3, f4, CallWhenAny);
2297  }
2298 
2299  private:
2300  typedef UniquePtr<WhenFutureComplete> ArgType;
2301  typedef void (*FuncType)(ArgType& ptr);
2302  static errno_t DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3,
2303  Future<R4>* f4, FuncType func);
2304  static void Call(ArgType& ptr) {
2305  // called from Thread::Exec()
2306  ptr->func_(ptr);
2307  }
2308  static void CallWhenAny(ArgType& ptr) {
2309  for (;;) {
2310  if (ptr->tuple_->f1.IsReady() || ptr->tuple_->f2.IsReady() ||
2311  ptr->tuple_->f3.IsReady() || ptr->tuple_->f4.IsReady()) {
2312  break;
2313  }
2314  this_thread::Sleep(TimeSpan(0, 0, 0, 200));
2315  }
2316  ptr->promise_.SetValue(ptr->tuple_.release());
2317  }
2318  static void CallWhenAll(ArgType& ptr) {
2319  ptr->tuple_->f1.Wait();
2320  ptr->tuple_->f2.Wait();
2321  ptr->tuple_->f3.Wait();
2322  ptr->tuple_->f4.Wait();
2323  ptr->promise_.SetValue(ptr->tuple_.release());
2324  }
2325  explicit WhenFutureComplete(FuncType f) : func_(f) {}
2326  errno_t
2327  Init(Future<ReturnType>* f, Future<R1>* f1, Future<R2>* f2, Future<R3>* f3, Future<R4>* f4) {
2328  errno_t e = promise_.Init();
2329  if (e != 0) return e;
2330  tuple_.reset(new (std::nothrow) FutureTuple<R1, R2, R3, R4>());
2331  if (!tuple_) return ENOMEM;
2332  e = promise_.GetFuture(f);
2333  if (e != 0) return e;
2334  e = tuple_->f1.MakeSharedFrom(*f1);
2335  if (e != 0) return e;
2336  e = tuple_->f2.MakeSharedFrom(*f2);
2337  if (e != 0) return e;
2338  e = tuple_->f3.MakeSharedFrom(*f3);
2339  if (e != 0) return e;
2340  e = tuple_->f4.MakeSharedFrom(*f4);
2341  if (e != 0) return e;
2342  return 0;
2343  }
2344 
2345  private:
2346  FuncType func_;
2347  ReturnType tuple_;
2348  Promise<ReturnType> promise_;
2349  NLIB_DISALLOW_COPY_AND_ASSIGN(WhenFutureComplete);
2350  friend class Thread;
2351 };
2352 
2353 template<class R1, class R2, class R3, class R4>
2354 inline errno_t
2355 WhenFutureComplete<R1, R2, R3, R4>::DoWhen(FutureType* f, Future<R1>* f1, Future<R2>* f2,
2356  Future<R3>* f3, Future<R4>* f4, FuncType func) {
2357  if (!f1 || !f2 || !f3 || !f4) return EINVAL;
2358  ArgType ptr(new (std::nothrow) WhenFutureComplete(func));
2359  if (!ptr) return 0;
2360  errno_t e;
2361  e = ptr->Init(f, f1, f2, f3, f4);
2362  if (e != 0) return e;
2363  Thread th;
2364  e = th.StartRaw(ptr);
2365  if (e != 0) return e;
2366  return 0;
2367 }
2368 
2369 } // namespace threading
2370 NLIB_NAMESPACE_END
2371 
2372 NLIB_DEFINE_STD_SWAP_T_BEGIN3(nn, nlib, threading)
2373 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::Future)
2374 NLIB_DEFINE_STD_SWAP_T1(R, NLIB_NS::threading::Promise)
2375 NLIB_DEFINE_STD_SWAP_T1(T, NLIB_NS::threading::PackagedTask)
2376 NLIB_DEFINE_STD_SWAP_T_END3(nn, nlib, threading)
2377 
2378 #endif // INCLUDE_NN_NLIB_THREADING_FUTURE_H_
errno_t MakeReadyFuture(Future< R > *future, const R &value)
Creates a Future with preset values.
Definition: Future.h:1927
#define NLIB_OVERRIDE
Defines override if it is available for use. If not, holds an empty string.
Definition: Config.h:249
errno_t Async(Future< R > *future, const FUNC &func, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, move_tag)
Async that moves arguments and function objects.
Definition: Future.h:1919
static errno_t Any(FutureType *f, Future< R1 > *f1, Future< R2 > *f2, Future< R3 > *f3, Future< R4 > *f4, Future< R5 > *f5)
When an error has been set to any of Future f1, f2, f3, f4, and f5, a value is set in f...
Definition: Future.h:2051
errno_t Sleep(const TimeSpan &span) noexcept
Makes the thread sleep for a specified period of time.
Definition: Thread.h:817
Substitute definitions for the C++11 standard header type_traits. These substitute definitions are us...
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:183
Implements mutex, reentrant timeout mutex, and reentrant mutex.
errno_t nlib_mutex_unlock(nlib_mutex *mutex) NLIB_RELEASE(*mutex)
Unlocks the specified mutex.
errno_t Wait() noexcept
Waits for conditions that allow results to be acquired.
Definition: Future.h:644
errno_t nlib_cond_broadcast(nlib_cond *cond)
Resumes the execution of all threads that are waiting for the conditional variable cond...
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
Definition: Base64.h:25
Future(Future &rhs, move_tag) noexcept
Corresponds to a move constructor.
Definition: Future.h:614
errno_t nlib_cond_init(nlib_cond *cond)
Initializes a condition variable.
void SetDetachState(bool detached) noexcept
Sets whether to start a thread in a detached state.
Definition: Thread.h:39
errno_t GetFuture(Future< R > *p) noexcept
Sets Future to get the result of execution.
Definition: Future.h:336
In the C++11 environment (which supports alias templates), std::unique_ptr is made an alias template...
Definition: UniquePtr.h:108
Defines that class that is corresponding to std::unique_ptr.
Promise & assign(Promise &rhs, move_tag) noexcept
Corresponds to a move assignment operator.
Definition: Future.h:327
errno_t WaitUntil(const DateTime &datetime) noexcept
Waits for conditions that allow results to be acquired, until the defined time.
Definition: Future.h:648
Class that calls the result of thread execution and outputs it in a thread safe manner. This class is similar to the std::promise class of C++11.
Definition: Future.h:43
R Get()
Calls Get(R* ptr) after creating an object for the type that will be used internally as the value...
Definition: Future.h:619
errno_t nlib_mutex_init(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Initializes a mutex.
The class for representing the date and time.
Definition: DateTime.h:231
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:87
bool IsValid() const noexcept
Definition: Future.h:642
errno_t nlib_cond_wait(nlib_cond *cond, nlib_mutex *mutex) NLIB_REQUIRES(*mutex)
Unlocks mutex and waits for a condition variable. It then relocks mutex after execution resumes...
errno_t WaitFor(const TimeSpan &span) noexcept
Waits for conditions that allow results to be acquired, for a specified amount of time...
Definition: Future.h:645
#define NLIB_ATOMIC_ACQUIRE
Similar to __ATOMIC_ACQUIRE of gcc or std::memory_order_acquire of C++11.
Defines a Future for which to set the value, under the condition that a value has been set for the Fu...
Definition: Future.h:2043
errno_t SetError(errno_t e) noexcept
Sets an error value.
Definition: Future.h:335
Class to wrap nlib_thread_attr. nlib_thread_attr_init() and nlib_thread_attr_destroy() are run automa...
Definition: Thread.h:29
errno_t nlib_mutex_lock(nlib_mutex *mutex) NLIB_ACQUIRE(*mutex)
Locks the specified mutex.
An empty structure indicating that an argument to a function needs to be moved.
Definition: Config.h:270
errno_t MakeSharedFrom(const Future &f) noexcept
Shares a Future so that it may be viewed.
Definition: Future.h:655
static errno_t All(FutureType *f, Future< R1 > *f1, Future< R2 > *f2, Future< R3 > *f3, Future< R4 > *f4, Future< R5 > *f5)
When an error has been set to all Future f1, f2, f3, f4, and f5, sets a value to f.
Definition: Future.h:2047
#define NLIB_CATCH(x)
Defines catch(x) if exceptions are enabled. If not, defines if (true).
Definition: Config.h:147
Defines the thread.
#define NLIB_TRY
Defines try if exceptions are enabled. If not, defines if (true).
Definition: Config.h:146
errno_t nlib_cond_destroy(nlib_cond *cond)
Destroys a condition variable object.
errno_t Get(R *ptr)
Waits until a result is acquired, and then gets the result.
Definition: Future.h:626
Defines the class for handling times and durations.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:109
pthread_cond_t nlib_cond
The type for a condition variable object.
errno_t GetFutureError(FutureResult &result) noexcept
Function that enables systems to get error values when threads hold an error value.
Definition: Future.h:35
Class that gets the output of a different thread executing in a thread safe manner. This class is similar to the std::shared_future class of C++11.
Definition: AsyncFileIo.h:26
Future< R > FutureType
The type for Future<R>.
Definition: Future.h:311
Wraps objects like CriticalSection. Locks with a constructor, and unlocks with a destructor.
pthread_mutex_t nlib_mutex
The type for mutex variables.
Class that wraps a function to run in a different thread, and gets the return value in a thread safe ...
Definition: Future.h:1083
Promise() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Future.h:312
bool IsReady() const noexcept
Returns whether a value has been set for Future (whether Promise set a value or an error)...
Definition: Future.h:643
int nlib_atomic_compare_exchange32(int32_t *ptr, int32_t *expected, int32_t desired, int weak, int success_memorder, int failure_memorder)
Compares and swaps atomic values. Its behavior is similar to the one for __atomic_compare_exchange_n(...
PackagedTask< T > ThisType
The object type.
Definition: Future.h:1085
The class for representing the time.
Definition: DateTime.h:97
errno_t Then(Future< RNEXT > *next, RNEXT(*cont)(Future< R > &)) noexcept
Registers the process to continue (continuation) to this future.
Definition: Future.h:652
Future< ReturnType > FutureType
Type of the newly created Future.
Definition: Future.h:2046
Future() noexcept
Instantiates the object with default parameters (default constructor).
Definition: Future.h:601
Future & assign(Future &rhs, move_tag) noexcept
Corresponds to a move assignment operator.
Definition: Future.h:615
errno_t Init() noexcept
Initializes the object.
Definition: Future.h:334
Promise(Promise &rhs, move_tag) noexcept
Corresponds to a move constructor.
Definition: Future.h:326
errno_t nlib_mutex_destroy(nlib_mutex *mutex) NLIB_EXCLUDES(*mutex)
Destroys the specified mutex object and frees any associated resources.
errno_t nlib_cond_wait_until(nlib_cond *cond, nlib_mutex *mutex, nlib_time abstime) NLIB_REQUIRES(*mutex)
Unlocks mutex and waits until abstime for a condition variable. It then relocks mutex after execution...
UniquePtr< FutureTuple< R1, R2, R3, R4, R5 > > ReturnType
Type of value to set to the newly created Future.
Definition: Future.h:2045
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37