git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: switch 'data' to std::array
commited3008c6dcf480710bc180f13c3e8f9f4b2fbee0 authorAndy Arvanitis <andyarvanitis@gmail.com> dateWed 26 Oct 2016, 22:40 (10 years ago) parentcb565d1
5 files changed+39−24
pcc/include/purescript.cc+2−6 pcc/include/purescript.hh+27−12 src/Language/PureScript/CodeGen/Cpp.hs+7−3 src/Language/PureScript/CodeGen/Cpp/Types.hs+2−2 src/Language/PureScript/Pretty/Cpp.hs+1−1
pcc/include/purescript.cc+2−6
@@ -74,16 +74,12 @@ any::operator const map&() const {
7474 RETURN_VALUE(Type::Map, m, *)
7575}
7676
77−any::operator const data&() const {
78− RETURN_VALUE(Type::Data, v, *)
79−}
80−
8177any::operator const array&() const {
8278 RETURN_VALUE(Type::Array, a, *)
8379}
8480
85−auto any::extractPointer() const -> void* {
86− RETURN_VALUE(Type::Pointer, POINTER_FROM_MEMBER(p),)
81+auto any::extractPointer(IF_DEBUG(const any::Type t)) const -> void* {
82+ RETURN_VALUE(t, POINTER_FROM_MEMBER(p),)
8783}
8884
8985auto any::unthunkVariant(const any& a) -> const any& {
pcc/include/purescript.hh+27−12
@@ -20,15 +20,18 @@
2020#if defined(DEBUG)
2121 #include <cassert>
2222 #include <climits>
23+ #define IF_DEBUG(x) x
2324#else
2425 #define NDEBUG
2526 #undef assert
2627 #define assert(x)
28+ #define IF_DEBUG(_)
2729#endif
2830
2931#include <functional>
3032#include <string>
3133#include <vector>
34+#include <array>
3235#include <deque>
3336#include <utility>
3437#include <stdexcept>
@@ -83,7 +86,10 @@ class any {
8386
8487 using map_pair = std::pair<const char * const, const any>;
8588 using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
86− using data = std::vector<any WITH_ALLOCATOR(any)>;
89+
90+ template <size_t N>
91+ using data = std::array<any, N>;
92+
8793 using array = std::deque<any WITH_ALLOCATOR(any)>;
8894 using fn = auto (*)(const any&) -> any;
8995 using eff_fn = auto (*)() -> any;
@@ -135,7 +141,6 @@ class any {
135141 mutable void * u;
136142 mutable managed<std::string> s;
137143 mutable managed<map> m;
138− mutable managed<data> v;
139144 mutable managed<array> a;
140145 mutable managed<closure> l;
141146 mutable managed<eff_closure> k;
@@ -168,8 +173,8 @@ class any {
168173 any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
169174 any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
170175
171− any(const data& val) : type(Type::Data), v(make_managed<data>(val)) {}
172− any(data&& val) noexcept : type(Type::Data), v(make_managed<data>(std::move(val))) {}
176+ template <size_t N>
177+ any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
173178
174179 any(const array& val) : type(Type::Array), a(make_managed<array>(val)) {}
175180 any(array&& val) noexcept : type(Type::Array), a(make_managed<array>(std::move(val))) {}
@@ -245,10 +250,10 @@ class any {
245250
246251 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
247252 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;
249253 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
250254 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
251255 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
256+ case Type::Data:
252257 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
253258
254259 default: assert(false && "Bad 'any' type"); break;
@@ -259,10 +264,10 @@ class any {
259264 switch (type) {
260265 case Type::String: s.~managed<std::string>(); break;
261266 case Type::Map: m.~managed<map>(); break;
262− case Type::Data: v.~managed<data>(); break;
263267 case Type::Array: a.~managed<array>(); break;
264268 case Type::Closure: l.~managed<closure>(); break;
265269 case Type::EffClosure: k.~managed<eff_closure>(); break;
270+ case Type::Data:
266271 case Type::Pointer: p.~managed<void>(); break;
267272
268273 default: break;
@@ -310,7 +315,6 @@ class any {
310315 operator char() const;
311316 operator cstring() const;
312317 operator const map&() const;
313− operator const data&() const;
314318 operator const array&() const;
315319
316320 auto operator[](const char[]) const -> const any&;
@@ -319,7 +323,7 @@ class any {
319323
320324 auto contains(const char[]) const -> bool;
321325
322− auto extractPointer() const -> void*;
326+ auto extractPointer(IF_DEBUG(const Type)) const -> void*;
323327
324328 auto rawPointer() const -> void* {
325329 const any& variant = unthunkVariant(*this);
@@ -387,6 +391,19 @@ class any {
387391 friend auto operator-(const any&) -> any; // unary negate
388392};
389393
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+
390407template <typename T>
391408inline auto cast(const any& a) ->
392409 typename std::enable_if<std::is_arithmetic<T>::value ||
@@ -397,17 +414,15 @@ inline auto cast(const any& a) ->
397414template <typename T>
398415inline auto cast(const any& a) ->
399416 typename std::enable_if<std::is_same<T, any::map>::value ||
400− std::is_same<T, any::data>::value ||
401417 std::is_same<T, any::array>::value, const T&>::type {
402418 return a;
403419}
404420
405421template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
406422inline auto cast(const any& a) ->
407− typename std::enable_if<!std::is_same<T, any::map>::value &&
408− !std::is_same<T, any::data>::value &&
423+ typename std::enable_if<!std::is_same<T, any::map>::value &&
409424 !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)));
411426}
412427
413428template <typename T>
src/Language/PureScript/CodeGen/Cpp.hs+7−3
@@ -368,7 +368,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
368368 [dict'])
369369 where
370370 dict' = CppVar dictname
371− dict'' = CppCast dataType dict'
371+ dict'' = CppCast (dataType 1) dict'
372372
373373 accessor :: String -> (String, Cpp) -> Cpp
374374 accessor dictname (name, _) =
@@ -625,7 +625,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
625625 EqualTo
626626 (CppIndexer
627627 (CppVar ctorKey)
628− (CppCast dataType $ CppVar varName))
628+ (CppCast (dataType 1) $ CppVar varName))
629629 ctorCpp)
630630 (CppBlock cpps)
631631 Nothing]
@@ -642,10 +642,14 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
642642 []
643643 (Just $ CppIndexer
644644 (fieldToIndex field)
645− (CppCast dataType $ CppVar varName))
645+ (CppCast (dataType $ fieldToIndex' field + 1) $ CppVar varName))
646646 : cpps
647647 fieldToIndex :: Ident -> Cpp
648648 fieldToIndex = CppNumericLiteral . Left . (+1) . read . dropWhile isLetter . runIdent
649+
650+ fieldToIndex' :: Ident -> Int
651+ fieldToIndex' = (+1) . read . dropWhile isLetter . runIdent
652+
649653 ctor' :: Cpp
650654 ctor' = CppAccessor (CppVar . identToCpp $ Ident ctor) (CppVar "data")
651655 ctorCpp :: Cpp
src/Language/PureScript/CodeGen/Cpp/Types.hs+2−2
@@ -127,8 +127,8 @@ charType = CppPrimitive "char"
127127mapType :: CppType
128128mapType = CppPrimitive "any::map"
129129
130−dataType :: CppType
131−dataType = CppPrimitive "any::data"
130+dataType :: Int -> CppType
131+dataType n = CppPrimitive $ "any::data<" ++ show n ++ ">"
132132
133133arrayType :: CppType
134134arrayType = CppPrimitive "any::array"
src/Language/PureScript/Pretty/Cpp.hs+1−1
@@ -104,7 +104,7 @@ literals = mkPattern' match
104104 , return " }"
105105 ]
106106 match (CppDataLiteral xs) = fmap concat $ sequence
107− [ return $ runType dataType
107+ [ return $ runType (dataType $ length xs)
108108 , return "{ "
109109 , fmap (intercalate ", ") $ forM xs prettyPrintCpp'
110110 , return " }"