diff --git a/include/boost/python/suite/indexing/value_traits.hpp b/include/boost/python/suite/indexing/value_traits.hpp index 4eeb6fc5..618efdee 100755 --- a/include/boost/python/suite/indexing/value_traits.hpp +++ b/include/boost/python/suite/indexing/value_traits.hpp @@ -22,11 +22,19 @@ #define BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP #include +#include #include namespace boost { namespace python { namespace indexing { + // The value_traits template is used by default by all + // ContainerTraits templates. It can be overridden by specialization + // or by supplying the optional ValueTraits parameter to a container + // traits template. + template struct value_traits; + + // Implementation for default use template - struct value_traits { + struct default_value_traits { BOOST_STATIC_CONSTANT (bool, equality_comparable = true); typedef std::equal_to equal_to; @@ -37,6 +45,40 @@ namespace boost { namespace python { namespace indexing { template static void visitor_helper (PythonClass &, Policy const &) { } }; + + // Implementation using pointer indirection + template + struct indirect_value_traits : default_value_traits { + // Hide the base class versions of the comparisons, using these + // indirect versions + struct less : std::binary_function { + bool operator() (Ptr const &p1, Ptr const &p2) const { + return *p1 < *p2; + } + }; + + struct equal_to : std::binary_function { + bool operator() (Ptr const &p1, Ptr const &p2) const { + return *p1 == *p2; + } + }; + }; + + // Default implementation selection + template + struct value_traits + : default_value_traits + { + }; + +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + // Partial specialization for instances of boost::shared_ptr + template + struct value_traits< ::boost::shared_ptr > + : indirect_value_traits< ::boost::shared_ptr > + { + }; +#endif } } } #endif // BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP diff --git a/test/test_vector_shared.cpp b/test/test_vector_shared.cpp index df8f4fc0..394fba83 100755 --- a/test/test_vector_shared.cpp +++ b/test/test_vector_shared.cpp @@ -31,23 +31,6 @@ unsigned int_wrapper::our_object_counter = 0; BOOST_TT_BROKEN_COMPILER_SPEC (boost::shared_ptr) -template -struct indirect_value_traits : boost::python::indexing::value_traits { - // Hide the base class versions of the comparisons, using - // indirect versions - struct less : std::binary_function { - bool operator() (Ptr const &p1, Ptr const &p2) const { - return *p1 < *p2; - } - }; - - struct equal_to : std::binary_function { - bool operator() (Ptr const &p1, Ptr const &p2) const { - return *p1 == *p2; - } - }; -}; - BOOST_PYTHON_MODULE(test_vector_shared_ext) { namespace indexing = boost::python::indexing; @@ -66,11 +49,18 @@ BOOST_PYTHON_MODULE(test_vector_shared_ext) .def ("__cmp__", compare) ; - typedef indirect_value_traits value_traits_; +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + // Partial specialization of value_traits takes care of things + // automatically + typedef indexing::container_suite Suite1; +#else + // Otherwise do it the hard way + typedef indexing::indirect_value_traits value_traits_; typedef indexing::default_sequence_traits container_traits_; typedef indexing::default_algorithms algorithms_; typedef indexing::container_suite Suite1; +#endif boost::python::class_("Vector_shared") .def (Suite1())