git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Faster primitive types (int, double, bool)
commitbad1d54b21e5c14d6011cfe28349144fcf97156b authorAndy Arvanitis <andyarvanitis@gmail.com> dateFri 25 Jan 2019, 21:03 (8 years ago) parent9eb0b93
1 file changed+64−10
runtime/purescript.h+64−10
runtime/purescript.h+64−10
@@ -30,6 +30,12 @@ namespace purescript {
3030 class boxed {
3131 std::shared_ptr<void> shared;
3232 public:
33+ union {
34+ int _int_;
35+ double _double_;
36+ bool _bool_;
37+ };
38+
3339 using fn_t = std::function<boxed(const boxed&)>;
3440 using eff_fn_t = std::function<boxed(void)>;
3541 using dict_t = string_literal_dict_t<boxed>;
@@ -45,9 +51,9 @@ namespace purescript {
4551 template <typename T>
4652 boxed(const std::shared_ptr<T>& other) : shared(other) {}
4753
48− boxed(const int n) : shared(std::make_shared<int>(n)) {}
54+ boxed(const int n) noexcept : _int_(n) {}
4955
50− boxed(const long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
56+ boxed(const long n) : _int_(static_cast<int>(n)) {
5157#if !defined(NDEBUG) // if debug build
5258 if (n < std::numeric_limits<int>::min() || n > std::numeric_limits<int>::max()) {
5359 throw std::runtime_error("integer out of range");
@@ -55,7 +61,7 @@ namespace purescript {
5561#endif // !defined(NDEBUG)
5662 }
5763
58− boxed(const unsigned long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
64+ boxed(const unsigned long n) : _int_(static_cast<int>(n)) {
5965#if !defined(NDEBUG) // if debug build
6066 if (n > std::numeric_limits<int>::max()) {
6167 throw std::runtime_error("integer out of range");
@@ -63,8 +69,8 @@ namespace purescript {
6369#endif // !defined(NDEBUG)
6470 }
6571
66− boxed(const double n) : shared(std::make_shared<double>(n)) {}
67− boxed(const bool b) : shared(std::make_shared<bool>(b)) {}
72+ boxed(const double n) noexcept : _double_(n) {}
73+ boxed(const bool b) noexcept : _bool_(b) {}
6874 boxed(const char s[]) : shared(std::make_shared<string>(s)) {}
6975 boxed(string&& s) : shared(std::make_shared<string>(std::move(s))) {}
7076 boxed(const string& s) : shared(std::make_shared<string>(s)) {}
@@ -201,29 +207,77 @@ namespace purescript {
201207 using dict_t = boxed::dict_t;
202208 using array_t = boxed::array_t;
203209
204− template <typename T, typename... Args>
210+ template <typename T, typename... Args,
211+ typename = typename std::enable_if<!std::is_same<T, int>::value &&
212+ !std::is_same<T, double>::value &&
213+ !std::is_same<T, bool>::value
214+ >::type>
205215 inline auto box(Args&&... args) -> boxed {
206216 return std::make_shared<T>(std::forward<Args>(args)...);
207217 }
208218
209− template <typename T>
219+ template <typename T,
220+ typename std::enable_if<std::is_same<T, int>::value, T>::type* = nullptr>
221+ inline auto box(T arg) noexcept -> boxed {
222+ return boxed(arg);
223+ }
224+
225+ template <typename T,
226+ typename std::enable_if<std::is_same<T, double>::value, T>::type* = nullptr>
227+ inline auto box(T arg) noexcept -> boxed {
228+ return boxed(arg);
229+ }
230+
231+ template <typename T,
232+ typename std::enable_if<std::is_same<T, bool>::value, T>::type* = nullptr>
233+ inline auto box(T arg) noexcept -> boxed {
234+ return boxed(arg);
235+ }
236+
237+ template <typename T,
238+ typename = typename std::enable_if<!std::is_same<T, int>::value &&
239+ !std::is_same<T, double>::value &&
240+ !std::is_same<T, bool>::value
241+ >::type>
210242 constexpr auto unbox(const boxed& b) -> const T& {
211243 return *static_cast<const T*>(b.get());
212244 }
213245
214− template <typename T>
246+ template <typename T,
247+ typename std::enable_if<std::is_same<T, int>::value, T>::type* = nullptr>
248+ constexpr auto unbox(const boxed& b) noexcept -> T {
249+ return b._int_;
250+ }
251+
252+ template <typename T,
253+ typename std::enable_if<std::is_same<T, double>::value, T>::type* = nullptr>
254+ constexpr auto unbox(const boxed& b) noexcept -> T {
255+ return b._double_;
256+ }
257+
258+ template <typename T,
259+ typename std::enable_if<std::is_same<T, bool>::value, T>::type* = nullptr>
260+ constexpr auto unbox(const boxed& b) noexcept -> T {
261+ return b._bool_;
262+ }
263+
264+ template <typename T,
265+ typename = typename std::enable_if<!std::is_same<T, int>::value &&
266+ !std::is_same<T, double>::value &&
267+ !std::is_same<T, bool>::value
268+ >::type>
215269 constexpr auto unbox(boxed& b) -> T& {
216270 return *static_cast<T*>(b.get());
217271 }
218272
219273 template <typename T>
220− constexpr auto unbox(const T value) -> T {
274+ constexpr auto unbox(const T value) noexcept -> T {
221275 return value;
222276 }
223277
224278 template <typename T,
225279 typename = typename std::enable_if<std::is_same<T, int>::value>::type>
226− constexpr auto unbox(const std::size_t value) -> long long {
280+ constexpr auto unbox(const std::size_t value) noexcept -> long long {
227281 return value;
228282 }
229283