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#define DECLARE_OPERATOR(op, ty, rty) \
36 friend auto operator op (const any&, ty) -> rty; \
37 friend auto operator op (ty, const any&) -> rty;
39#define DECLARE_COMPARISON_OPERATOR(op) \
40 friend auto operator op (const any&, const any&) -> bool; \
41 DECLARE_OPERATOR(op, long, bool) \
42 DECLARE_OPERATOR(op, double, bool) \
43 DECLARE_OPERATOR(op, char, bool) \
44 DECLARE_OPERATOR(op, const char *, bool)
49using string = const char *;
50using nullptr_t = std::nullptr_t;
52// Workaround for missing C++11 version in gcc
53class runtime_error : public std::runtime_error {
55 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
58const bool undefined = false;
59const std::vector<int>::size_type kDataCtor = 0;
61// A variant data class designed to provide some features of dynamic typing.
66 enum class Type : int8_t {
83 mutable Type type = Type::Unknown;
87 static constexpr as_thunk unthunk = as_thunk{};
89 using map = std::vector<std::pair<const char * const, const any>>;
90 using vector = std::vector<any>;
91 using fn = auto (*)(const any&) -> any;
92 using closure = std::function<any(const any&)>;
93 using eff_fn = std::function<any()>;
94 using thunk = auto (*)(const as_thunk) -> const any&;
97 using shared = std::shared_ptr<T>;
99 template <typename T, typename... Args>
100 inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
101 return std::make_shared<T>(std::forward<Args>(args)...);
111 mutable shared<std::string> s;
112 mutable shared<map> m;
113 mutable shared<vector> v;
115 mutable shared<closure> l;
116 mutable shared<eff_fn> e;
118 mutable shared<void> p;
123 any(const long val) : type(Type::Integer), i(val) {}
124 any(const int val) : type(Type::Integer), i(val) {}
125 any(const unsigned int val) : type(Type::Integer), i(val) {}
126 any(const double val) : type(Type::Double), d(val) {}
127 any(const char val) : type(Type::Character), c(val) {}
129 template <typename T, typename = typename std::enable_if<std::is_same<bool,T>::value>::type>
130 any(const T val) : type(Type::Boolean), b(val) {}
133 any(const char (&val)[N]) : type(Type::StringLiteral), r(val) {}
134 any(char * val) : type(Type::String), s(make_shared<std::string>(val)) {}
136 any(const std::string& val) : type(Type::String), s(make_shared<std::string>(val)) {}
137 any(std::string&& val) : type(Type::String), s(make_shared<std::string>(std::move(val))) {}
139 any(const shared<std::string>& val) : type(Type::String), s(val) {}
140 any(shared<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
142 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
143 any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
145 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
146 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
148 template <typename T>
149 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
150 : type(Type::Function), f(val) {}
152 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
153 !std::is_convertible<T,fn>::value>::type>
154 any(const T& val, typename std::enable_if<std::is_assignable<closure,T>::value>::type* = 0)
155 : type(Type::Closure), l(make_shared<closure>(val)) {}
157 template <typename T>
158 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
159 : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
161 template <typename T>
162 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
163 : type(Type::Thunk), t(val) {}
165 template <typename T>
166 any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
167 : type(Type::Pointer), p(val) {}
169 template <typename T>
170 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
171 : type(Type::Pointer), p(std::move(val)) {}
173 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
178 auto operator=(const any&) -> any&;
179 auto operator=(any&) noexcept -> any&;
180 auto operator=(any&&) noexcept -> any&;
185 template <typename T>
186 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
188 template <typename T>
189 auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
191 template <typename T>
192 auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
194 template <typename T>
195 auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
197 template <typename T>
198 auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type;
200 template <typename T>
201 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
203 template <typename T>
204 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
206 template <typename T>
207 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
208 return static_cast<typename T::element_type*>(extractPointer());
211 auto operator()(const any&) const -> any;
213 auto operator()(const as_thunk) const -> const any&;
215 auto operator()() const -> any;
217 operator long() const;
218 operator double() const;
219 operator bool() const;
221 operator string() const;
222 operator const map&() const;
223 operator const vector&() const;
225 auto operator[](const char[]) const -> const any&;
226 auto operator[](const vector::size_type) const -> const any&;
227 auto operator[](const any&) const -> const any&;
229 auto contains(const char[]) const -> bool;
231 auto extractPointer() const -> void*;
233 static auto unthunkVariant(const any&) -> const any&;
235 DECLARE_COMPARISON_OPERATOR(==)
236 DECLARE_COMPARISON_OPERATOR(!=)
237 DECLARE_COMPARISON_OPERATOR(<)
238 DECLARE_COMPARISON_OPERATOR(<=)
239 DECLARE_COMPARISON_OPERATOR(>)
240 DECLARE_COMPARISON_OPERATOR(>=)
242 friend auto operator+(const any&, const any&) -> any;
244 DECLARE_OPERATOR(+, long, long)
245 DECLARE_OPERATOR(+, double, double)
246 DECLARE_OPERATOR(+, char, char)
247 DECLARE_OPERATOR(+, const char *, std::string)
249 friend auto operator-(const any&, const any&) -> any;
251 DECLARE_OPERATOR(-, long, long)
252 DECLARE_OPERATOR(-, double, double)
253 DECLARE_OPERATOR(-, char, char)
255 friend auto operator*(const any&, const any&) -> any;
257 DECLARE_OPERATOR(*, long, long)
258 DECLARE_OPERATOR(*, double, double)
259 DECLARE_OPERATOR(*, char, char)
261 friend auto operator/(const any&, const any&) -> any;
263 DECLARE_OPERATOR(/, long, long)
264 DECLARE_OPERATOR(/, double, double)
265 DECLARE_OPERATOR(/, char, char)
267 friend auto operator%(const any&, const any&) -> any;
269 DECLARE_OPERATOR(%, long, long)
270 DECLARE_OPERATOR(%, char, char)
272 friend auto operator-(const any&) -> any; // unary negate
275} // namespace PureScript
277#undef DECLARE_OPERATOR
278#undef DECLARE_COMPARISON_OPERATOR
280#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