git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: use custom functors instead of std::function (optimization)
8a8d1d1Andy Arvanitis
pcc/include/purescript.hh+34−6
@@ -89,10 +89,38 @@ class any {
89 using map = std::vector<std::pair<const char * const, const any>>;
89 using map = std::vector<std::pair<const char * const, const any>>;
90 using vector = std::vector<any>;
90 using vector = std::vector<any>;
91 using fn = auto (*)(const any&) -> 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&;
92 using thunk = auto (*)(const as_thunk) -> const any&;
95
93
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+
96 template <typename T>
124 template <typename T>
97 using shared = std::shared_ptr<T>;
125 using shared = std::shared_ptr<T>;
98
126
@@ -151,12 +179,12 @@ class any {
151
179
152 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
180 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
153 !std::is_convertible<T,fn>::value>::type>
181 !std::is_convertible<T,fn>::value>::type>
154− any(const T& val, typename std::enable_if<std::is_assignable<closure,T>::value>::type* = 0)
182+ any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
155− : type(Type::Closure), l(make_shared<closure>(val)) {}
183+ : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
156
184
157 template <typename T>
185 template <typename T>
158− any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
186+ any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
159− : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
187+ : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
160
188
161 template <typename T>
189 template <typename T>
162 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
190 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
120 block <- asReturnBlock <$> valueToCpp body
120 block <- asReturnBlock <$> valueToCpp body
121 let fn' = CppFunction (identToCpp ident)
121 let fn' = CppFunction (identToCpp ident)
122 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
122 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
123− (Just $ CppAny [CppConst, CppRef])
123+ (Just $ CppAny [])
124 []
124 []
125 block
125 block
126 return fn'
126 return fn'