Skip to content

Commit

Permalink
[embind] Allow optional types to contain pointers.
Browse files Browse the repository at this point in the history
Previously, register_vector and register_map didn't use std::optional,
but allowed pointers. After changing them to use std::optional, pointers
were no longer were allowed. This restores the previous behavior.

Fixes #21768
  • Loading branch information
brendandahl committed Apr 16, 2024
1 parent ebc7938 commit 85e1e49
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
4 changes: 3 additions & 1 deletion system/include/emscripten/bind.h
Expand Up @@ -1885,7 +1885,9 @@ void register_optional() {
return;
}
hasRun = true;
internal::_embind_register_optional(internal::TypeID<std::optional<T>>::get(), internal::TypeID<T>::get());
internal::_embind_register_optional(
internal::TypeID<std::optional<T>>::get(),
internal::TypeID<typename std::remove_pointer<T>::type>::get());
}
#endif

Expand Down
17 changes: 17 additions & 0 deletions test/embind/embind.test.js
Expand Up @@ -1160,6 +1160,14 @@ module({
assert.equal(20, vec.get(1));
vec.delete();
});

test("vectors can contain pointers", function() {
var vec = cm.emval_test_return_vector_pointers();
var small = vec.get(0);
assert.equal(7, small.member);
small.delete();
vec.delete();
});
});

BaseFixture.extend("map", function() {
Expand Down Expand Up @@ -1233,6 +1241,15 @@ module({
assert.equal(undefined, optional);
});

test("std::optional works with returning SmallClass pointer", function() {
var optional = cm.embind_test_return_optional_small_class_pointer(true);
assert.equal(7, optional.member);
optional.delete();

optional = cm.embind_test_return_optional_small_class(false);
assert.equal(undefined, optional);
});

test("std::optional works with returning string", function() {
var optional = cm.embind_test_return_optional_string(true);
assert.equal("hello", optional);
Expand Down
16 changes: 16 additions & 0 deletions test/embind/embind_test.cpp
Expand Up @@ -1309,6 +1309,12 @@ std::vector<std::shared_ptr<StringHolder>> emval_test_return_shared_ptr_vector()
return sharedStrVector;
}

std::vector<SmallClass*> emval_test_return_vector_pointers() {
std::vector<SmallClass*> vec;
vec.push_back(new SmallClass());
return vec;
}

void test_string_with_vec(const std::string& p1, std::vector<std::string>& v1) {
// THIS DOES NOT WORK -- need to get as val and then call vecFromJSArray
printf("%s\n", p1.c_str());
Expand Down Expand Up @@ -1339,6 +1345,12 @@ std::optional<SmallClass> embind_test_return_optional_small_class(bool create) {
}
return {};
}
std::optional<SmallClass*> embind_test_return_optional_small_class_pointer(bool create) {
if (create) {
return new SmallClass();
}
return {};
}

int embind_test_optional_int_arg(std::optional<int> arg) {
if (arg) {
Expand Down Expand Up @@ -1885,6 +1897,7 @@ EMSCRIPTEN_BINDINGS(tests) {
register_vector<emscripten::val>("EmValVector");
register_vector<float>("FloatVector");
register_vector<std::vector<int>>("IntegerVectorVector");
register_vector<SmallClass*>("SmallClassPointerVector");

class_<DummyForPointer>("DummyForPointer");

Expand Down Expand Up @@ -2352,6 +2365,7 @@ EMSCRIPTEN_BINDINGS(tests) {

function("emval_test_return_vector", &emval_test_return_vector);
function("emval_test_return_vector_of_vectors", &emval_test_return_vector_of_vectors);
function("emval_test_return_vector_pointers", &emval_test_return_vector_pointers);

register_vector<std::shared_ptr<StringHolder>>("SharedPtrVector");
function("emval_test_return_shared_ptr_vector", &emval_test_return_shared_ptr_vector);
Expand All @@ -2371,10 +2385,12 @@ EMSCRIPTEN_BINDINGS(tests) {
register_optional<int>();
register_optional<float>();
register_optional<SmallClass>();
register_optional<SmallClass*>();
register_optional<std::string>();
function("embind_test_return_optional_int", &embind_test_return_optional_int);
function("embind_test_return_optional_float", &embind_test_return_optional_float);
function("embind_test_return_optional_small_class", &embind_test_return_optional_small_class);
function("embind_test_return_optional_small_class_pointer", &embind_test_return_optional_small_class_pointer);
function("embind_test_return_optional_string", &embind_test_return_optional_string);
function("embind_test_optional_int_arg", &embind_test_optional_int_arg);
function("embind_test_optional_float_arg", &embind_test_optional_float_arg);
Expand Down

0 comments on commit 85e1e49

Please sign in to comment.