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///////////////////////////////////////////////////////////////////////////////
35#include <iso646.h> // mostly for MS Visual Studio compiler
37#define DECLARE_OPERATOR(op, ty, rty) \
38 friend auto operator op (const any&, ty) -> rty; \
39 friend auto operator op (ty, const any&) -> rty;
41#define DECLARE_COMPARISON_OPERATOR(op) \
42 friend auto operator op (const any&, const any&) -> bool; \
43 DECLARE_OPERATOR(op, long, bool) \
44 DECLARE_OPERATOR(op, double, bool) \
45 DECLARE_OPERATOR(op, char, bool) \
46 DECLARE_OPERATOR(op, const char *, bool)
51using string = const char *;
52using nullptr_t = std::nullptr_t;
54// Workaround for missing C++11 version in gcc
55class runtime_error : public std::runtime_error {
57 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
60const bool undefined = false;
61const size_t constructor = 0;
63// A variant data class designed to provide some features of dynamic typing.
92 static constexpr as_thunk unthunk = as_thunk{};
94 using map = std::vector<std::pair<const char * const, const any>>;
95 using data = std::vector<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 ~closure() {}
107 template <typename T>
108 class _closure : public closure {
111 _closure(const T& l) noexcept : lambda(l) {}
112 auto operator()(const any& arg) const -> any {
119 virtual auto operator()() const -> any = 0;
122 template <typename T>
123 class _eff_fn : public eff_fn {
126 _eff_fn(const T& l) noexcept : lambda(l) {}
127 auto operator()() const -> any {
133 template <typename T>
134 using shared = std::shared_ptr<T>;
136 template <typename T, typename... Args>
137 inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
138 return std::make_shared<T>(std::forward<Args>(args)...);
150 mutable shared<std::string> s;
151 mutable shared<map> m;
152 mutable shared<data> v;
153 mutable shared<array> a;
154 mutable shared<closure> l;
155 mutable shared<eff_fn> e;
156 mutable shared<void> p;
161 any(const long val) : type(Type::Integer), i(val) {}
162 any(const int val) : type(Type::Integer), i(val) {}
163 any(const unsigned int val) : type(Type::Integer), i(val) {}
164 any(const double val) : type(Type::Double), d(val) {}
165 any(const char val) : type(Type::Character), c(val) {}
167 template <typename T, typename = typename std::enable_if<std::is_same<bool,T>::value>::type>
168 any(const T val) : type(Type::Boolean), b(val) {}
171 any(const char (&val)[N]) : type(Type::StringLiteral), r(val) {}
172 any(char * val) : type(Type::String), s(make_shared<std::string>(val)) {}
174 any(const std::string& val) : type(Type::String), s(make_shared<std::string>(val)) {}
175 any(std::string&& val) : type(Type::String), s(make_shared<std::string>(std::move(val))) {}
177 any(const shared<std::string>& val) : type(Type::String), s(val) {}
178 any(shared<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
180 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
181 any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
183 any(const data& val) : type(Type::Data), v(make_shared<data>(val)) {}
184 any(data&& val) noexcept : type(Type::Data), v(make_shared<data>(std::move(val))) {}
186 any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
187 any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
189 template <typename T>
190 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
191 : type(Type::Function), f(val) {}
193 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
194 !std::is_convertible<T,fn>::value>::type>
195 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
196 : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
198 template <typename T>
199 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
200 : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
202 template <typename T>
203 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
204 : type(Type::Thunk), t(val) {}
206 template <typename T>
207 any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
208 : type(Type::Pointer), p(val) {}
210 template <typename T>
211 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
212 : type(Type::Pointer), p(std::move(val)) {}
214 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
218 auto copy(const any& other) const -> void {
219 if (type & Type::Shared) {
220 new (&p) shared<void>(other.p);
226 auto move(any& other) const noexcept -> void {
227 if (type & Type::Shared) {
228 new (&p) shared<void>(std::move(other.p));
234 auto destruct() noexcept -> void {
235 if (type & Type::Shared) {
242 any(const any& other) : type(other.type) {
246 any(any&& other) noexcept : type(other.type) {
250 auto operator=(const any& rhs) -> any& {
257 auto operator=(any&& rhs) noexcept -> any& {
270 template <typename T>
271 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
273 template <typename T>
274 auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
276 template <typename T>
277 auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
279 template <typename T>
280 auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
282 template <typename T>
283 auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type;
285 template <typename T>
286 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
288 template <typename T>
289 auto cast() const -> typename std::enable_if<std::is_same<T, data>::value, const T&>::type;
291 template <typename T>
292 auto cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type;
294 template <typename T>
295 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
296 return static_cast<typename T::element_type*>(extractPointer());
299 auto operator()(const any&) const -> any;
300 auto operator()(const as_thunk) const -> const any&;
301 auto operator()() const -> any;
303 operator long() const;
304 operator double() const;
305 operator bool() const;
307 operator string() const;
308 operator const map&() const;
309 operator const data&() const;
310 operator const array&() const;
312 auto operator[](const char[]) const -> const any&;
313 auto operator[](const size_t) const -> const any&;
314 auto operator[](const any&) const -> const any&;
316 auto contains(const char[]) const -> bool;
318 auto extractPointer() const -> void*;
320 static auto unthunkVariant(const any&) -> const any&;
322 DECLARE_COMPARISON_OPERATOR(==)
323 DECLARE_COMPARISON_OPERATOR(!=)
324 DECLARE_COMPARISON_OPERATOR(<)
325 DECLARE_COMPARISON_OPERATOR(<=)
326 DECLARE_COMPARISON_OPERATOR(>)
327 DECLARE_COMPARISON_OPERATOR(>=)
329 // For MS Visual Studio compiler: broken typed-enum workaround
330 DECLARE_OPERATOR(==, int, bool)
331 DECLARE_OPERATOR(!=, int, bool)
333 friend auto operator+(const any&, const any&) -> any;
335 DECLARE_OPERATOR(+, long, long)
336 DECLARE_OPERATOR(+, double, double)
337 DECLARE_OPERATOR(+, char, char)
338 DECLARE_OPERATOR(+, const char *, std::string)
340 friend auto operator-(const any&, const any&) -> any;
342 DECLARE_OPERATOR(-, long, long)
343 DECLARE_OPERATOR(-, double, double)
344 DECLARE_OPERATOR(-, char, char)
346 friend auto operator*(const any&, const any&) -> any;
348 DECLARE_OPERATOR(*, long, long)
349 DECLARE_OPERATOR(*, double, double)
350 DECLARE_OPERATOR(*, char, char)
352 friend auto operator/(const any&, const any&) -> any;
354 DECLARE_OPERATOR(/, long, long)
355 DECLARE_OPERATOR(/, double, double)
356 DECLARE_OPERATOR(/, char, char)
358 friend auto operator%(const any&, const any&) -> any;
360 DECLARE_OPERATOR(%, long, long)
361 DECLARE_OPERATOR(%, char, char)
363 friend auto operator-(const any&) -> any; // unary negate
366// For MS Visual Studio compiler: broken typed-enum workaround
367inline auto operator==(const any& lhs, int rhs) -> bool {
368 return lhs == (long)rhs;
370inline auto operator!=(const any& lhs, int rhs) -> bool {
371 return lhs != (long)rhs;
374} // namespace PureScript
376#undef DECLARE_OPERATOR
377#undef DECLARE_COMPARISON_OPERATOR
379#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