
#ifndef CONTEXT_SWITCHER_CONTINUATION_H_
#define CONTEXT_SWITCHER_CONTINUATION_H_

#include "assembly_bindings.h"

#include <cstdlib>
#include <cstdio>

namespace context_switcher {

/**
 * One-Shot continuation. Represents the paused state of an execution thread.
 * Can be used exactly once to jump back to that state.
 *
 * Move only to ensure semantics of one time use.
 */
struct continuation {
 public:
  continuation() : cont_pointer_{nullptr} {};
  explicit continuation(assembly_bindings::continuation_t cont_pointer) : cont_pointer_{cont_pointer} {};

  // Move-Only Semantics
  continuation(const continuation &other) = delete;
  continuation(continuation &&other) noexcept {
    cont_pointer_ = other.cont_pointer_;
    other.cont_pointer_ = nullptr;
  }

  continuation &operator=(const continuation &other) = delete;
  continuation &operator=(continuation &&other) noexcept {
    cont_pointer_ = other.cont_pointer_;
    other.cont_pointer_ = nullptr;

    return *this;
  }

  // Semantics as 'one time use'
  bool valid() const {
    return cont_pointer_ != nullptr;
  }

  assembly_bindings::continuation_t consume() {
    if (cont_pointer_ == nullptr) {
      printf("Error!\n");
    }

    auto tmp = cont_pointer_;
    cont_pointer_ = nullptr;
    return tmp;
  }

 private:
  assembly_bindings::continuation_t cont_pointer_;
};

}

#endif //CONTEXT_SWITCHER_CONTINUATION_H_
