Improve and cleanup make_foreign_class()
No need to have two versions of this. Static assert when users specify ambiguous overloads. Currently overloads are discriminated only by parameter count, not types, so we need to enforce this.
This commit is contained in:
parent
a8cef95cb9
commit
4d3dfce93f
2 changed files with 62 additions and 15 deletions
|
@ -71,6 +71,16 @@ namespace wren {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ForeignParamHelper {
|
||||
static constexpr std::size_t argument_count = 1;
|
||||
};
|
||||
|
||||
template <template <typename...> class Pack, typename... PackArgs>
|
||||
struct ForeignParamHelper<Pack<PackArgs...>> {
|
||||
static constexpr std::size_t argument_count = sizeof...(PackArgs);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ForeignClassHelper<T> {
|
||||
static bool construct (VM& vm, int cardinality, void* memory) {
|
||||
|
@ -95,10 +105,31 @@ namespace wren {
|
|||
ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, memory);
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Search, std::size_t... Values>
|
||||
struct AssertIfDuplicateValues {
|
||||
static_assert(sizeof...(Values) == 0, "Code bug?");
|
||||
};
|
||||
|
||||
template <std::size_t Search, std::size_t Value, std::size_t... Values>
|
||||
struct AssertIfDuplicateValues<Search, Value, Values...> : AssertIfDuplicateValues<Search, Values...>, AssertIfDuplicateValues<Value, Values...> {
|
||||
static_assert(Search != Value, "Constructor overloads with the same argument counts are not currently allowed");
|
||||
static constexpr std::size_t value = 1;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
constexpr void static_assert_all_packs_are_unique() {
|
||||
if constexpr (sizeof...(Args) > 0) {
|
||||
constexpr auto dummy = AssertIfDuplicateValues<ForeignParamHelper<Args>::argument_count...>::value;
|
||||
static_assert(dummy == 1); //always true
|
||||
}
|
||||
}
|
||||
} //namespace detail
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline foreign_class_t make_overloaded_foreign_class() {
|
||||
inline foreign_class_t make_foreign_class() {
|
||||
detail::static_assert_all_packs_are_unique<Args...>();
|
||||
|
||||
foreign_class_t ret;
|
||||
ret.allocate = [](VM& vm) {
|
||||
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
||||
|
@ -116,9 +147,4 @@ namespace wren {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline foreign_class_t make_foreign_class() {
|
||||
return make_overloaded_foreign_class<T, std::tuple<Args...>>();
|
||||
}
|
||||
} //namespace wren
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue