Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'wifi_rate_zero' into 'master'
[simgrid.git] / include / simgrid / kernel / future.hpp
index 7b2941e..ac6a448 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2019. The SimGrid Team.
+/* Copyright (c) 2016-2022. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -17,7 +17,7 @@
 
 #include <xbt/base.h>
 #include <xbt/functional.hpp>
-#include <xbt/future.hpp>
+#include <xbt/promise.hpp>
 
 namespace simgrid {
 namespace kernel {
@@ -48,7 +48,7 @@ public:
   FutureStateBase(FutureStateBase const&) = delete;
   FutureStateBase& operator=(FutureStateBase const&) = delete;
 
-  XBT_PUBLIC void schedule(simgrid::xbt::Task<void()>&& job);
+  XBT_PUBLIC void schedule(simgrid::xbt::Task<void()>&& job) const;
 
   void set_exception(std::exception_ptr exception)
   {
@@ -116,8 +116,7 @@ protected:
    **/
   void resolve()
   {
-    if (status_ != FutureStatus::ready)
-      xbt_die("Deadlock: this future is not ready");
+    xbt_assert(status_ == FutureStatus::ready, "Deadlock: this future is not ready");
     status_ = FutureStatus::done;
     if (exception_) {
       std::exception_ptr exception = std::move(exception_);
@@ -142,7 +141,6 @@ private:
 template<class T>
 class FutureState : public FutureStateBase {
 public:
-
   void set_value(T value)
   {
     if (this->get_status() != FutureStatus::not_ready)
@@ -280,17 +278,12 @@ class Future {
 public:
   Future() = default;
   explicit Future(std::shared_ptr<FutureState<T>> state) : state_(std::move(state)) {}
-  ~Future() = default;
 
   // Move type:
   Future(Future&) = delete;
-  Future& operator=(Future&) = delete;
-  Future(Future&& that) : state_(std::move(that.state_)) {}
-  Future& operator=(Future&& that)
-  {
-    state_ = std::move(that.state_);
-    return *this;
-  }
+  Future& operator=(const Future&) = delete;
+  Future(Future&&) noexcept        = default;
+  Future& operator=(Future&&) noexcept = default;
 
   /** Whether the future is valid:.
    *
@@ -334,7 +327,7 @@ public:
    */
   template <class F> auto then_no_unwrap(F continuation) -> Future<decltype(continuation(std::move(*this)))>
   {
-    typedef decltype(continuation(std::move(*this))) R;
+    using R = decltype(continuation(std::move(*this)));
     if (state_ == nullptr)
       throw std::future_error(std::future_errc::no_state);
     auto state = std::move(state_);
@@ -363,19 +356,16 @@ public:
    * @exception std::future_error no state is associated with the future
    */
   template <class F>
-  auto then(F continuation) -> typename std::enable_if<not is_future<decltype(continuation(std::move(*this)))>::value,
-                                                       Future<decltype(continuation(std::move(*this)))>>::type
+  auto then(F continuation) -> typename std::enable_if_t<not is_future<decltype(continuation(std::move(*this)))>::value,
+                                                         Future<decltype(continuation(std::move(*this)))>>
   {
     return this->then_no_unwrap(std::move(continuation));
   }
 
   /** Attach a continuation to this future (future chaining) */
-  template<class F>
-  auto then(F continuation)
-  -> typename std::enable_if<
-       is_future<decltype(continuation(std::move(*this)))>::value,
-       decltype(continuation(std::move(*this)))
-     >::type
+  template <class F>
+  auto then(F continuation) -> typename std::enable_if_t<is_future<decltype(continuation(std::move(*this)))>::value,
+                                                         decltype(continuation(std::move(*this)))>
   {
     return unwrap_future(this->then_no_unwrap(std::move(continuation)));
   }
@@ -423,7 +413,7 @@ template <class T> Future<T> unwrap_future(Future<Future<T>> future)
  *  auto promise = std::make_shared<simgrid::kernel::Promise<T>>();
  *  auto future = promise->get_future();
  *
- *  simgrid::simix::Timer::set(date, [promise] {
+ *  simgrid::kernel::timer::Timer::set(date, [promise] {
  *    try {
  *      int value = compute_the_value();
  *      if (value < 0)
@@ -446,19 +436,15 @@ template <class T> Future<T> unwrap_future(Future<Future<T>> future)
 template<class T>
 class Promise {
 public:
-  Promise() : state_(std::make_shared<FutureState<T>>()) {}
+  Promise() = default;
   explicit Promise(std::shared_ptr<FutureState<T>> state) : state_(std::move(state)) {}
 
   // Move type
   Promise(Promise const&) = delete;
   Promise& operator=(Promise const&) = delete;
-  Promise(Promise&& that) :
-    state_(std::move(that.state_)), future_get_(that.future_get_)
-  {
-    that.future_get_ = false;
-  }
+  Promise(Promise&& that) noexcept : state_(std::move(that.state_)) { std::swap(future_get_, that.future_get_); }
 
-  Promise& operator=(Promise&& that)
+  Promise& operator=(Promise&& that) noexcept
   {
     this->state_ = std::move(that.state_);
     this->future_get_ = that.future_get_;
@@ -494,14 +480,14 @@ public:
   }
 
 private:
-  std::shared_ptr<FutureState<T>> state_;
+  std::shared_ptr<FutureState<T>> state_ = std::make_shared<FutureState<T>>();
   bool future_get_ = false;
 };
 
 template<>
 class Promise<void> {
 public:
-  Promise() : state_(std::make_shared<FutureState<void>>()) {}
+  Promise() = default;
   explicit Promise(std::shared_ptr<FutureState<void>> state) : state_(std::move(state)) {}
   ~Promise()
   {
@@ -513,12 +499,8 @@ public:
   // Move type
   Promise(Promise const&) = delete;
   Promise& operator=(Promise const&) = delete;
-  Promise(Promise&& that) :
-    state_(std::move(that.state_)), future_get_(that.future_get_)
-  {
-    that.future_get_ = false;
-  }
-  Promise& operator=(Promise&& that)
+  Promise(Promise&& that) noexcept : state_(std::move(that.state_)) { std::swap(future_get_, that.future_get_); }
+  Promise& operator=(Promise&& that) noexcept
   {
     this->state_ = std::move(that.state_);
     this->future_get_ = that.future_get_;
@@ -535,13 +517,13 @@ public:
     future_get_ = true;
     return Future<void>(state_);
   }
-  void set_value()
+  void set_value() const
   {
     if (state_ == nullptr)
       throw std::future_error(std::future_errc::no_state);
     state_->set_value();
   }
-  void set_exception(std::exception_ptr exception)
+  void set_exception(std::exception_ptr exception) const
   {
     if (state_ == nullptr)
       throw std::future_error(std::future_errc::no_state);
@@ -549,7 +531,7 @@ public:
   }
 
 private:
-  std::shared_ptr<FutureState<void>> state_;
+  std::shared_ptr<FutureState<void>> state_ = std::make_shared<FutureState<void>>();
   bool future_get_ = false;
 };