/////////////////////////////////////////////////////////////////////////////// // // Module : recursion.h // Copyright : (c) Andy Arvanitis 2019 // License : BSD // // Maintainer : Andy Arvanitis // Stability : experimental // Portability : // // Runtime types to support recursion // /////////////////////////////////////////////////////////////////////////////// // #ifndef purescript_recursion_H #define purescript_recursion_H #include namespace purescript { namespace _template_ { template class weak { std::weak_ptr wptr; public: weak() = delete; weak(T& b) : wptr(b.shared) {} auto shared() const -> std::shared_ptr { #if defined(NDEBUG) return wptr.lock(); #else return static_cast>(wptr); #endif } }; // class weak template class recur { std::shared_ptr sptr; std::shared_ptr wptr; public: recur() : sptr(std::make_shared()) , wptr(std::make_shared(*sptr)) {} auto shared() const -> std::shared_ptr { return sptr->shared; } auto operator()() const -> T { return (*sptr)(); } auto operator()(const T& arg) const -> T { return (*sptr)(arg); } template auto operator=(U&& right) -> recur& { *sptr = std::forward(right); *wptr = *sptr; return *this; } class weak { std::shared_ptr wptr; public: weak(const recur& r) : wptr(r.wptr) {} auto shared() const -> std::shared_ptr { return wptr->shared(); } auto operator()() const -> T { return static_cast(*wptr)(); } auto operator()(const T& arg) const -> T { return static_cast(*wptr)(arg); } }; // class recur::weak }; // class recur } // namespace _template_ } // namespace purescript #endif // purescript_recursion_H