git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: use custom functors instead of std::function (optimization)
commit8a8d1d14b0e54222ff15ec3b2e50e4cee3d977bb authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 24 Jan 2016, 16:22 (11 years ago) parent48ce93b
2 files changed+35−7
pcc/include/purescript.hh+34−6 src/Language/PureScript/CodeGen/Cpp.hs+1−1
pcc/include/purescript.hh+34−6
@@ -89,10 +89,38 @@ class any {
8989 using map = std::vector<std::pair<const char * const, const any>>;
9090 using vector = std::vector<any>;
9191 using fn = auto (*)(const any&) -> any;
92− using closure = std::function<any(const any&)>;
93− using eff_fn = std::function<any()>;
9492 using thunk = auto (*)(const as_thunk) -> const any&;
9593
94+ class closure {
95+ public:
96+ virtual any operator()(const any&) = 0;
97+ };
98+
99+ template <typename T>
100+ class _closure : public closure {
101+ T lambda;
102+ public:
103+ _closure(const T& l) noexcept : lambda(l) {}
104+ any operator()(const any& arg) {
105+ return lambda(arg);
106+ }
107+ };
108+
109+ class eff_fn {
110+ public:
111+ virtual any operator()() = 0;
112+ };
113+
114+ template <typename T>
115+ class _eff_fn : public eff_fn {
116+ T lambda;
117+ public:
118+ _eff_fn(const T& l) noexcept : lambda(l) {}
119+ any operator()() {
120+ return lambda();
121+ }
122+ };
123+
96124 template <typename T>
97125 using shared = std::shared_ptr<T>;
98126
@@ -151,12 +179,12 @@ class any {
151179
152180 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
153181 !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)) {}
182+ any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
183+ : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
156184
157185 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)) {}
186+ any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
187+ : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
160188
161189 template <typename T>
162190 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
src/Language/PureScript/CodeGen/Cpp.hs+1−1
@@ -120,7 +120,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
120120 block <- asReturnBlock <$> valueToCpp body
121121 let fn' = CppFunction (identToCpp ident)
122122 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
123− (Just $ CppAny [CppConst, CppRef])
123+ (Just $ CppAny [])
124124 []
125125 block
126126 return fn'