| 1983 | |
| 1984 | template <typename type_, typename... options> |
| 1985 | class class_ : public detail::generic_type { |
| 1986 | template <typename T> |
| 1987 | using is_holder = detail::is_holder_type<type_, T>; |
| 1988 | template <typename T> |
| 1989 | using is_subtype = detail::is_strict_base_of<type_, T>; |
| 1990 | template <typename T> |
| 1991 | using is_base = detail::is_strict_base_of<T, type_>; |
| 1992 | // struct instead of using here to help MSVC: |
| 1993 | template <typename T> |
| 1994 | struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {}; |
| 1995 | |
| 1996 | public: |
| 1997 | using type = type_; |
| 1998 | using type_alias = detail::exactly_one_t<is_subtype, void, options...>; |
| 1999 | constexpr static bool has_alias = !std::is_void<type_alias>::value; |
| 2000 | using holder_type = detail::exactly_one_t<is_holder, default_holder_type<type>, options...>; |
| 2001 | |
| 2002 | static_assert(detail::all_of<is_valid_class_option<options>...>::value, |
| 2003 | "Unknown/invalid class_ template parameters provided"); |
| 2004 | |
| 2005 | static_assert(!has_alias || std::is_polymorphic<type>::value, |
| 2006 | "Cannot use an alias class (aka trampoline) with a non-polymorphic type"); |
| 2007 | |
| 2008 | #ifndef PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE |
| 2009 | static_assert(!has_alias || !detail::is_smart_holder<holder_type>::value |
| 2010 | || std::is_base_of<trampoline_self_life_support, type_alias>::value, |
| 2011 | "Alias class (aka trampoline) must inherit from" |
| 2012 | " pybind11::trampoline_self_life_support if used in combination with" |
| 2013 | " pybind11::smart_holder"); |
| 2014 | #endif |
| 2015 | static_assert(!has_alias || detail::is_smart_holder<holder_type>::value |
| 2016 | || !std::is_base_of<trampoline_self_life_support, type_alias>::value, |
| 2017 | "pybind11::trampoline_self_life_support is a smart_holder feature, therefore" |
| 2018 | " an alias class (aka trampoline) should inherit from" |
| 2019 | " pybind11::trampoline_self_life_support only if used in combination with" |
| 2020 | " pybind11::smart_holder"); |
| 2021 | |
| 2022 | PYBIND11_OBJECT(class_, generic_type, PyType_Check) |
| 2023 | |
| 2024 | template <typename... Extra> |
| 2025 | class_(handle scope, const char *name, const Extra &...extra) { |
| 2026 | using namespace detail; |
| 2027 | |
| 2028 | // MI can only be specified via class_ template options, not constructor parameters |
| 2029 | static_assert( |
| 2030 | none_of<is_pyobject<Extra>...>::value || // no base class arguments, or: |
| 2031 | (constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base |
| 2032 | constexpr_sum(is_base<options>::value...) == 0 && // no template option bases |
| 2033 | // no multiple_inheritance attr |
| 2034 | none_of<std::is_same<multiple_inheritance, Extra>...>::value), |
| 2035 | "Error: multiple inheritance bases must be specified via class_ template options"); |
| 2036 | |
| 2037 | type_record record; |
| 2038 | record.scope = scope; |
| 2039 | record.name = name; |
| 2040 | record.type = &typeid(type); |
| 2041 | record.type_size = sizeof(conditional_t<has_alias, type_alias, type>); |
| 2042 | record.type_align = alignof(conditional_t<has_alias, type_alias, type> &); |
nothing calls this directly
no test coverage detected