1///////////////////////////////////////////////////////////////////////////////
3// Module : purescript.h
4// Copyright : (c) Andy Arvanitis 2018
7// Maintainer : Andy Arvanitis
8// Stability : experimental
11// Basic types and functions to support purescript-to-C++ rendering
13///////////////////////////////////////////////////////////////////////////////
30 class boxed : public std::shared_ptr<void> {
33 using fn_t = std::function<boxed(const boxed&)>;
34 using eff_fn_t = std::function<boxed(void)>;
35 using dict_t = std::map<const string, boxed>;
36 using array_t = std::deque<boxed>;
39 using std::shared_ptr<void>::shared_ptr;
41 boxed(const int n) : std::shared_ptr<void>(std::make_shared<int>(n)) {
44 boxed(const long n) : std::shared_ptr<void>(std::make_shared<int>(static_cast<int>(n))) {
46 if (n < std::numeric_limits<int>::min() || n > std::numeric_limits<int>::max()) {
47 throw std::runtime_error("integer out of range");
52 boxed(const double n) : std::shared_ptr<void>(std::make_shared<double>(n)) {
55 boxed(const bool b) : std::shared_ptr<void>(std::make_shared<bool>(b)) {
58 boxed(const char s[]) : std::shared_ptr<void>(std::make_shared<string>(s)) {
61 boxed(string&& s) : std::shared_ptr<void>(std::make_shared<string>(std::move(s))) {
64 boxed(const std::nullptr_t) : std::shared_ptr<void>() {
67 boxed(array_t&& l) : std::shared_ptr<void>(std::make_shared<array_t>(std::move(l))) {
70 boxed(dict_t&& m) : std::shared_ptr<void>(std::make_shared<dict_t>(std::move(m))) {
74 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
76 typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<fn_t>(f)) {
80 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
82 typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
86 typename = typename std::enable_if<!std::is_same<boxed,T>::value &&
87 std::is_convertible<T,fn_t>::value>::type>
88 auto operator=(const T& right) -> boxed& {
89 if (std::shared_ptr<void>::operator bool()) {
90 auto& f = *static_cast<fn_t*>(get());
93 reset(new fn_t(right));
98 auto operator()(const boxed& arg) const -> boxed {
99 auto& f = *static_cast<fn_t*>(get());
103 auto operator()() const -> boxed {
104 auto& f = *static_cast<eff_fn_t*>(get());
108 auto operator[](const string& key) const -> const boxed& {
109 const auto& dict = *static_cast<const dict_t*>(get());
113 auto operator[](const string& key) -> boxed& {
114 auto& dict = *static_cast<dict_t*>(get());
119 auto operator[](const int index) const -> const boxed& {
120 const auto& array = *static_cast<const array_t*>(get());
124 auto operator[](const int index) -> boxed& {
125 auto& array = *static_cast<array_t*>(get());
129 auto operator[](const int index) const -> const boxed& {
130 const auto& array = *static_cast<const array_t*>(get());
131 return array.at(index);
134 auto operator[](const int index) -> boxed& {
135 auto& array = *static_cast<array_t*>(get());
136 return array.at(index);
143 template <typename T, typename... Args>
144 inline auto box(Args&&... args) -> boxed {
145 return std::make_shared<T>(std::forward<Args>(args)...);
148 template <typename T>
149 inline auto unbox(const boxed& b) -> const T& {
150 const auto& unboxed = *static_cast<const T*>(b.get());
154 template <typename T,
155 typename = typename std::enable_if<!std::is_same<T, const boxed&>::value>::type>
156 constexpr auto unbox(const T value) -> T {
160 template <typename T>
161 inline auto peek(boxed& b) -> T& {
162 auto& unboxed = *static_cast<T*>(b.get());
166 template <typename T>
167 inline auto copy(const boxed& b) -> boxed {
168 return box<T>(unbox<T>(b));
171 using fn_t = boxed::fn_t;
172 using eff_fn_t = boxed::eff_fn_t;
173 using dict_t = boxed::dict_t;
174 using array_t = boxed::array_t;
176 constexpr auto undefined = nullptr;
178} // namespace purescript
180#define FOREIGN_BEGIN(NS) namespace NS {\
181 using namespace purescript;\
182 auto _foreign_() -> dict_t&;\
183 static const auto& NS ## _foreign_init = []() {\
184 dict_t& exports = _foreign_();
185#define FOREIGN_END return exports; }(); }
187#endif // purescript_H
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list