git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Use custom classes instead of std::function (faster functions)
460264bAndy Arvanitis
runtime/purescript.h+41−9
@@ -16,7 +16,6 @@
16#define purescript_H
16#define purescript_H
17
17
18#include <memory>
18#include <memory>
19−#include <functional>
20#include <deque>
19#include <deque>
21#include <string>
20#include <string>
22#include <limits>
21#include <limits>
@@ -29,6 +28,7 @@ namespace purescript {
29
28
30 class boxed {
29 class boxed {
31 std::shared_ptr<void> shared;
30 std::shared_ptr<void> shared;
31+
32 public:
32 public:
33 union {
33 union {
34 int _int_;
34 int _int_;
@@ -36,8 +36,38 @@ namespace purescript {
36 bool _bool_;
36 bool _bool_;
37 };
37 };
38
38
39− using fn_t = std::function<boxed(const boxed&)>;
39+ class fn_t {
40− using eff_fn_t = std::function<boxed(void)>;
40+ public:
41+ virtual ~fn_t() {}
42+ virtual auto operator ()(const boxed&) const -> boxed = 0;
43+ };
44+
45+ template <typename T>
46+ class fn_template_t : public fn_t {
47+ T fn;
48+ public:
49+ fn_template_t(T f) : fn(std::move(f)) {}
50+ auto operator ()(const boxed& arg) const -> boxed override {
51+ return fn(arg);
52+ }
53+ };
54+
55+ class eff_fn_t {
56+ public:
57+ virtual ~eff_fn_t() {}
58+ virtual auto operator ()() const -> boxed = 0;
59+ };
60+
61+ template <typename T>
62+ class eff_fn_template_t : public eff_fn_t {
63+ T fn;
64+ public:
65+ eff_fn_template_t(T f) : fn(std::move(f)) {}
66+ auto operator ()() const -> boxed override {
67+ return fn();
68+ }
69+ };
70+
41 using dict_t = string_literal_dict_t<boxed>;
71 using dict_t = string_literal_dict_t<boxed>;
42 using array_t = std::deque<boxed>;
72 using array_t = std::deque<boxed>;
43
73
@@ -81,16 +111,18 @@ namespace purescript {
81
111
82 template <typename T,
112 template <typename T,
83 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
113 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
84− boxed(const T& f,
114+ boxed(T f,
85− typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0)
115+ typename std::enable_if<std::is_same<decltype(std::declval<T>()(std::declval<boxed>())),
116+ boxed>::value>::type* = 0)
86− : shared(std::make_shared<fn_t>(f)) {
117+ : shared(std::make_shared<fn_template_t<T>>(std::move(f))) {
87 }
118 }
88
119
89 template <typename T,
120 template <typename T,
90 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
121 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
91− boxed(const T& f,
122+ boxed(T f,
92− typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0)
123+ typename std::enable_if<std::is_same<decltype(std::declval<T>()()),
124+ boxed>::value>::type* = 0)
93− : shared(std::make_shared<eff_fn_t>(f)) {
125+ : shared(std::make_shared<eff_fn_template_t<T>>(std::move(f))) {
94 }
126 }
95
127
96 inline auto get() const noexcept -> void * {
128 inline auto get() const noexcept -> void * {