Skip to content

Commit

Permalink
Add support for noexcept keyword to embind. (#17140)
Browse files Browse the repository at this point in the history
* Add support for noexcept keyword in C++ class methods

* Remove code duplication after adding support for noexcept

* Add support for noexcept keyword to embind.

This continues the work from #15273 and #10613 which supports the noexcept
keyword by ignoring it on c++17 compilers. I've also added a missing
template for class methods and tests for each possible use of noexcept.

Co-authored-by: Hunter Richards <[email protected]>
  • Loading branch information
brendandahl and harichards authored Jun 10, 2022
1 parent b725fbf commit 4549d9d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
30 changes: 30 additions & 0 deletions system/include/emscripten/bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,12 @@ struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
}
};

#ifdef __cpp_noexcept_function_type
template<typename GetterReturnType, typename GetterThisType>
struct GetterPolicy<GetterReturnType (GetterThisType::*)() const noexcept>
: GetterPolicy<GetterReturnType (GetterThisType::*)() const> {};
#endif

template<typename GetterReturnType, typename GetterThisType>
struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
typedef GetterReturnType ReturnType;
Expand Down Expand Up @@ -710,6 +716,12 @@ struct SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType)> {
}
};

#ifdef __cpp_noexcept_function_type
template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
struct SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType) noexcept>
: SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType)> {};
#endif

template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
struct SetterPolicy<SetterReturnType (*)(SetterThisType&, SetterArgumentType)> {
typedef SetterArgumentType ArgumentType;
Expand Down Expand Up @@ -1326,6 +1338,12 @@ struct RegisterClassMethod<ReturnType (ClassType::*)(Args...)> {
}
};

#ifdef __cpp_noexcept_function_type
template<typename ClassType, typename ReturnType, typename... Args>
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) noexcept>
: RegisterClassMethod<ReturnType (ClassType::*)(Args...)> {};
#endif

template<typename ClassType, typename ReturnType, typename... Args>
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) const> {

Expand All @@ -1347,6 +1365,12 @@ struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) const> {
}
};

#ifdef __cpp_noexcept_function_type
template<typename ClassType, typename ReturnType, typename... Args>
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) const noexcept>
: RegisterClassMethod<ReturnType (ClassType::*)(Args...) const> {};
#endif

template<typename ReturnType, typename ThisType, typename... Args>
struct RegisterClassMethod<ReturnType (*)(ThisType, Args...)> {

Expand All @@ -1367,6 +1391,12 @@ struct RegisterClassMethod<ReturnType (*)(ThisType, Args...)> {
}
};

#ifdef __cpp_noexcept_function_type
template<typename ReturnType, typename ThisType, typename... Args>
struct RegisterClassMethod<ReturnType (*)(ThisType, Args...) noexcept>
: RegisterClassMethod<ReturnType (*)(ThisType, Args...)> {};
#endif

template<typename ReturnType, typename ThisType, typename... Args>
struct RegisterClassMethod<std::function<ReturnType (ThisType, Args...)>> {

Expand Down
22 changes: 22 additions & 0 deletions tests/embind/embind_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,22 @@ class BigClass {
}
};

class NoExceptClass {
public:
int getValue() noexcept {
return 42;
}
int getValueConst() const noexcept {
return 43;
}
int getX() const noexcept { return x; }
void setX(int x_) noexcept { x = x_; }
private:
int x;
};

void embind_test_no_except_function(NoExceptClass&) noexcept {}

class ParentClass {
public:
ParentClass(): bigClass() {};
Expand Down Expand Up @@ -1970,6 +1986,12 @@ EMSCRIPTEN_BINDINGS(tests) {
.function("getMember", &TemplateClass<int>::getMember)
;

class_<NoExceptClass>("NoExceptClass")
.function("embind_test_no_except_function", &embind_test_no_except_function)
.function("getValue", &NoExceptClass::getValue)
.function("getValueConst", &NoExceptClass::getValueConst)
.property("x", &NoExceptClass::getX, &NoExceptClass::setX);

class_<ContainsTemplatedMemberClass>("ContainsTemplatedMemberClass")
.constructor<>()
.function("getTestTemplate", &ContainsTemplatedMemberClass::getTestTemplate)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -2499,6 +2499,8 @@ def test_embind_closure_no_dynamic_execution(self):
def test_embind(self, extra_args):
test_cases = [
(['-lembind']),
# Ensure embind compiles under C++17 where "noexcept" became part of the function signature.
(['-lembind', '-std=c++17']),
(['-lembind', '-O1']),
(['-lembind', '-O2']),
(['-lembind', '-O2', '-sALLOW_MEMORY_GROWTH', test_file('embind/isMemoryGrowthEnabled=true.cpp')]),
Expand Down

0 comments on commit 4549d9d

Please sign in to comment.