git.iko.soy/rowtype-yoga/purescript-native
on cpp help sign in
92 lines 2.2 kB history raw
1///////////////////////////////////////////////////////////////////////////////
2//
3// Module : recursion.h
4// Copyright : (c) Andy Arvanitis 2019
5// License : BSD
6//
7// Maintainer : Andy Arvanitis
8// Stability : experimental
9// Portability :
10//
11// Runtime types to support recursion
12//
13///////////////////////////////////////////////////////////////////////////////
14//
15#ifndef purescript_recursion_H
16#define purescript_recursion_H
18#include <memory>
20namespace purescript {
22 namespace _template_ {
24 template <typename T>
25 class weak {
26 std::weak_ptr<void> wptr;
28 public:
29 weak() = delete;
30 weak(T& b) : wptr(b.shared) {}
32 auto shared() const -> std::shared_ptr<void> {
33#if defined(NDEBUG)
34 return wptr.lock();
35#else
36 return static_cast<std::shared_ptr<void>>(wptr);
37#endif
38 }
40 }; // class weak
42 template <typename T>
43 class recur {
44 std::shared_ptr<T> sptr;
45 std::shared_ptr<typename T::weak> wptr;
47 public:
48 recur() : sptr(std::make_shared<T>())
49 , wptr(std::make_shared<typename T::weak>(*sptr)) {}
51 auto shared() const -> std::shared_ptr<void> {
52 return sptr->shared;
53 }
55 auto operator()() const -> T {
56 return (*sptr)();
57 }
59 auto operator()(const T& arg) const -> T {
60 return (*sptr)(arg);
61 }
63 template <typename U>
64 auto operator=(U&& right) -> recur& {
65 *sptr = std::forward<U>(right);
66 *wptr = *sptr;
67 return *this;
68 }
70 class weak {
71 std::shared_ptr<typename T::weak> wptr;
72 public:
73 weak(const recur& r) : wptr(r.wptr) {}
75 auto shared() const -> std::shared_ptr<void> {
76 return wptr->shared();
77 }
79 auto operator()() const -> T {
80 return static_cast<T>(*wptr)();
81 }
83 auto operator()(const T& arg) const -> T {
84 return static_cast<T>(*wptr)(arg);
85 }
86 }; // class recur::weak
87 }; // class recur
89 } // namespace _template_
90} // namespace purescript
92#endif // purescript_recursion_H