| 2275 | |
| 2276 | template <typename type_, typename... options> |
| 2277 | class class_ : public detail::generic_type { |
| 2278 | template <typename T> |
| 2279 | using is_holder = detail::is_holder_type<type_, T>; |
| 2280 | template <typename T> |
| 2281 | using is_subtype = detail::is_strict_base_of<type_, T>; |
| 2282 | template <typename T> |
| 2283 | using is_base = detail::is_strict_base_of<T, type_>; |
| 2284 | // struct instead of using here to help MSVC: |
| 2285 | template <typename T> |
| 2286 | struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {}; |
| 2287 | |
| 2288 | public: |
| 2289 | using type = type_; |
| 2290 | using type_alias = detail::exactly_one_t<is_subtype, void, options...>; |
| 2291 | constexpr static bool has_alias = !std::is_void<type_alias>::value; |
| 2292 | using holder_type = detail::exactly_one_t<is_holder, default_holder_type<type>, options...>; |
| 2293 | |
| 2294 | static_assert(detail::all_of<is_valid_class_option<options>...>::value, |
| 2295 | "Unknown/invalid class_ template parameters provided"); |
| 2296 | |
| 2297 | static_assert(!has_alias || std::is_polymorphic<type>::value, |
| 2298 | "Cannot use an alias class (aka trampoline) with a non-polymorphic type"); |
| 2299 | |
| 2300 | #ifndef PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE |
| 2301 | static_assert(!has_alias || !detail::is_smart_holder<holder_type>::value |
| 2302 | || std::is_base_of<trampoline_self_life_support, type_alias>::value, |
| 2303 | "Alias class (aka trampoline) must inherit from" |
| 2304 | " pybind11::trampoline_self_life_support if used in combination with" |
| 2305 | " pybind11::smart_holder"); |
| 2306 | #endif |
| 2307 | static_assert(!has_alias || detail::is_smart_holder<holder_type>::value |
| 2308 | || !std::is_base_of<trampoline_self_life_support, type_alias>::value, |
| 2309 | "pybind11::trampoline_self_life_support is a smart_holder feature, therefore" |
| 2310 | " an alias class (aka trampoline) should inherit from" |
| 2311 | " pybind11::trampoline_self_life_support only if used in combination with" |
| 2312 | " pybind11::smart_holder"); |
| 2313 | |
| 2314 | PYBIND11_OBJECT(class_, generic_type, PyType_Check) |
| 2315 | |
| 2316 | template <typename... Extra> |
| 2317 | class_(handle scope, const char *name, const Extra &...extra) { |
| 2318 | using namespace detail; |
| 2319 | |
| 2320 | // MI can only be specified via class_ template options, not constructor parameters |
| 2321 | static_assert( |
| 2322 | none_of<is_pyobject<Extra>...>::value || // no base class arguments, or: |
| 2323 | (constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base |
| 2324 | constexpr_sum(is_base<options>::value...) == 0 && // no template option bases |
| 2325 | // no multiple_inheritance attr |
| 2326 | none_of<std::is_same<multiple_inheritance, Extra>...>::value), |
| 2327 | "Error: multiple inheritance bases must be specified via class_ template options"); |
| 2328 | |
| 2329 | type_record record; |
| 2330 | record.scope = scope; |
| 2331 | record.name = name; |
| 2332 | record.type = &typeid(type); |
| 2333 | record.type_size = sizeof(conditional_t<has_alias, type_alias, type>); |
| 2334 | record.type_align = alignof(conditional_t<has_alias, type_alias, type> &); |
nothing calls this directly
no test coverage detected