mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
Replace first_of_t with exactly_one_t
This commit is contained in:
parent
1ac19036d6
commit
82ece940fb
@ -456,7 +456,7 @@ using is_call_guard = is_instantiation<call_guard, T>;
|
||||
|
||||
/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
|
||||
template <typename... Extra>
|
||||
using extract_guard_t = typename first_of_t<is_call_guard, call_guard<>, Extra...>::type;
|
||||
using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
|
||||
|
||||
/// Check the number of named arguments at compile time
|
||||
template <typename... Extra,
|
||||
|
@ -502,20 +502,27 @@ constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate<Ts>:
|
||||
template <template<typename> class Predicate, typename... Ts>
|
||||
constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate<Ts>::value...); }
|
||||
|
||||
// Extracts the first type from the template parameter pack matching the predicate, or Default if none match.
|
||||
template <template<class> class Predicate, class Default, class... Ts> struct first_of;
|
||||
template <template<class> class Predicate, class Default> struct first_of<Predicate, Default> {
|
||||
using type = Default;
|
||||
/// Return the Nth element from the parameter pack
|
||||
template <size_t N, typename T, typename... Ts>
|
||||
struct pack_element { using type = typename pack_element<N - 1, Ts...>::type; };
|
||||
template <typename T, typename... Ts>
|
||||
struct pack_element<0, T, Ts...> { using type = T; };
|
||||
|
||||
/// Return the one and only type which matches the predicate, or Default if none match.
|
||||
/// If more than one type matches the predicate, fail at compile-time.
|
||||
template <template<typename> class Predicate, typename Default, typename... Ts>
|
||||
struct exactly_one {
|
||||
static constexpr auto found = constexpr_sum(Predicate<Ts>::value...);
|
||||
static_assert(found <= 1, "Found more than one type matching the predicate");
|
||||
|
||||
static constexpr auto index = found ? constexpr_first<Predicate, Ts...>() : 0;
|
||||
using type = conditional_t<found, typename pack_element<index, Ts...>::type, Default>;
|
||||
};
|
||||
template <template<class> class Predicate, class Default, class T, class... Ts>
|
||||
struct first_of<Predicate, Default, T, Ts...> {
|
||||
using type = typename std::conditional<
|
||||
Predicate<T>::value,
|
||||
T,
|
||||
typename first_of<Predicate, Default, Ts...>::type
|
||||
>::type;
|
||||
};
|
||||
template <template<class> class Predicate, class Default, class... T> using first_of_t = typename first_of<Predicate, Default, T...>::type;
|
||||
template <template<typename> class P, typename Default>
|
||||
struct exactly_one<P, Default> { using type = Default; };
|
||||
|
||||
template <template<typename> class Predicate, typename Default, typename... Ts>
|
||||
using exactly_one_t = typename exactly_one<Predicate, Default, Ts...>::type;
|
||||
|
||||
/// Defer the evaluation of type T until types Us are instantiated
|
||||
template <typename T, typename... /*Us*/> struct deferred_type { using type = T; };
|
||||
|
@ -888,9 +888,9 @@ class class_ : public detail::generic_type {
|
||||
|
||||
public:
|
||||
using type = type_;
|
||||
using type_alias = detail::first_of_t<is_subtype, void, options...>;
|
||||
using type_alias = detail::exactly_one_t<is_subtype, void, options...>;
|
||||
constexpr static bool has_alias = !std::is_void<type_alias>::value;
|
||||
using holder_type = detail::first_of_t<is_holder, std::unique_ptr<type>, options...>;
|
||||
using holder_type = detail::exactly_one_t<is_holder, std::unique_ptr<type>, options...>;
|
||||
using instance_type = detail::instance<type, holder_type>;
|
||||
|
||||
static_assert(detail::all_of<is_valid_class_option<options>...>::value,
|
||||
@ -1158,15 +1158,12 @@ public:
|
||||
using class_<Type>::def;
|
||||
using class_<Type>::def_property_readonly_static;
|
||||
using Scalar = typename std::underlying_type<Type>::type;
|
||||
template <typename T> using arithmetic_tag = std::is_same<T, arithmetic>;
|
||||
|
||||
template <typename... Extra>
|
||||
enum_(const handle &scope, const char *name, const Extra&... extra)
|
||||
: class_<Type>(scope, name, extra...), m_entries(), m_parent(scope) {
|
||||
|
||||
constexpr bool is_arithmetic =
|
||||
!std::is_same<detail::first_of_t<arithmetic_tag, void, Extra...>,
|
||||
void>::value;
|
||||
constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
|
||||
|
||||
auto m_entries_ptr = m_entries.inc_ref().ptr();
|
||||
def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str {
|
||||
|
Loading…
Reference in New Issue
Block a user