about summary refs log tree commit diff
path: root/third_party/immer/extra/js/immer.cpp
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-07-15T07·20+0100
committerVincent Ambo <mail@tazj.in>2020-07-15T07·23+0100
commit1213b086a1015a662ab7ebd658f784534fd3116a (patch)
treed3bc8f3b7f40b8b60f0ef6fbd649cf765f4fdfb6 /third_party/immer/extra/js/immer.cpp
parent1390827b9ea1e04bc9863e48930bfd16db3b716e (diff)
parent7f19d641647ac4ef313ed88d6b5c140983ce5436 (diff)
merge(3p/immer): Subtree merge at 'ad3e3556d' as 'third_party/immer' r/1299
Change-Id: I9636a41ad44b4218293833fd3e9456d9b07c731b
Diffstat (limited to 'third_party/immer/extra/js/immer.cpp')
-rw-r--r--third_party/immer/extra/js/immer.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/third_party/immer/extra/js/immer.cpp b/third_party/immer/extra/js/immer.cpp
new file mode 100644
index 0000000000..d0d77c8a2c
--- /dev/null
+++ b/third_party/immer/extra/js/immer.cpp
@@ -0,0 +1,79 @@
+//
+// immer: immutable data structures for C++
+// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
+//
+// This software is distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
+//
+
+#include <immer/vector.hpp>
+#include <immer/refcount/unsafe_refcount_policy.hpp>
+#include <emscripten/bind.h>
+
+namespace {
+
+using memory_t = immer::memory_policy<
+    immer::unsafe_free_list_heap_policy<immer::malloc_heap>,
+    immer::unsafe_refcount_policy>;
+
+template <typename T>
+using js_vector_t = immer::vector<T, memory_t>;
+
+template <typename VectorT>
+VectorT range(typename VectorT::value_type first,
+              typename VectorT::value_type last)
+{
+    auto v = VectorT{};
+    for (; first != last; ++first)
+        v = std::move(v).push_back(first);
+    return v;
+}
+
+template <typename VectorT>
+VectorT range_slow(typename VectorT::value_type first,
+                   typename VectorT::value_type last)
+{
+    auto v = VectorT{};
+    for (; first != last; ++first)
+        v = v.push_back(first);
+    return v;
+}
+
+template <typename VectorT>
+VectorT push_back(VectorT& v, typename VectorT::value_type x)
+{ return v.push_back(x); }
+
+template <typename VectorT>
+VectorT set(VectorT& v, std::size_t i, typename VectorT::value_type x)
+{ return v.set(i, x); }
+
+template <typename T>
+void bind_vector(const char* name)
+{
+    using emscripten::class_;
+
+    using vector_t = js_vector_t<T>;
+
+    class_<vector_t>(name)
+        .constructor()
+        .function("push",  &push_back<vector_t>)
+        .function("set",   &set<vector_t>)
+        .function("get",   &vector_t::operator[])
+        .property("size",  &vector_t::size);
+}
+
+} // anonymous namespace
+
+EMSCRIPTEN_BINDINGS(immer)
+{
+    using emscripten::function;
+
+    bind_vector<emscripten::val>("Vector");
+    bind_vector<int>("VectorInt");
+    bind_vector<double>("VectorNumber");
+
+    function("range_int", &range<js_vector_t<int>>);
+    function("rangeSlow_int", &range_slow<js_vector_t<int>>);
+    function("range_double", &range<js_vector_t<double>>);
+    function("rangeSlow_double", &range_slow<js_vector_t<double>>);
+}