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///////////////////////////////////////////////////////////////////////////////
32#include <unordered_map>
40using string = std::string;
41using runtime_error = std::runtime_error;
42using nullptr_t = std::nullptr_t;
44// A variant data class designed to provide some features of dynamic typing.
49 enum class Type : std::int8_t {
64 Type type = Type::Unknown;
68 static constexpr as_thunk unthunk = as_thunk{};
70 using map = std::unordered_map<map_key_t, const any, map_key_t::hasher, map_key_t::equal>;
71 using vector = std::vector<any>;
72 using fn = std::function<any(const any&)>;
73 using eff_fn = std::function<any()>;
74 using thunk = std::function<const any& (const as_thunk)>;
76 using shared_string = std::shared_ptr<string>;
77 using shared_map = std::shared_ptr<map>;
78 using shared_vector = std::shared_ptr<vector>;
80 using shared_fn = std::shared_ptr<fn>;
81 using shared_eff_fn = std::shared_ptr<eff_fn>;
82 using shared_thunk = std::shared_ptr<thunk>;
85 using shared = std::shared_ptr<T>;
87 using shared_void_ptr = std::shared_ptr<void>;
90 static constexpr auto make_shared(const T& arg) -> shared<T> {
91 return std::make_shared<T>(arg);
95 static constexpr auto make_shared(T&& arg) -> shared<T> {
96 return std::make_shared<T>(std::move(arg));
99 template <typename T, typename U>
100 static constexpr auto static_cast_shared(U arg) -> T* {
101 return static_cast<T*>(arg.get());
121 any(const long val) : type(Type::Integer), i(val) {}
122 any(const int val) : type(Type::Integer), i(val) {}
123 any(const unsigned int val) : type(Type::Integer), i(val) {}
125 any(const double val) : type(Type::Double), d(val) {}
127 any(const char val) : type(Type::Character), c(val) {}
129 any(const bool val) : type(Type::Boolean), b(val) {}
131 any(const string& val) : type(Type::String), s(make_shared<string>(val)) {}
132 any(string&& val) : type(Type::String), s(make_shared<string>(std::move(val))) {}
134 any(const char val[]) : type(Type::String), s(make_shared<string>(val)) {}
136 any(const shared_string& val) : type(Type::String), s(val) {}
137 any(shared_string&& val) : type(Type::String), s(std::move(val)) {}
139 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
140 any(map&& val) : type(Type::Map), m(make_shared<map>(std::move(val))) {}
142 any(const shared_map& val) : type(Type::Map), m(val) {}
143 any(shared_map&& val) : type(Type::Map), m(std::move(val)) {}
145 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
146 any(vector&& val) : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
148 any(const shared_vector& val) : type(Type::Vector), v(val) {}
149 any(shared_vector&& val) : type(Type::Vector), v(std::move(val)) {}
151 any(const shared_fn& val) : type(Type::Function), f(val) {}
152 any(shared_fn&& val) : type(Type::Function), f(std::move(val)) {}
154 template <typename T>
155 any(const T& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
156 : type(Type::Function), f(make_shared<fn>(val)) {}
158 // template <typename T>
159 // any(T&& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
160 // : type(Type::Function), f(std::move(val)) {}
162 any(const shared_eff_fn& val) : type(Type::EffFunction), e(val) {}
163 any(shared_eff_fn&& val) : type(Type::EffFunction), e(std::move(val)) {}
165 template <typename T>
166 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
167 : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
169 any(const shared_thunk& val) : type(Type::Thunk), t(val) {}
170 any(shared_thunk&& val) : type(Type::Thunk), t(std::move(val)) {}
172 template <typename T>
173 any(const T& val, typename std::enable_if<std::is_assignable<thunk,T>::value>::type* = 0)
174 : type(Type::Thunk), t(make_shared<thunk>(val)) {}
176 template <typename T>
177 any(const T& val, typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value>::type* = 0)
178 : type(Type::Pointer), p(val) {}
180 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
182 template <typename T>
183 any(T&& val, typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value>::type* = 0)
184 : type(Type::Pointer), p(std::move(val)) {}
191 swap(std::move(val));
194 auto operator=(any val) -> any& {
195 swap(std::move(val));
202 template <typename T>
203 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
205 template <typename T>
206 auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
208 template <typename T>
209 auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
211 template <typename T>
212 auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
214 template <typename T>
215 auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type;
217 template <typename T>
218 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
220 template <typename T>
221 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
223 template <typename T>
224 auto cast() const -> typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value, typename T::element_type*>::type {
225 if (type == Type::Pointer) {
226 return static_cast_shared<typename T::element_type>(p);
228 const any* valuePtr = this;
230 assert(valuePtr->type == Type::Thunk);
231 const any& value = (*valuePtr->t)(unthunk);
232 if (value.type == Type::Pointer) {
233 return static_cast_shared<typename T::element_type>(value.p);
236 } while (valuePtr->type != Type::Unknown);
240 auto operator()(const any) const -> any;
242 auto operator()(const as_thunk) const -> const any&;
244 auto operator()() const -> any;
246 static auto call(const any& a) -> any;
248 operator long() const;
249 operator double() const;
250 operator bool() const;
252 operator const string&() const;
253 operator const map&() const;
254 operator const vector&() const;
256 auto operator[](const map_key_t) const -> const any&;
257 auto operator[](const vector::size_type) const -> const any&;
258 auto operator[](const any&) const -> const any&;
260 auto extractPointer() const -> const void*;
262 static auto extract_value(const any&) -> const any&;
264 auto operator==(const any&) const -> bool;
265 auto operator==(const long) const -> bool;
266 auto operator==(const double) const -> bool;
267 auto operator==(const char) const -> bool;
268 auto operator==(const bool) const -> bool;
269 auto operator==(const string&) const -> bool;
270 auto operator==(const char * const) const -> bool;
272 auto operator!=(const any&) const -> bool;
273 auto operator!=(const long) const -> bool;
274 auto operator!=(const double) const -> bool;
275 auto operator!=(const char) const -> bool;
276 auto operator!=(const bool) const -> bool;
277 auto operator!=(const string&) const -> bool;
278 auto operator!=(const char * const) const -> bool;
280 auto operator<(const any&) const -> bool;
281 auto operator<(const long) const -> bool;
282 auto operator<(const double) const -> bool;
283 auto operator<(const char) const -> bool;
284 auto operator<(const bool) const -> bool;
285 auto operator<(const string&) const -> bool;
286 auto operator<(const char * const) const -> bool;
288 auto operator<=(const any&) const -> bool;
289 auto operator<=(const long) const -> bool;
290 auto operator<=(const double) const -> bool;
291 auto operator<=(const char) const -> bool;
292 auto operator<=(const bool) const -> bool;
293 auto operator<=(const string&) const -> bool;
294 auto operator<=(const char * const) const -> bool;
296 auto operator>(const any&) const -> bool;
297 auto operator>(const long) const -> bool;
298 auto operator>(const double) const -> bool;
299 auto operator>(const char) const -> bool;
300 auto operator>(const bool) const -> bool;
301 auto operator>(const string&) const -> bool;
302 auto operator>(const char * const) const -> bool;
304 auto operator>=(const any&) const -> bool;
305 auto operator>=(const long) const -> bool;
306 auto operator>=(const double) const -> bool;
307 auto operator>=(const char) const -> bool;
308 auto operator>=(const bool) const -> bool;
309 auto operator>=(const string&) const -> bool;
310 auto operator>=(const char * const) const -> bool;
312 auto operator+(const any&) const -> any;
313 auto operator+(const long) const -> long;
314 auto operator+(const double) const -> double;
315 auto operator+(const char) const -> char;
316 auto operator+(const string&) const -> string;
317 auto operator+(const char * const) const -> string;
319 auto operator-(const any&) const -> any;
320 auto operator-(const long) const -> long;
321 auto operator-(const double) const -> double;
322 auto operator-(const char) const -> char;
324 auto operator*(const any&) const -> any;
325 auto operator*(const long) const -> long;
326 auto operator*(const double) const -> double;
328 auto operator/(const any&) const -> any;
329 auto operator/(const long) const -> long;
330 auto operator/(const double) const -> double;
332 auto operator%(const any&) const -> any;
333 auto operator%(const long) const -> long;
335 auto operator-() const -> any; // unary negate
337 friend auto operator==(const long, const any&) -> bool;
338 friend auto operator!=(const long, const any&) -> bool;
339 friend auto operator< (const long, const any&) -> bool;
340 friend auto operator<=(const long, const any&) -> bool;
341 friend auto operator> (const long, const any&) -> bool;
342 friend auto operator>=(const long, const any&) -> bool;
344 friend auto operator==(const double, const any&) -> bool;
345 friend auto operator!=(const double, const any&) -> bool;
346 friend auto operator< (const double, const any&) -> bool;
347 friend auto operator<=(const double, const any&) -> bool;
348 friend auto operator> (const double, const any&) -> bool;
349 friend auto operator>=(const double, const any&) -> bool;
351 friend auto operator==(const char, const any&) -> bool;
352 friend auto operator!=(const char, const any&) -> bool;
353 friend auto operator< (const char, const any&) -> bool;
354 friend auto operator<=(const char, const any&) -> bool;
355 friend auto operator> (const char, const any&) -> bool;
356 friend auto operator>=(const char, const any&) -> bool;
358 friend auto operator==(const bool, const any&) -> bool;
359 friend auto operator!=(const bool, const any&) -> bool;
360 friend auto operator< (const bool, const any&) -> bool;
361 friend auto operator<=(const bool, const any&) -> bool;
362 friend auto operator> (const bool, const any&) -> bool;
363 friend auto operator>=(const bool, const any&) -> bool;
365 friend auto operator==(const string&, const any&) -> bool;
366 friend auto operator!=(const string&, const any&) -> bool;
367 friend auto operator< (const string&, const any&) -> bool;
368 friend auto operator<=(const string&, const any&) -> bool;
369 friend auto operator> (const string&, const any&) -> bool;
370 friend auto operator>=(const string&, const any&) -> bool;
372 friend auto operator==(const char* const, const any&) -> bool;
373 friend auto operator!=(const char* const, const any&) -> bool;
374 friend auto operator< (const char* const, const any&) -> bool;
375 friend auto operator<=(const char* const, const any&) -> bool;
376 friend auto operator> (const char* const, const any&) -> bool;
377 friend auto operator>=(const char* const, const any&) -> bool;
379 friend auto operator+(const long, const any&) -> long;
380 friend auto operator-(const long, const any&) -> long;
381 friend auto operator*(const long, const any&) -> long;
382 friend auto operator/(const long, const any&) -> long;
383 friend auto operator%(const long, const any&) -> long;
385 friend auto operator+(const double, const any&) -> double;
386 friend auto operator-(const double, const any&) -> double;
387 friend auto operator*(const double, const any&) -> double;
388 friend auto operator/(const double, const any&) -> double;
390 friend auto operator+(const char, const any&) -> char;
391 friend auto operator-(const char, const any&) -> char;
393 friend auto operator+(const string&, const any&) -> string;
394 friend auto operator+(const char* const, const any&) -> string;
398} // namespace PureScript
400#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