@@ -26,6 +26,11 @@ PYBIND11_NAMESPACE_BEGIN(detail)
26
26
class args_proxy;
27
27
inline bool isinstance_generic (handle obj, const std::type_info &tp);
28
28
29
+ // Indicates that type is generic and and does not have a specialized
30
+ // `type_caster<>` specialization. Defined in `cast.h`.
31
+ template <typename T, typename SFINAE>
32
+ struct is_generic_type ;
33
+
29
34
// Accessor forward declarations
30
35
template <typename Policy> class accessor ;
31
36
namespace accessor_policies {
@@ -380,13 +385,18 @@ class error_already_set : public std::runtime_error {
380
385
/* * \ingroup python_builtins
381
386
\rst
382
387
Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of
383
- `object` or a class which was exposed to Python as ``py::class_<T>``.
388
+ `object` or a class which was exposed to Python as ``py::class_<T>`` (generic) .
384
389
\endrst */
385
390
template <typename T, detail::enable_if_t <std::is_base_of<object, T>::value, int > = 0 >
386
391
bool isinstance (handle obj) { return T::check_ (obj); }
387
392
388
393
template <typename T, detail::enable_if_t <!std::is_base_of<object, T>::value, int > = 0 >
389
- bool isinstance (handle obj) { return detail::isinstance_generic (obj, typeid (T)); }
394
+ bool isinstance (handle obj) {
395
+ static_assert (
396
+ is_generic_type<T>::value,
397
+ " isisntance<T>() requires specialization for this type" );
398
+ return detail::isinstance_generic (obj, typeid (T));
399
+ }
390
400
391
401
template <> inline bool isinstance<handle>(handle) = delete ;
392
402
template <> inline bool isinstance<object>(handle obj) { return obj.ptr () != nullptr ; }
@@ -941,6 +951,21 @@ class iterable : public object {
941
951
PYBIND11_OBJECT_DEFAULT (iterable, object, detail::PyIterable_Check)
942
952
};
943
953
954
+ // / Provides similar interface to `iterable`, but constraining the intended
955
+ // / type.
956
+ // / @warning Due to usage of `isinstance<T>()` in the related type-caster, this
957
+ // / does *not* work for iterables of type-converted values (e.g. `int`).
958
+ template <typename T>
959
+ class iterable_t : public py ::iterable {
960
+ public:
961
+ // See type_caster specialization.
962
+ static_assert (
963
+ is_generic_type<T>::value || is_pyobject<T>::value,
964
+ " iterable_t can only be used with pyobjects and generic types "
965
+ " (py::class_<T>" );
966
+ using py::iterable::iterable;
967
+ };
968
+
944
969
class bytes ;
945
970
946
971
class str : public object {
0 commit comments