git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: function pointer optimization
commit07114643cdc2e23d92400fbd6679d401b02278fd authorAndy Arvanitis <andyarvanitis@gmail.com> dateSat 16 Jan 2016, 11:38 (11 years ago) parentadbb476
2 files changed+25−8
pcc/include/purescript.cc+12−3 pcc/include/purescript.hh+13−5
pcc/include/purescript.cc+12−3
@@ -26,7 +26,8 @@ namespace PureScript {
2626 case Type::String: new (&s) shared<string> (src.s); break; \
2727 case Type::Map: new (&m) shared<map> (src.m); break; \
2828 case Type::Vector: new (&v) shared<vector> (src.v); break; \
29− case Type::Function: new (&f) shared<fn> (src.f); break; \
29+ case Type::Function: f = src.f; break; \
30+ case Type::Closure: new (&l) shared<closure> (src.l); break; \
3031 case Type::EffFunction: new (&e) shared<eff_fn> (src.e); break; \
3132 case Type::Thunk: t = src.t; break; \
3233 case Type::Pointer: new (&p) shared<void> (src.p); break; \
@@ -44,7 +45,8 @@ namespace PureScript {
4445 case Type::String: new (&s) shared<string> (std::move(src.s)); break; \
4546 case Type::Map: new (&m) shared<map> (std::move(src.m)); break; \
4647 case Type::Vector: new (&v) shared<vector> (std::move(src.v)); break; \
47− case Type::Function: new (&f) shared<fn> (std::move(src.f)); break; \
48+ case Type::Function: f = src.f; break; \
49+ case Type::Closure: new (&l) shared<closure> (std::move(src.l)); break; \
4850 case Type::EffFunction: new (&e) shared<eff_fn> (std::move(src.e)); break; \
4951 case Type::Thunk: t = src.t; break; \
5052 case Type::Pointer: new (&p) shared<void> (std::move(src.p)); break; \
@@ -86,7 +88,8 @@ any::~any() {
8688 case Type::String: s.~shared<string>(); break;
8789 case Type::Map: m.~shared<map>(); break;
8890 case Type::Vector: v.~shared<vector>(); break;
89− case Type::Function: f.~shared<fn>(); break;
91+ case Type::Function: ; break;
92+ case Type::Closure: l.~shared<closure>(); break;
9093 case Type::EffFunction: e.~shared<eff_fn>(); break;
9194 case Type::Thunk: ; break;
9295 case Type::Pointer: p.~shared<void>(); break;
@@ -163,6 +166,9 @@ any::~any() {
163166 if (type == Type::Function) {
164167 return (*f)(arg);
165168 }
169+ if (type == Type::Closure) {
170+ return (*l)(arg);
171+ }
166172 const any* valuePtr = this;
167173 do {
168174 assert(valuePtr->type == Type::Thunk);
@@ -170,6 +176,9 @@ any::~any() {
170176 if (value.type == Type::Function) {
171177 return (*value.f)(arg);
172178 }
179+ if (value.type == Type::Closure) {
180+ return (*value.l)(arg);
181+ }
173182 valuePtr = &value;
174183 } while (valuePtr->type != Type::Unknown);
175184 assert(false && "Unknown value type");
pcc/include/purescript.hh+13−5
@@ -56,6 +56,7 @@ class any {
5656 Map,
5757 Vector,
5858 Function,
59+ Closure,
5960 EffFunction,
6061 Thunk,
6162 Pointer
@@ -69,7 +70,8 @@ class any {
6970
7071 using map = std::unordered_map<const map_key_t, const any, map_key_t::hasher, map_key_t::equal>;
7172 using vector = std::vector<any>;
72− using fn = std::function<any(const any&)>;
73+ using fn = auto (*)(const any&) -> any;
74+ using closure = std::function<any(const any&)>;
7375 using eff_fn = std::function<any()>;
7476 using thunk = auto (*)(const as_thunk) -> const any&;
7577
@@ -90,7 +92,8 @@ class any {
9092 mutable shared<string> s;
9193 mutable shared<map> m;
9294 mutable shared<vector> v;
93− mutable shared<fn> f;
95+ mutable fn f;
96+ mutable shared<closure> l;
9497 mutable shared<eff_fn> e;
9598 mutable thunk t;
9699 mutable shared<void> p;
@@ -117,9 +120,14 @@ class any {
117120 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
118121 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
119122
120− template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value>::type>
121− any(const T& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
122− : type(Type::Function), f(make_shared<fn>(val)) {}
123+ template <typename T>
124+ any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
125+ : type(Type::Function), f(val) {}
126+
127+ template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
128+ !std::is_convertible<T,fn>::value>::type>
129+ any(const T& val, typename std::enable_if<std::is_assignable<closure,T>::value>::type* = 0)
130+ : type(Type::Closure), l(make_shared<closure>(val)) {}
123131
124132 template <typename T>
125133 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)