Home | History | Annotate | Download | only in support
      1 // -*- C++ -*-
      2 //===----------------------------------------------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef SUPPORT_COROUTINE_TYPES_H
     12 #define SUPPORT_COROUTINE_TYPES_H
     13 
     14 #include <experimental/coroutine>
     15 
     16 template <typename Ty> struct generator {
     17   struct promise_type {
     18     Ty current_value;
     19     std::experimental::suspend_always yield_value(Ty value) {
     20       this->current_value = value;
     21       return {};
     22     }
     23     std::experimental::suspend_always initial_suspend() { return {}; }
     24     std::experimental::suspend_always final_suspend() { return {}; }
     25     generator get_return_object() { return generator{this}; };
     26     void return_void() {}
     27     void unhandled_exception() {}
     28   };
     29 
     30   struct iterator {
     31     std::experimental::coroutine_handle<promise_type> _Coro;
     32     bool _Done;
     33 
     34     iterator(std::experimental::coroutine_handle<promise_type> Coro, bool Done)
     35         : _Coro(Coro), _Done(Done) {}
     36 
     37     iterator &operator++() {
     38       _Coro.resume();
     39       _Done = _Coro.done();
     40       return *this;
     41     }
     42 
     43     bool operator==(iterator const &_Right) const {
     44       return _Done == _Right._Done;
     45     }
     46 
     47     bool operator!=(iterator const &_Right) const { return !(*this == _Right); }
     48 
     49     Ty const &operator*() const { return _Coro.promise().current_value; }
     50 
     51     Ty const *operator->() const { return &(operator*()); }
     52   };
     53 
     54   iterator begin() {
     55     p.resume();
     56     return {p, p.done()};
     57   }
     58 
     59   iterator end() { return {p, true}; }
     60 
     61   generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; }
     62 
     63   ~generator() {
     64     if (p)
     65       p.destroy();
     66   }
     67 
     68 private:
     69   explicit generator(promise_type *p)
     70       : p(std::experimental::coroutine_handle<promise_type>::from_promise(*p)) {}
     71 
     72   std::experimental::coroutine_handle<promise_type> p;
     73 };
     74 
     75 #endif // SUPPORT_COROUTINE_TYPES_H
     76