1///////////////////////////////////////////////////////////////////////////////
3// Module : purescript.hh
4// Copyright : (c) Andy Arvanitis 2015
7// Maintainer : Andy Arvanitis <andy.arvanitis@gmail.com>
8// Stability : experimental
11// Basic types and functions to support purescript-to-C++1x rendering
13///////////////////////////////////////////////////////////////////////////////
36#define DECLARE_OPERATOR(op, ty, rty) \
37 friend auto operator op (const any&, ty) -> rty; \
38 friend auto operator op (ty, const any&) -> rty;
40#define DECLARE_COMPARISON_OPERATOR(op) \
41 friend auto operator op (const any&, const any&) -> bool; \
42 DECLARE_OPERATOR(op, long, bool) \
43 DECLARE_OPERATOR(op, double, bool) \
44 DECLARE_OPERATOR(op, char, bool) \
45 DECLARE_OPERATOR(op, const char *, bool)
50using string = const char *;
51using nullptr_t = std::nullptr_t;
53// Workaround for missing C++11 version in gcc
54class runtime_error : public std::runtime_error {
56 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
59const bool undefined = false;
60const size_t constructor = 0;
62// A variant data class designed to provide some features of dynamic typing.
67 enum class Type : int8_t {
86 mutable Type type = Type::Unknown;
87 using vector = std::vector<any>;
92 static constexpr as_thunk unthunk = as_thunk{};
94 using map = std::vector<std::pair<const char * const, const any>>;
96 using array = std::deque<any>;
97 using fn = auto (*)(const any&) -> any;
98 using thunk = auto (*)(const as_thunk) -> const any&;
103 virtual auto operator()(const any&) const -> any = 0;
104 virtual auto operator()(const any&, const any&) const -> any = 0;
105 virtual auto operator()(const any&, const any&, const any&) const -> any = 0;
108 template <typename T>
109 class _closure : public closure {
112 _closure(const T& l) noexcept : lambda(l) {}
113 auto operator()(const any& arg) const -> any {
116 auto operator()(const any& arg1, const any& arg2) const -> any {
117 return lambda(arg1)(arg2);
119 auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
120 return lambda(arg1)(arg2)(arg3);
124 template <typename T>
125 class _closure2 : public closure {
128 _closure2(const T& l) noexcept : lambda(l) {}
129 auto operator()(const any& arg1) const -> any {
130 return [=](const any& arg2) -> any {
131 return lambda(arg1, arg2);
134 auto operator()(const any& arg1, const any& arg2) const -> any {
135 return lambda(arg1, arg2);
137 auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
138 return lambda(arg1, arg2)(arg3);
142 template <typename T>
143 class _closure3 : public closure {
146 _closure3(const T& l) noexcept : lambda(l) {}
147 auto operator()(const any& arg1) const -> any {
148 return [=](const any& arg2) -> any {
149 return [=](const any& arg3) -> any {
150 return lambda(arg1, arg2, arg3);
154 auto operator()(const any& arg1, const any& arg2) const -> any {
155 return [=](const any& arg3) -> any {
156 return lambda(arg1, arg2, arg3);
159 auto operator()(const any& arg1, const any& arg2, const any& arg3) const -> any {
160 return lambda(arg1, arg2, arg3);
166 virtual auto operator()() const -> any = 0;
169 template <typename T>
170 class _eff_fn : public eff_fn {
173 _eff_fn(const T& l) noexcept : lambda(l) {}
174 auto operator()() const -> any {
180 template <typename T>
181 using shared = std::shared_ptr<T>;
183 template <typename T, typename... Args>
184 inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
185 return std::make_shared<T>(std::forward<Args>(args)...);
195 mutable shared<std::string> s;
196 mutable shared<map> m;
197 mutable shared<vector> v;
198 mutable shared<array> a;
200 mutable shared<closure> l;
201 mutable shared<eff_fn> e;
203 mutable shared<void> p;
208 any(const long val) : type(Type::Integer), i(val) {}
209 any(const int val) : type(Type::Integer), i(val) {}
210 any(const unsigned int val) : type(Type::Integer), i(val) {}
211 any(const double val) : type(Type::Double), d(val) {}
212 any(const char val) : type(Type::Character), c(val) {}
214 template <typename T, typename = typename std::enable_if<std::is_same<bool,T>::value>::type>
215 any(const T val) : type(Type::Boolean), b(val) {}
218 any(const char (&val)[N]) : type(Type::StringLiteral), r(val) {}
219 any(char * val) : type(Type::String), s(make_shared<std::string>(val)) {}
221 any(const std::string& val) : type(Type::String), s(make_shared<std::string>(val)) {}
222 any(std::string&& val) : type(Type::String), s(make_shared<std::string>(std::move(val))) {}
224 any(const shared<std::string>& val) : type(Type::String), s(val) {}
225 any(shared<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
227 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
228 any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
230 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
231 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
233 any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
234 any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
236 template <typename T>
237 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
238 : type(Type::Function), f(val) {}
240 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
241 !std::is_convertible<T,fn>::value>::type>
242 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
243 : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
245 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
246 !std::is_convertible<T,fn>::value>::type>
247 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
248 const any&)>,T>::value>::type* = 0)
249 : type(Type::Closure), l(make_shared<_closure2<T>>(val)) {}
251 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
252 !std::is_convertible<T,fn>::value>::type>
253 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&,
255 const any&)>,T>::value>::type* = 0)
256 : type(Type::Closure), l(make_shared<_closure3<T>>(val)) {}
258 template <typename T>
259 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
260 : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
262 template <typename T>
263 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
264 : type(Type::Thunk), t(val) {}
266 template <typename T>
267 any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
268 : type(Type::Pointer), p(val) {}
270 template <typename T>
271 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
272 : type(Type::Pointer), p(std::move(val)) {}
274 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
279 auto operator=(const any&) -> any&;
280 auto operator=(any&) noexcept -> any&;
281 auto operator=(any&&) noexcept -> any&;
286 template <typename T>
287 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
289 template <typename T>
290 auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
292 template <typename T>
293 auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
295 template <typename T>
296 auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
298 template <typename T>
299 auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type;
301 template <typename T>
302 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
304 template <typename T>
305 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
307 template <typename T>
308 auto cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type;
310 template <typename T>
311 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
312 return static_cast<typename T::element_type*>(extractPointer());
315 auto operator()(const any&) const -> any;
316 auto operator()(const any&, const any&) const -> any;
317 auto operator()(const any&, const any&, const any&) const -> any;
319 auto operator()(const as_thunk) const -> const any&;
321 auto operator()() const -> any;
323 operator long() const;
324 operator double() const;
325 operator bool() const;
327 operator string() const;
328 operator const map&() const;
329 operator const vector&() const;
330 operator const array&() const;
332 auto operator[](const char[]) const -> const any&;
333 auto operator[](const size_t) const -> const any&;
334 auto operator[](const any&) const -> const any&;
336 auto contains(const char[]) const -> bool;
338 auto extractPointer() const -> void*;
340 static auto unthunkVariant(const any&) -> const any&;
342 DECLARE_COMPARISON_OPERATOR(==)
343 DECLARE_COMPARISON_OPERATOR(!=)
344 DECLARE_COMPARISON_OPERATOR(<)
345 DECLARE_COMPARISON_OPERATOR(<=)
346 DECLARE_COMPARISON_OPERATOR(>)
347 DECLARE_COMPARISON_OPERATOR(>=)
349 friend auto operator+(const any&, const any&) -> any;
351 DECLARE_OPERATOR(+, long, long)
352 DECLARE_OPERATOR(+, double, double)
353 DECLARE_OPERATOR(+, char, char)
354 DECLARE_OPERATOR(+, const char *, std::string)
356 friend auto operator-(const any&, const any&) -> any;
358 DECLARE_OPERATOR(-, long, long)
359 DECLARE_OPERATOR(-, double, double)
360 DECLARE_OPERATOR(-, char, char)
362 friend auto operator*(const any&, const any&) -> any;
364 DECLARE_OPERATOR(*, long, long)
365 DECLARE_OPERATOR(*, double, double)
366 DECLARE_OPERATOR(*, char, char)
368 friend auto operator/(const any&, const any&) -> any;
370 DECLARE_OPERATOR(/, long, long)
371 DECLARE_OPERATOR(/, double, double)
372 DECLARE_OPERATOR(/, char, char)
374 friend auto operator%(const any&, const any&) -> any;
376 DECLARE_OPERATOR(%, long, long)
377 DECLARE_OPERATOR(%, char, char)
379 friend auto operator-(const any&) -> any; // unary negate
382} // namespace PureScript
384#undef DECLARE_OPERATOR
385#undef DECLARE_COMPARISON_OPERATOR
387#endif // PureScript_HH
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