From 8469f751cba1e4b187367ea7f2a9b5e54fe4df87 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 6 Jul 2016 00:40:54 -0400 Subject: [PATCH] Add _("s1", "s2") ternary & use TYPE_CASTER This commit adds an additional _ template function for compile-time selection between two description strings. This in turn allows the elimination of needing two name() methods in type_caster and type_caster, which allows them to start using PYBIND11_TYPE_CASTER instead, simplifying their code by eliminating all the code that they are duplicating from the macro. --- include/pybind11/cast.h | 17 +---------------- include/pybind11/descr.h | 13 +++++++++++++ include/pybind11/eigen.h | 36 ++++-------------------------------- 3 files changed, 18 insertions(+), 48 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 4f7bc2d01..a2a135e8e 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -369,22 +369,7 @@ public: } } - static handle cast(const T *src, return_value_policy policy, handle parent) { - return cast(*src, policy, parent); - } - - template ::value, int>::type = 0> - static PYBIND11_DESCR name() { return type_descr(_("int")); } - - template ::value, int>::type = 0> - static PYBIND11_DESCR name() { return type_descr(_("float")); } - - operator T*() { return &value; } - operator T&() { return value; } - - template using cast_op_type = pybind11::detail::cast_op_type; -protected: - T value; + PYBIND11_TYPE_CASTER(T, _::value>("int", "float")); }; template <> class type_caster { diff --git a/include/pybind11/descr.h b/include/pybind11/descr.h index 6c1d86432..0104e2b50 100644 --- a/include/pybind11/descr.h +++ b/include/pybind11/descr.h @@ -83,6 +83,16 @@ template struct int_to_str<0, Digits...> { static constexpr auto digits = descr({ ('0' + Digits)..., '\0' }, { nullptr }); }; +// Ternary description (like std::conditional) +template +constexpr typename std::enable_if>::type _(char const(&text1)[Size1], char const(&)[Size2]) { + return _(text1); +} +template +constexpr typename std::enable_if>::type _(char const(&)[Size1], char const(&text2)[Size2]) { + return _(text2); +} + template auto constexpr _() { return int_to_str::digits; } @@ -153,6 +163,9 @@ PYBIND11_NOINLINE inline descr _(const char *text) { return descr(text, types); } +template PYBIND11_NOINLINE typename std::enable_if::type _(const char *text1, const char *) { return _(text1); } +template PYBIND11_NOINLINE typename std::enable_if::type _(char const *, const char *text2) { return _(text2); } + template PYBIND11_NOINLINE descr _() { const std::type_info *types[2] = { &typeid(Type), nullptr }; return descr("%", types); diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index 718107947..fa4e9f642 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -96,10 +96,6 @@ struct type_caster::value>::t return true; } - static handle cast(const Type *src, return_value_policy policy, handle parent) { - return cast(*src, policy, parent); - } - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { if (isVector) { return array(buffer_info( @@ -136,15 +132,8 @@ struct type_caster::value>::t } } - template using cast_op_type = pybind11::detail::cast_op_type<_T>; - - static PYBIND11_DESCR name() { - return _("numpy.ndarray[dtype=") + npy_format_descriptor::name() + - _(", shape=(") + rows() + _(", ") + cols() + _(")]"); - } - - operator Type*() { return &value; } - operator Type&() { return value; } + PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[dtype=") + npy_format_descriptor::name() + + _(", shape=(") + rows() + _(", ") + cols() + _(")]")); protected: template ::type = 0> @@ -155,9 +144,6 @@ protected: static PYBIND11_DESCR cols() { return _("n"); } template ::type = 0> static PYBIND11_DESCR cols() { return _(); } - -protected: - Type value; }; template @@ -211,10 +197,6 @@ struct type_caster::value>:: return true; } - static handle cast(const Type *src, return_value_policy policy, handle parent) { - return cast(*src, policy, parent); - } - static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { const_cast(src).makeCompressed(); @@ -272,18 +254,8 @@ struct type_caster::value>:: ).release(); } - template using cast_op_type = pybind11::detail::cast_op_type<_T>; - - template ::type = 0> - static PYBIND11_DESCR name() { return _("scipy.sparse.csr_matrix[dtype=") + npy_format_descriptor::name() + _("]"); } - template ::type = 0> - static PYBIND11_DESCR name() { return _("scipy.sparse.csc_matrix[dtype=") + npy_format_descriptor::name() + _("]"); } - - operator Type*() { return &value; } - operator Type&() { return value; } - -protected: - Type value; + PYBIND11_TYPE_CASTER(Type, _<(Type::Flags & Eigen::RowMajorBit) != 0>("scipy.sparse.csr_matrix[dtype=", "scipy.sparse.csc_matrix[dtype=") + + npy_format_descriptor::name() + _("]")); }; NAMESPACE_END(detail)