From b82c0ea16458dcef55bd0ab8e93960a0a2a1f61d Mon Sep 17 00:00:00 2001 From: Sergey Lyskov Date: Thu, 12 May 2016 18:17:02 -0400 Subject: [PATCH] Refactoring had_equal_operator so it now can handle STL containers which have operator== always defined. Adding specialization for vector, deque, set, pair and map types. --- example/example17.cpp | 2 ++ example/example17.py | 5 ++- include/pybind11/stl_binders.h | 61 ++++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/example/example17.cpp b/example/example17.cpp index 8370b5c68..feeadc38f 100644 --- a/example/example17.cpp +++ b/example/example17.cpp @@ -34,4 +34,6 @@ void init_ex17(py::module &m) { pybind11::vector_binder(m, "VectorInt"); pybind11::vector_binder(m, "VectorA"); + + pybind11::vector_binder< std::vector >(m, "VectorVectorA"); } diff --git a/example/example17.py b/example/example17.py index 52cda4238..4138d1763 100644 --- a/example/example17.py +++ b/example/example17.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from __future__ import print_function -from example import VectorInt, VectorA, A +from example import VectorInt, A, VectorA, VectorVectorA v_int = VectorInt(2) print(len(v_int)) @@ -29,3 +29,6 @@ v_a = VectorA() v_a.append(A(1)) v_a.append(A(2)) print(v_a) + +vv_a = VectorVectorA() +vv_a.append(v_a) diff --git a/include/pybind11/stl_binders.h b/include/pybind11/stl_binders.h index 93b5cad3b..0588ba2b7 100644 --- a/include/pybind11/stl_binders.h +++ b/include/pybind11/stl_binders.h @@ -17,33 +17,52 @@ #include #include #include - +#include +#include +#include +#include NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(detail) template -constexpr auto has_equal_operator(int) -> decltype(std::declval() == std::declval(), bool()) { return true; } +constexpr auto has_equal_operator(int) -> decltype(std::declval() == std::declval(), std::declval() != std::declval(), bool()) { return true; } template constexpr bool has_equal_operator(...) { return false; } -// Workaround for MSVC 2015 -template +template struct has_equal_operator_s { + static const bool value = false; +}; +template +struct has_equal_operator_s +{ static const bool value = has_equal_operator(0); }; - - - -template -constexpr auto has_not_equal_operator(int) -> decltype(std::declval() != std::declval(), bool()) { return true; } -template -constexpr bool has_not_equal_operator(...) { return false; } - -// Workaround for MSVC 2015 -template -struct has_not_equal_operator_s { - static const bool value = has_not_equal_operator(0); +template<> template +struct has_equal_operator_s< std::vector > +{ + static const bool value = has_equal_operator_s::value; +}; +template<> template +struct has_equal_operator_s< std::deque > +{ + static const bool value = has_equal_operator_s::value; +}; +template<> template +struct has_equal_operator_s< std::set > +{ + static const bool value = has_equal_operator_s::value; +}; +template<> template +struct has_equal_operator_s< std::pair > +{ + static const bool value = has_equal_operator_s::value and has_equal_operator_s::value; +}; +template<> template +struct has_equal_operator_s< std::map > +{ + static const bool value = has_equal_operator_s::value and has_equal_operator_s::value; }; @@ -103,6 +122,7 @@ void vector_maybe_has_equal_operator(Class_ &cl) { using T = typename Vector::value_type; cl.def(pybind11::self == pybind11::self); + cl.def(pybind11::self != pybind11::self); cl.def("count", [](Vector const &v, T const & value) { return std::count(v.begin(), v.end(), value); }, "counts the elements that are equal to value"); @@ -118,14 +138,6 @@ template::value >::type * = nullptr> -void vector_maybe_has_not_equal_operator(Class_ &cl) { - cl.def(pybind11::self != pybind11::self); -} -template::value >::type * = nullptr> -void vector_maybe_has_not_equal_operator(Class_ &) {} - - template::value >::type * = nullptr> void vector_maybe_has_insertion_operator(char const *name, Class_ &cl) { using size_type = typename Vector::size_type; @@ -244,7 +256,6 @@ pybind11::class_, holder_type > vector_binder(pybind11 // Comparisons detail::vector_maybe_has_equal_operator(cl); - detail::vector_maybe_has_not_equal_operator(cl); // Printing detail::vector_maybe_has_insertion_operator(name, cl);