git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: switch 'data' to std::array
ed3008cAndy Arvanitis
pcc/include/purescript.cc+2−6
@@ -74,16 +74,12 @@ any::operator const map&() const {
74 RETURN_VALUE(Type::Map, m, *)
74 RETURN_VALUE(Type::Map, m, *)
75}
75}
76
76
77−any::operator const data&() const {
78− RETURN_VALUE(Type::Data, v, *)
79−}
80−
81any::operator const array&() const {
77any::operator const array&() const {
82 RETURN_VALUE(Type::Array, a, *)
78 RETURN_VALUE(Type::Array, a, *)
83}
79}
84
80
85−auto any::extractPointer() const -> void* {
81+auto any::extractPointer(IF_DEBUG(const any::Type t)) const -> void* {
86− RETURN_VALUE(Type::Pointer, POINTER_FROM_MEMBER(p),)
82+ RETURN_VALUE(t, POINTER_FROM_MEMBER(p),)
87}
83}
88
84
89auto any::unthunkVariant(const any& a) -> const any& {
85auto any::unthunkVariant(const any& a) -> const any& {
pcc/include/purescript.hh+27−12
@@ -20,15 +20,18 @@
20#if defined(DEBUG)
20#if defined(DEBUG)
21 #include <cassert>
21 #include <cassert>
22 #include <climits>
22 #include <climits>
23+ #define IF_DEBUG(x) x
23#else
24#else
24 #define NDEBUG
25 #define NDEBUG
25 #undef assert
26 #undef assert
26 #define assert(x)
27 #define assert(x)
28+ #define IF_DEBUG(_)
27#endif
29#endif
28
30
29#include <functional>
31#include <functional>
30#include <string>
32#include <string>
31#include <vector>
33#include <vector>
34+#include <array>
32#include <deque>
35#include <deque>
33#include <utility>
36#include <utility>
34#include <stdexcept>
37#include <stdexcept>
@@ -83,7 +86,10 @@ class any {
83
86
84 using map_pair = std::pair<const char * const, const any>;
87 using map_pair = std::pair<const char * const, const any>;
85 using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
88 using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
89+
90+ template <size_t N>
86− using data = std::vector<any WITH_ALLOCATOR(any)>;
91+ using data = std::array<any, N>;
92+
87 using array = std::deque<any WITH_ALLOCATOR(any)>;
93 using array = std::deque<any WITH_ALLOCATOR(any)>;
88 using fn = auto (*)(const any&) -> any;
94 using fn = auto (*)(const any&) -> any;
89 using eff_fn = auto (*)() -> any;
95 using eff_fn = auto (*)() -> any;
@@ -135,7 +141,6 @@ class any {
135 mutable void * u;
141 mutable void * u;
136 mutable managed<std::string> s;
142 mutable managed<std::string> s;
137 mutable managed<map> m;
143 mutable managed<map> m;
138− mutable managed<data> v;
139 mutable managed<array> a;
144 mutable managed<array> a;
140 mutable managed<closure> l;
145 mutable managed<closure> l;
141 mutable managed<eff_closure> k;
146 mutable managed<eff_closure> k;
@@ -168,8 +173,8 @@ class any {
168 any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
173 any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
169 any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
174 any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
170
175
171− any(const data& val) : type(Type::Data), v(make_managed<data>(val)) {}
176+ template <size_t N>
172− any(data&& val) noexcept : type(Type::Data), v(make_managed<data>(std::move(val))) {}
177+ any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
173
178
174 any(const array& val) : type(Type::Array), a(make_managed<array>(val)) {}
179 any(const array& val) : type(Type::Array), a(make_managed<array>(val)) {}
175 any(array&& val) noexcept : type(Type::Array), a(make_managed<array>(std::move(val))) {}
180 any(array&& val) noexcept : type(Type::Array), a(make_managed<array>(std::move(val))) {}
@@ -245,10 +250,10 @@ class any {
245
250
246 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
251 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
247 case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
252 case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
248− case Type::Data: new (&v) managed<data>(move_if_rvalue<T>(other.v)); break;
249 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
253 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
250 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
254 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
251 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
255 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
256+ case Type::Data:
252 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
257 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
253
258
254 default: assert(false && "Bad 'any' type"); break;
259 default: assert(false && "Bad 'any' type"); break;
@@ -259,10 +264,10 @@ class any {
259 switch (type) {
264 switch (type) {
260 case Type::String: s.~managed<std::string>(); break;
265 case Type::String: s.~managed<std::string>(); break;
261 case Type::Map: m.~managed<map>(); break;
266 case Type::Map: m.~managed<map>(); break;
262− case Type::Data: v.~managed<data>(); break;
263 case Type::Array: a.~managed<array>(); break;
267 case Type::Array: a.~managed<array>(); break;
264 case Type::Closure: l.~managed<closure>(); break;
268 case Type::Closure: l.~managed<closure>(); break;
265 case Type::EffClosure: k.~managed<eff_closure>(); break;
269 case Type::EffClosure: k.~managed<eff_closure>(); break;
270+ case Type::Data:
266 case Type::Pointer: p.~managed<void>(); break;
271 case Type::Pointer: p.~managed<void>(); break;
267
272
268 default: break;
273 default: break;
@@ -310,7 +315,6 @@ class any {
310 operator char() const;
315 operator char() const;
311 operator cstring() const;
316 operator cstring() const;
312 operator const map&() const;
317 operator const map&() const;
313− operator const data&() const;
314 operator const array&() const;
318 operator const array&() const;
315
319
316 auto operator[](const char[]) const -> const any&;
320 auto operator[](const char[]) const -> const any&;
@@ -319,7 +323,7 @@ class any {
319
323
320 auto contains(const char[]) const -> bool;
324 auto contains(const char[]) const -> bool;
321
325
322− auto extractPointer() const -> void*;
326+ auto extractPointer(IF_DEBUG(const Type)) const -> void*;
323
327
324 auto rawPointer() const -> void* {
328 auto rawPointer() const -> void* {
325 const any& variant = unthunkVariant(*this);
329 const any& variant = unthunkVariant(*this);
@@ -387,6 +391,19 @@ class any {
387 friend auto operator-(const any&) -> any; // unary negate
391 friend auto operator-(const any&) -> any; // unary negate
388};
392};
389
393
394+template <typename T, typename U=void>
395+struct TypeTag {};
396+
397+template <size_t N>
398+struct TypeTag<any::data<N>> {
399+ static constexpr any::Type TypeId = any::Type::Data;
400+};
401+
402+template <typename T>
403+struct TypeTag<T> {
404+ static constexpr any::Type TypeId = any::Type::Pointer;
405+};
406+
390template <typename T>
407template <typename T>
391inline auto cast(const any& a) ->
408inline auto cast(const any& a) ->
392 typename std::enable_if<std::is_arithmetic<T>::value ||
409 typename std::enable_if<std::is_arithmetic<T>::value ||
@@ -397,17 +414,15 @@ inline auto cast(const any& a) ->
397template <typename T>
414template <typename T>
398inline auto cast(const any& a) ->
415inline auto cast(const any& a) ->
399 typename std::enable_if<std::is_same<T, any::map>::value ||
416 typename std::enable_if<std::is_same<T, any::map>::value ||
400− std::is_same<T, any::data>::value ||
401 std::is_same<T, any::array>::value, const T&>::type {
417 std::is_same<T, any::array>::value, const T&>::type {
402 return a;
418 return a;
403}
419}
404
420
405template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
421template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
406inline auto cast(const any& a) ->
422inline auto cast(const any& a) ->
407− typename std::enable_if<!std::is_same<T, any::map>::value &&
423+ typename std::enable_if<!std::is_same<T, any::map>::value &&
408− !std::is_same<T, any::data>::value &&
409 !std::is_same<T, any::array>::value, T&>::type {
424 !std::is_same<T, any::array>::value, T&>::type {
410− return *static_cast<T*>(a.extractPointer());
425+ return *static_cast<T*>(a.extractPointer(IF_DEBUG(TypeTag<T>::TypeId)));
411}
426}
412
427
413template <typename T>
428template <typename T>
src/Language/PureScript/CodeGen/Cpp.hs+7−3
@@ -368,7 +368,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
368 [dict'])
368 [dict'])
369 where
369 where
370 dict' = CppVar dictname
370 dict' = CppVar dictname
371− dict'' = CppCast dataType dict'
371+ dict'' = CppCast (dataType 1) dict'
372
372
373 accessor :: String -> (String, Cpp) -> Cpp
373 accessor :: String -> (String, Cpp) -> Cpp
374 accessor dictname (name, _) =
374 accessor dictname (name, _) =
@@ -625,7 +625,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
625 EqualTo
625 EqualTo
626 (CppIndexer
626 (CppIndexer
627 (CppVar ctorKey)
627 (CppVar ctorKey)
628− (CppCast dataType $ CppVar varName))
628+ (CppCast (dataType 1) $ CppVar varName))
629 ctorCpp)
629 ctorCpp)
630 (CppBlock cpps)
630 (CppBlock cpps)
631 Nothing]
631 Nothing]
@@ -642,10 +642,14 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
642 []
642 []
643 (Just $ CppIndexer
643 (Just $ CppIndexer
644 (fieldToIndex field)
644 (fieldToIndex field)
645− (CppCast dataType $ CppVar varName))
645+ (CppCast (dataType $ fieldToIndex' field + 1) $ CppVar varName))
646 : cpps
646 : cpps
647 fieldToIndex :: Ident -> Cpp
647 fieldToIndex :: Ident -> Cpp
648 fieldToIndex = CppNumericLiteral . Left . (+1) . read . dropWhile isLetter . runIdent
648 fieldToIndex = CppNumericLiteral . Left . (+1) . read . dropWhile isLetter . runIdent
649+
650+ fieldToIndex' :: Ident -> Int
651+ fieldToIndex' = (+1) . read . dropWhile isLetter . runIdent
652+
649 ctor' :: Cpp
653 ctor' :: Cpp
650 ctor' = CppAccessor (CppVar . identToCpp $ Ident ctor) (CppVar "data")
654 ctor' = CppAccessor (CppVar . identToCpp $ Ident ctor) (CppVar "data")
651 ctorCpp :: Cpp
655 ctorCpp :: Cpp
src/Language/PureScript/CodeGen/Cpp/Types.hs+2−2
@@ -127,8 +127,8 @@ charType = CppPrimitive "char"
127mapType :: CppType
127mapType :: CppType
128mapType = CppPrimitive "any::map"
128mapType = CppPrimitive "any::map"
129
129
130−dataType :: CppType
130+dataType :: Int -> CppType
131−dataType = CppPrimitive "any::data"
131+dataType n = CppPrimitive $ "any::data<" ++ show n ++ ">"
132
132
133arrayType :: CppType
133arrayType :: CppType
134arrayType = CppPrimitive "any::array"
134arrayType = CppPrimitive "any::array"
src/Language/PureScript/Pretty/Cpp.hs+1−1
@@ -104,7 +104,7 @@ literals = mkPattern' match
104 , return " }"
104 , return " }"
105 ]
105 ]
106 match (CppDataLiteral xs) = fmap concat $ sequence
106 match (CppDataLiteral xs) = fmap concat $ sequence
107− [ return $ runType dataType
107+ [ return $ runType (dataType $ length xs)
108 , return "{ "
108 , return "{ "
109 , fmap (intercalate ", ") $ forM xs prettyPrintCpp'
109 , fmap (intercalate ", ") $ forM xs prettyPrintCpp'
110 , return " }"
110 , return " }"