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///////////////////////////////////////////////////////////////////////////////
25#if !defined(PURESCRIPT_DISABLE_EXCEPTIONS)
29#include "dictionary.h"
38 std::shared_ptr<void> shared;
46 using fn_t = _template_::fn_t<boxed>;
47 using eff_fn_t = _template_::eff_fn_t<boxed>;
49 using dict_t = _template_::dict_t<boxed>;
50 using array_t = std::vector<boxed>;
52 using weak = _template_::weak<boxed>;
53 using recur = _template_::recur<boxed>;
57 using fn_T = _template_::fn_T<boxed, T>;
60 using eff_fn_T = _template_::eff_fn_T<boxed, T>;
63 boxed() noexcept : shared() {}
64 boxed(const std::nullptr_t) noexcept : shared() {}
66 boxed(const weak& w) : shared(w.shared()) {}
67 boxed(const recur& r) : shared(r.shared()) {}
68 boxed(const recur::weak& w) : shared(w.shared()) {}
71 boxed(std::shared_ptr<T>&& other) noexcept : shared(std::move(other)) {}
74 boxed(const std::shared_ptr<T>& other) : shared(other) {}
76 boxed(const int n) noexcept : _int_(n) {}
78 boxed(const unsigned long n);
79 boxed(const double n) noexcept : _double_(n) {}
80 boxed(const bool b) noexcept : _bool_(b) {}
81 boxed(const char s[]) : shared(std::make_shared<string>(s)) {}
82 boxed(string&& s) : shared(std::make_shared<string>(std::move(s))) {}
83 boxed(const string& s) : shared(std::make_shared<string>(s)) {}
84 boxed(array_t&& l) : shared(std::make_shared<array_t>(std::move(l))) {}
85 boxed(const array_t& l) : shared(std::make_shared<array_t>(l)) {}
86 boxed(dict_t&& m) : shared(std::make_shared<dict_t>(std::move(m))) {}
87 boxed(const dict_t& m) : shared(std::make_shared<dict_t>(m)) {}
90 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
92 typename std::enable_if<std::is_same<decltype(std::declval<T>()(std::declval<boxed>())),
93 boxed>::value>::type* = 0)
94 : shared(std::shared_ptr<fn_t>(std::make_shared<fn_T<T>>(std::move(f)))) {
98 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
100 typename std::enable_if<std::is_same<decltype(std::declval<T>()()),
101 boxed>::value>::type* = 0)
102 : shared(std::shared_ptr<eff_fn_t>(std::make_shared<eff_fn_T<T>>(std::move(f)))) {
105 auto get() const noexcept -> void * {
109 auto operator()(const boxed& arg) const -> boxed {
110 return (*static_cast<fn_t*>(shared.get()))(arg);
113 auto operator()() const -> boxed {
114 return (*static_cast<eff_fn_t*>(shared.get()))();
117 auto operator[](const char key[]) const -> const boxed& {
118 return (*static_cast<const dict_t*>(shared.get()))[key];
121 auto operator[](const char key[]) -> boxed& {
122 return (*static_cast<dict_t*>(shared.get()))[key];
125 auto operator[](const int index) const -> const boxed&;
126 auto operator[](const int index) -> boxed&;
130 extern template class _template_::fn_t<boxed>;
131 extern template class _template_::eff_fn_t<boxed>;
132 extern template class _template_::dict_t<boxed>;
133 extern template class _template_::weak<boxed>;
134 extern template class _template_::recur<boxed>;
136 extern const boxed undefined;
138 using fn_t = boxed::fn_t;
139 using eff_fn_t = boxed::eff_fn_t;
140 using dict_t = boxed::dict_t;
141 using array_t = boxed::array_t;
143 template <typename T, typename... Args,
144 typename = typename std::enable_if<!std::is_same<T, int>::value &&
145 !std::is_same<T, double>::value &&
146 !std::is_same<T, bool>::value
148 inline auto box(Args&&... args) -> boxed {
149 return std::make_shared<T>(std::forward<Args>(args)...);
152 template <typename T,
153 typename std::enable_if<std::is_same<T, int>::value, T>::type* = nullptr>
154 inline auto box(T arg) noexcept -> boxed {
158 template <typename T,
159 typename std::enable_if<std::is_same<T, double>::value, T>::type* = nullptr>
160 inline auto box(T arg) noexcept -> boxed {
164 template <typename T,
165 typename std::enable_if<std::is_same<T, bool>::value, T>::type* = nullptr>
166 inline auto box(T arg) noexcept -> boxed {
170 template <typename T,
171 typename = typename std::enable_if<!std::is_same<T, int>::value &&
172 !std::is_same<T, double>::value &&
173 !std::is_same<T, bool>::value
175 constexpr auto unbox(const boxed& b) -> const T& {
176 return *static_cast<const T*>(b.get());
179 template <typename T,
180 typename std::enable_if<std::is_same<T, int>::value, T>::type* = nullptr>
181 constexpr auto unbox(const boxed& b) noexcept -> T {
185 template <typename T,
186 typename std::enable_if<std::is_same<T, double>::value, T>::type* = nullptr>
187 constexpr auto unbox(const boxed& b) noexcept -> T {
191 template <typename T,
192 typename std::enable_if<std::is_same<T, bool>::value, T>::type* = nullptr>
193 constexpr auto unbox(const boxed& b) noexcept -> T {
197 template <typename T,
198 typename = typename std::enable_if<!std::is_same<T, int>::value &&
199 !std::is_same<T, double>::value &&
200 !std::is_same<T, bool>::value
202 constexpr auto unbox(boxed& b) -> T& {
203 return *static_cast<T*>(b.get());
206 template <typename T>
207 constexpr auto unbox(const T value) noexcept -> T {
211 template <typename T,
212 typename = typename std::enable_if<std::is_same<T, int>::value>::type>
213 constexpr auto unbox(const std::size_t value) noexcept -> long long {
217 inline auto array_length(const boxed& a) -> boxed::array_t::size_type {
218 return unbox<boxed::array_t>(a).size();
221} // namespace purescript
223#if !defined(PURESCRIPT_DISABLE_EXCEPTIONS)
224#define THROW_(e) throw std::runtime_error(s)
226#define THROW_(e) return undefined
229#define DEFINE_FOREIGN_DICTIONARY_AND_ACCESSOR() \
230 inline auto foreign() -> dict_t& {\
235#define FOREIGN_BEGIN(NS) namespace NS {\
236 using namespace purescript;\
237 DEFINE_FOREIGN_DICTIONARY_AND_ACCESSOR()\
238 static const auto data = ([]() -> char {\
239 dict_t& exports = foreign();
240#define FOREIGN_END return 0; }()); }
242#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