Skip to content

Commit 2e2ec08

Browse files
authored
Add missing template parameters to register_map and register_vector (#23625)
Add missing template args to register_map and register_vector to allow this kind of bindings: ``` #include <emscripten.h> #include <emscripten/bind.h> std::map<std::string, std::string, std::greater<std::string>> get_map() { std::map<std::string, std::string, std::greater<std::string>> m; m["a"] = "b"; m["c"] = "d"; return m; } EMSCRIPTEN_BINDINGS(test_map) { emscripten::register_map<std::string, std::string, std::greater<std::string>>("StringMap"); emscripten::function("get_map", &get_map); } ```
1 parent fe8c2fa commit 2e2ec08

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

site/source/docs/porting/connecting_cpp_and_javascript/embind.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ Out of the box, *embind* provides converters for many standard C++ types:
10711071
\*\*Requires BigInt support to be enabled with the `-sWASM_BIGINT` flag.
10721072

10731073
For convenience, *embind* provides factory functions to register
1074-
``std::vector<T>`` (:cpp:func:`register_vector`), ``std::map<K, V>``
1074+
``std::vector<T, class Allocator=std::allocator<T>>`` (:cpp:func:`register_vector`), ``std::map<K, V, class Compare=std::less<K>, class Allocator=std::allocator<std::pair<const K, V>>>``
10751075
(:cpp:func:`register_map`), and ``std::optional<T>`` (:cpp:func:`register_optional`) types:
10761076

10771077
.. code:: cpp

system/include/emscripten/bind.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,9 +2073,9 @@ struct VectorAccess {
20732073

20742074
} // end namespace internal
20752075

2076-
template<typename T>
2077-
class_<std::vector<T>> register_vector(const char* name) {
2078-
typedef std::vector<T> VecType;
2076+
template<typename T, class Allocator=std::allocator<T>>
2077+
class_<std::vector<T, Allocator>> register_vector(const char* name) {
2078+
typedef std::vector<T, Allocator> VecType;
20792079
#if __cplusplus >= 201703L
20802080
register_optional<T>();
20812081
#endif
@@ -2151,9 +2151,10 @@ struct MapAccess {
21512151

21522152
} // end namespace internal
21532153

2154-
template<typename K, typename V>
2155-
class_<std::map<K, V>> register_map(const char* name) {
2156-
typedef std::map<K,V> MapType;
2154+
template<typename K, typename V, class Compare = std::less<K>,
2155+
class Allocator = std::allocator<std::pair<const K, V>>>
2156+
class_<std::map<K, V, Compare, Allocator>> register_map(const char* name) {
2157+
typedef std::map<K,V, Compare, Allocator> MapType;
21572158
#if __cplusplus >= 201703L
21582159
register_optional<V>();
21592160
#endif

test/embind/embind.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,26 @@ module({
11851185
});
11861186
});
11871187

1188+
BaseFixture.extend("map_with_greater_comparator", function() {
1189+
test("std::map with std::greater comparator", function() {
1190+
var map = cm.embind_test_get_int_string_greater_map();
1191+
assert.equal(2, map.size());
1192+
assert.equal("one", map.get(1));
1193+
assert.equal("two", map.get(2));
1194+
map.delete();
1195+
});
1196+
1197+
test("std::map with std::greater comparator keys are sorted in reverse", function() {
1198+
var map = cm.embind_test_get_int_string_greater_map();
1199+
var keys = map.keys();
1200+
assert.equal(2, keys.size());
1201+
assert.equal(2, keys.get(0));
1202+
assert.equal(1, keys.get(1));
1203+
keys.delete();
1204+
map.delete();
1205+
});
1206+
});
1207+
11881208
BaseFixture.extend("optional", function() {
11891209
if (!("embind_test_return_optional_int" in cm)) {
11901210
return;

test/embind/embind_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,15 @@ std::map<std::string, int> embind_test_get_string_int_map() {
885885
return m;
886886
};
887887

888+
std::map<int, std::string, std::greater<int>> embind_test_get_int_string_greater_map() {
889+
std::map<int, std::string, std::greater<int>> m;
890+
891+
m[1] = "one";
892+
m[2] = "two";
893+
894+
return m;
895+
}
896+
888897
struct Vector {
889898
Vector() = delete;
890899

@@ -2373,6 +2382,9 @@ EMSCRIPTEN_BINDINGS(tests) {
23732382

23742383
register_map<std::string, int>("StringIntMap");
23752384
function("embind_test_get_string_int_map", embind_test_get_string_int_map);
2385+
2386+
register_map<int, std::string, std::greater<int>>("IntStringMapGreater");
2387+
function("embind_test_get_int_string_greater_map", embind_test_get_int_string_greater_map);
23762388

23772389
function("embind_test_getglobal", &embind_test_getglobal);
23782390

0 commit comments

Comments
 (0)