From 91db6f2d50e4b37a14752107591977d3f4da3e30 Mon Sep 17 00:00:00 2001 From: Raoul Gough Date: Mon, 10 Nov 2003 18:06:41 +0000 Subject: [PATCH] MSVC6 and 7 compatibility fixes [SVN r20779] --- .../python/suite/indexing/algo_selector.hpp | 14 +- .../python/suite/indexing/algorithms.hpp | 61 +++--- .../python/suite/indexing/container_proxy.hpp | 193 ++++++++++++++---- .../python/suite/indexing/container_suite.hpp | 6 +- .../suite/indexing/container_traits.hpp | 62 +++--- include/boost/python/suite/indexing/deque.hpp | 8 + .../python/suite/indexing/element_proxy.hpp | 25 ++- .../suite/indexing/element_proxy_traits.hpp | 10 +- .../suite/indexing/int_slice_helper.hpp | 41 +++- .../python/suite/indexing/iterator_range.hpp | 40 +++- .../python/suite/indexing/iterator_traits.hpp | 14 +- include/boost/python/suite/indexing/list.hpp | 8 + include/boost/python/suite/indexing/map.hpp | 30 ++- .../python/suite/indexing/proxy_iterator.hpp | 61 +++++- include/boost/python/suite/indexing/set.hpp | 17 +- .../suite/indexing/shared_proxy_impl.hpp | 10 +- include/boost/python/suite/indexing/slice.hpp | 19 +- .../python/suite/indexing/slice_handler.hpp | 105 +++++----- .../python/suite/indexing/suite_utils.hpp | 2 +- .../python/suite/indexing/value_traits.hpp | 6 +- .../boost/python/suite/indexing/vector.hpp | 8 + .../boost/python/suite/indexing/visitor.hpp | 10 +- .../python/suite/indexing/workaround.hpp | 27 ++- src/indexing/python_iterator.cpp | 10 +- src/indexing/slice.cpp | 15 +- test/int_wrapper.hpp | 3 + test/test_array_ext.cpp | 26 ++- test/test_container_proxy.cpp | 39 +++- test/test_deque_ext.cpp | 28 +-- test/test_indexing_const.cpp | 14 +- test/test_list_ext.cpp | 10 +- test/test_vector_ext.cpp | 39 ++-- test/test_vector_shared.cpp | 75 ++++++- test/testnonlinear.cpp | 21 +- 34 files changed, 773 insertions(+), 284 deletions(-) diff --git a/include/boost/python/suite/indexing/algo_selector.hpp b/include/boost/python/suite/indexing/algo_selector.hpp index 47f96db8..822bb02c 100755 --- a/include/boost/python/suite/indexing/algo_selector.hpp +++ b/include/boost/python/suite/indexing/algo_selector.hpp @@ -21,9 +21,19 @@ #ifndef BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP #define BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP +#include + namespace boost { namespace python { namespace indexing { namespace detail { - template class selector_impl; + template class selector_impl +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + { + // Bogus types to prevent compile errors due to ETI + typedef selector_impl mutable_algorithms; + typedef selector_impl const_algorithms; + } +#endif + ; // selector_impl specializations should include *two* publically // accessible typedefs, called mutable_algorithms and @@ -41,12 +51,14 @@ namespace boost { namespace python { namespace indexing { { }; +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // Partial specialization for const containers template struct algo_selector : public detail::selector_impl::const_algorithms { }; +#endif } } } #endif // BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP diff --git a/include/boost/python/suite/indexing/algorithms.hpp b/include/boost/python/suite/indexing/algorithms.hpp index 9bf24822..fa2ddd70 100755 --- a/include/boost/python/suite/indexing/algorithms.hpp +++ b/include/boost/python/suite/indexing/algorithms.hpp @@ -53,7 +53,8 @@ namespace boost { namespace python { namespace indexing { class default_algorithms { typedef default_algorithms self_type; - typedef typename detail::maybe_override::type most_derived; + typedef typename detail::maybe_override + ::type most_derived; public: typedef ContainerTraits container_traits; @@ -93,9 +94,18 @@ namespace boost { namespace python { namespace indexing { // Default visitor_helper template - static void visitor_helper (PythonClass &, Policy const &); + static void visitor_helper (PythonClass &pyClass, Policy const &policy) + { + container_traits::visitor_helper (pyClass, policy); + } +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // MSVC6 and 7.0 seem to complain about most_derived::bounds_check + // for an instantiation of list_algorithms. + public: +#else private: +#endif static size_type bounds_check ( container &, index_param, char const *msg , bool one_past = false @@ -116,12 +126,13 @@ namespace boost { namespace python { namespace indexing { class assoc_algorithms : public default_algorithms , Ovr> ::type> { typedef assoc_algorithms self_type; - typedef typename detail::maybe_override::type most_derived; + typedef typename detail::maybe_override + ::type most_derived; typedef default_algorithms Parent; public: @@ -150,7 +161,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::size_type + BOOST_DEDUCED_TYPENAME default_algorithms::size_type default_algorithms::size (container &c) { return c.size(); @@ -161,7 +172,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::size_type + BOOST_DEDUCED_TYPENAME default_algorithms::size_type default_algorithms::bounds_check ( container &c , index_param ix @@ -218,7 +229,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::iterator + BOOST_DEDUCED_TYPENAME default_algorithms::iterator default_algorithms::find ( container &c, key_param key) { @@ -230,13 +241,13 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::size_type + BOOST_DEDUCED_TYPENAME default_algorithms::size_type default_algorithms::get_index ( container &c, key_param key) { - iterator temp (most_derived::find (c, key)); + iterator found (most_derived::find (c, key)); - if (temp == most_derived::end(c)) + if (found == most_derived::end(c)) { PyErr_SetString ( PyExc_ValueError, "get_index: element not found"); @@ -244,7 +255,8 @@ namespace boost { namespace python { namespace indexing { boost::python::throw_error_already_set (); } - return std::distance (most_derived::begin (c), temp); + iterator start (most_derived::begin (c)); + return std::distance (start, found); } ///////////////////////////////////////////////////////////////////////// @@ -252,7 +264,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::size_type + BOOST_DEDUCED_TYPENAME default_algorithms::size_type default_algorithms::count ( container &c, key_param key) { @@ -276,7 +288,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::reference + BOOST_DEDUCED_TYPENAME default_algorithms::reference default_algorithms::get ( container &c, index_param ix) { @@ -387,32 +399,19 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename default_algorithms::slice_helper + BOOST_DEDUCED_TYPENAME default_algorithms::slice_helper default_algorithms ::make_slice_helper (container &c, slice const &sl) { return slice_helper (c, integer_slice (sl, most_derived::size (c))); } - ///////////////////////////////////////////////////////////////////////// - // Visitor helper function (default version) - ///////////////////////////////////////////////////////////////////////// - - template - template - void - default_algorithms - ::visitor_helper (PythonClass &pyClass, Policy const &policy) - { - container_traits::visitor_helper (pyClass, policy); - } - ///////////////////////////////////////////////////////////////////////// // Index into a container (associative version) ///////////////////////////////////////////////////////////////////////// template - typename assoc_algorithms::reference + BOOST_DEDUCED_TYPENAME assoc_algorithms::reference assoc_algorithms::get (container &c, index_param ix) { return *most_derived::find_or_throw (c, ix); @@ -441,7 +440,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename assoc_algorithms::iterator + BOOST_DEDUCED_TYPENAME assoc_algorithms::iterator assoc_algorithms ::find (container &c, key_param key) { @@ -466,7 +465,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename assoc_algorithms::iterator + BOOST_DEDUCED_TYPENAME assoc_algorithms::iterator assoc_algorithms::find_or_throw ( container &c, index_param ix) { @@ -488,7 +487,7 @@ namespace boost { namespace python { namespace indexing { ///////////////////////////////////////////////////////////////////////// template - typename assoc_algorithms::size_type + BOOST_DEDUCED_TYPENAME assoc_algorithms::size_type assoc_algorithms::count ( container &c, key_param key) { diff --git a/include/boost/python/suite/indexing/container_proxy.hpp b/include/boost/python/suite/indexing/container_proxy.hpp index d35ee63c..4f5df942 100755 --- a/include/boost/python/suite/indexing/container_proxy.hpp +++ b/include/boost/python/suite/indexing/container_proxy.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -82,8 +83,11 @@ namespace boost { namespace python { namespace indexing { typedef typename Container::iterator raw_iterator; typedef ::boost::detail::iterator_traits raw_iterator_traits; +#if !defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template friend class shared_proxy_impl; - template friend class proxy_iterator; + template + friend class proxy_iterator; +#endif public: typedef typename Holder::held_type held_type; @@ -101,14 +105,22 @@ namespace boost { namespace python { namespace indexing { typedef const_element_proxy const_value_type; typedef const_value_type const_reference; // Ref. semantics - typedef proxy_iterator iterator; - typedef proxy_iterator const_iterator; // ?? + typedef proxy_iterator iterator; + typedef iterator const_iterator; // No const_iterator yet implemented public: // Constructors + template container_proxy (Iter start, Iter finish) + // Define inline for MSVC6 compatibility + : m_held_obj (Holder::create()) + , m_proxies () + { + insert (begin(), start, finish); + } + container_proxy (); explicit container_proxy (held_type const &h); - template container_proxy (Iter, Iter); container_proxy (container_proxy const &); container_proxy &operator= (container_proxy const &); @@ -133,7 +145,14 @@ namespace boost { namespace python { namespace indexing { iterator erase (iterator); iterator erase (iterator, iterator); iterator insert (iterator, raw_value_type const &); - template void insert (iterator, Iter, Iter); + + template void insert (iterator iter, Iter from, Iter to) + // Define here for MSVC6 compatibility + { + // Forward insertion to the right overloaded version + typedef typename BOOST_ITERATOR_CATEGORY::type category; + insert (iter, from, to, category()); + } void push_back (raw_value_type const ©) { insert (end(), copy); } @@ -163,7 +182,7 @@ namespace boost { namespace python { namespace indexing { public: // Convenient replacement of elements (automatic proxy detachment) void replace (size_type index, raw_value_type const &); - template void replace (size_type index, Iter, Iter); + // template void replace (size_type index, Iter, Iter); void swap_elements (size_type index1, size_type index2); @@ -172,20 +191,87 @@ namespace boost { namespace python { namespace indexing { private: // Overloads for insertions with/without useful std::distance template - void insert (iterator, Iter, Iter, std::forward_iterator_tag); + void insert (iterator iter, Iter from, Iter to, std::forward_iterator_tag) + // Define here for MSVC6 compatibility + { + assert (iter.ptr == this); + size_type count = std::distance (from, to); + + // Add empty proxy pointers for the new value(s) (could throw) + m_proxies.insert (m_proxies.begin() + iter.index, count, pointer_impl()); + + try + { + // Insert the new element(s) into the real container (could throw) + raw_container().insert ( + raw_container().begin() + iter.index + , from + , to); + + try + { + // Create new proxies for the new elements (could throw) + write_proxies (iter.index, iter.index + count); + } + + catch (...) + { + raw_container().erase ( + raw_container().begin() + iter.index + , raw_container().begin() + iter.index + count); + + throw; + } + } + + catch (...) + { + m_proxies.erase ( + m_proxies.begin() + iter.index + , m_proxies.begin() + iter.index + count); + + throw; + } + + // Adjust any proxies after the inserted elements (nothrow) + adjust_proxies ( + m_proxies.begin() + iter.index + count + , m_proxies.end() + , static_cast (count)); + } template - void insert (iterator, Iter, Iter, std::input_iterator_tag); + void insert (iterator iter, Iter from, Iter to, std::input_iterator_tag) + // Define here for MSVC6 compatibility + { + // insert overload for iterators where we *can't* get distance() + // so just insert elements one at a time + while (from != to) + { + iter = insert (iter, *from++) + 1; + } + } private: typedef boost::shared_ptr pointer_impl; - typedef typename Generator::template apply::type - pointer_container; +#if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + // Ignore the Generator argument, to avoid an MSVC6 fatal error + // (C1001 internal compiler error). + typedef std::vector pointer_container; +#else + typedef typename Generator::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE + apply::type pointer_container; +#endif typedef typename pointer_container::iterator pointer_iterator; - private: +#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + // Proxies need mutable access, and can't be friends with MSVC6 + public: +#endif Container &raw_container(); + private: void adjust_proxies (pointer_iterator, pointer_iterator, difference_type); void write_proxies (size_type, size_type); bool clear_proxy (pointer_impl &); // detach and do not reset @@ -214,6 +300,7 @@ namespace boost { namespace python { namespace indexing { write_proxies (0, size()); } + /* template template container_proxy @@ -223,6 +310,7 @@ namespace boost { namespace python { namespace indexing { { insert (begin(), start, finish); } + */ template container_proxy @@ -238,6 +326,8 @@ namespace boost { namespace python { namespace indexing { container_proxy ::operator= (container_proxy const ©) { + // *FIXME* - provide an exception safety guarantee + // Copy original values into any proxies being shared by external pointers clear_proxies (0, size()); @@ -282,22 +372,22 @@ namespace boost { namespace python { namespace indexing { } template - typename container_proxy::reference + BOOST_DEDUCED_TYPENAME container_proxy::reference container_proxy ::at (size_type index) { - pointer_impl const &ptr (m_proxies.BOOST_INDEXING_AT (index)); + pointer_impl const &ptr = m_proxies.BOOST_PYTHON_INDEXING_AT (index); assert (ptr->owner() == this); assert (ptr->index() == index); return reference (ptr); } template - typename container_proxy::const_reference + BOOST_DEDUCED_TYPENAME container_proxy::const_reference container_proxy ::at (size_type index) const { - pointer_impl const &ptr (m_proxies.BOOST_INDEXING_AT (index)); + pointer_impl const &ptr (m_proxies.BOOST_PYTHON_INDEXING_AT (index)); assert (ptr->owner() == this); assert (ptr->index() == index); return const_reference (ptr); @@ -309,10 +399,11 @@ namespace boost { namespace python { namespace indexing { ::replace (size_type index, raw_value_type const ©) { detach_proxy (index); - raw_container().BOOST_INDEXING_AT (index) = copy; + raw_container().BOOST_PYTHON_INDEXING_AT (index) = copy; write_proxies (index, index + 1); } + /* template template void @@ -324,14 +415,15 @@ namespace boost { namespace python { namespace indexing { replace (index++, *from++); } } + */ template void container_proxy ::swap_elements (size_type index1, size_type index2) { - pointer_impl &ptr1 (m_proxies[index1]); - pointer_impl &ptr2 (m_proxies[index2]); + pointer_impl &ptr1 = m_proxies[index1]; + pointer_impl &ptr2 = m_proxies[index2]; assert (ptr1->owner() == this); assert (ptr2->owner() == this); @@ -363,14 +455,14 @@ namespace boost { namespace python { namespace indexing { } template - typename container_proxy::iterator + BOOST_DEDUCED_TYPENAME container_proxy::iterator container_proxy::erase (iterator iter) { return erase (iter, iter + 1); } template - typename container_proxy::iterator + BOOST_DEDUCED_TYPENAME container_proxy::iterator container_proxy::erase ( iterator from, iterator to) { @@ -389,6 +481,7 @@ namespace boost { namespace python { namespace indexing { return iterator (this, result); } + /* template template void container_proxy::insert ( @@ -440,18 +533,6 @@ namespace boost { namespace python { namespace indexing { , static_cast (count)); } - template - typename container_proxy::iterator - container_proxy::insert ( - iterator iter, raw_value_type const ©) - { - // Use the iterator-based version by treating the value as an - // array of size one (see section 5.7/4 of the C++98 standard) - insert (iter, ©, (©) + 1, std::random_access_iterator_tag()); - - return iter; - } - template template void container_proxy::insert ( @@ -474,6 +555,19 @@ namespace boost { namespace python { namespace indexing { typedef typename BOOST_ITERATOR_CATEGORY::type category; insert (iter, from, to, category()); } + */ + + template + BOOST_DEDUCED_TYPENAME container_proxy::iterator + container_proxy::insert ( + iterator iter, raw_value_type const ©) + { + // Use the iterator-based version by treating the value as an + // array of size one (see section 5.7/4 of the C++98 standard) + insert (iter, ©, (©) + 1, std::random_access_iterator_tag()); + + return iter; + } template bool container_proxy::clear_proxy ( @@ -514,7 +608,7 @@ namespace boost { namespace python { namespace indexing { void container_proxy ::detach_proxy (size_type index) { - pointer_impl &ptr (m_proxies[index]); + pointer_impl &ptr = m_proxies[index]; assert (ptr->index() == index); @@ -608,7 +702,7 @@ namespace boost { namespace python { namespace indexing { while (from != to) { - pointer_impl &ptr (m_proxies[from]); + pointer_impl &ptr = m_proxies[from]; if ((ptr.get() == 0) || (!ptr.unique())) { @@ -635,7 +729,7 @@ namespace boost { namespace python { namespace indexing { for (size_type count = 0; ok && (count < size()); ++count) { - pointer_impl const &ptr (m_proxies[count]); + pointer_impl const &ptr = m_proxies[count]; ok = ptr.get() && (ptr->owner() == this) && (ptr->index() == count) && !ptr->m_element_ptr.get(); @@ -654,19 +748,33 @@ namespace boost { namespace python { namespace indexing { typedef Container container; typedef typename container::raw_value_type value_type; // insert, ... typedef typename container::raw_value_type key_type; // find, count, ... - typedef typename container::reference reference; // return values + typedef typename container::reference reference; // return values - typedef typename boost::call_traits::param_type value_param; - typedef typename boost::call_traits::param_type key_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + value_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + key_param; +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) typedef value_traits value_traits_; +#else + typedef element_proxy_traits value_traits_; + + // Forward visitor_helper to eleemnt_proxy_traits + template + static void visitor_helper (PythonClass &pyClass, Policy const &policy) + { + value_traits_::visitor_helper (pyClass, policy); + } +#endif // Get value_traits for the reference type (i.e. element_proxy) // to get the custom visitor_helper }; +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// - // algo_selector support for std::list instances + // algo_selector support for container_proxy instances /////////////////////////////////////////////////////////////////////// template @@ -682,6 +790,13 @@ namespace boost { namespace python { namespace indexing { typedef default_algorithms const_algorithms; }; } +#endif + template > + struct container_proxy_suite + : container_suite > + { + }; + } } } #endif // BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP diff --git a/include/boost/python/suite/indexing/container_suite.hpp b/include/boost/python/suite/indexing/container_suite.hpp index 20448259..b3f93b70 100755 --- a/include/boost/python/suite/indexing/container_suite.hpp +++ b/include/boost/python/suite/indexing/container_suite.hpp @@ -29,7 +29,11 @@ namespace boost { namespace python { namespace indexing { typedef boost::python::return_value_policy default_container_policies; - template > + template < + class Container + , class Algorithms + = algo_selector + > struct container_suite : public visitor { diff --git a/include/boost/python/suite/indexing/container_traits.hpp b/include/boost/python/suite/indexing/container_traits.hpp index d6234acd..d2254a48 100755 --- a/include/boost/python/suite/indexing/container_traits.hpp +++ b/include/boost/python/suite/indexing/container_traits.hpp @@ -28,8 +28,25 @@ #include #include #include +#include + +#define ICE_AND(a, b) type_traits::ice_and<(a), (b)>::value namespace boost { namespace python { namespace indexing { +#if BOOST_WORKAROUND (BOOST_MSVC, <= 1200) + // MSVC6 has problems with get_signature if parameter types have + // top-level const qualification (e.g. int const). Unfortunately, + // this is exactly what happens with boost::call_traits, so we + // substitute a really dumb version of it instead. + + template struct broken_call_traits { + typedef T const & param_type; + }; +# define BOOST_PYTHON_INDEXING_CALL_TRAITS broken_call_traits +#else +# define BOOST_PYTHON_INDEXING_CALL_TRAITS ::boost::call_traits +#endif + ///////////////////////////////////////////////////////////////////////// // Lowest common denominator traits - applicable to real containers // and iterator pairs @@ -38,19 +55,19 @@ namespace boost { namespace python { namespace indexing { template struct base_container_traits : public ::boost::python::indexing::iterator_traits < - typename mpl::if_ < + BOOST_DEDUCED_TYPENAME mpl::if_ < is_const - , typename Container::const_iterator - , typename Container::iterator + , BOOST_DEDUCED_TYPENAME Container::const_iterator + , BOOST_DEDUCED_TYPENAME Container::iterator >::type > { protected: typedef ::boost::python::indexing::iterator_traits < - typename mpl::if_ < + BOOST_DEDUCED_TYPENAME mpl::if_ < is_const - , typename Container::const_iterator - , typename Container::iterator + , BOOST_DEDUCED_TYPENAME Container::const_iterator + , BOOST_DEDUCED_TYPENAME Container::iterator >::type > base_type; @@ -61,20 +78,23 @@ namespace boost { namespace python { namespace indexing { typedef Container container; typedef typename container::size_type size_type; - typedef typename base_type::value_type value_type; // insert, etc. - typedef typename base_type::value_type key_type; // find, count, ... + typedef typename base_type::value_type value_type; // insert + typedef typename base_type::value_type key_type; // find typedef typename make_signed::type index_type; // at(), operator[]. Signed to support Python -ve indexes - typedef typename boost::call_traits::param_type value_param; - typedef typename boost::call_traits::param_type key_param; - typedef typename boost::call_traits::param_type index_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + value_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + key_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + index_param; typedef value_traits value_traits_; BOOST_STATIC_CONSTANT (bool, has_mutable_ref - = base_type::has_mutable_ref && is_mutable); + = ICE_AND (base_type::has_mutable_ref, is_mutable)); BOOST_STATIC_CONSTANT (bool, has_find = value_traits_::equality_comparable); @@ -87,7 +107,10 @@ namespace boost { namespace python { namespace indexing { // Forward visitor_helper to value_traits_ template - static void visitor_helper (PythonClass &, Policy const &); + static void visitor_helper (PythonClass &pyClass, Policy const &policy) + { + value_traits_::visitor_helper (pyClass, policy); + } }; ///////////////////////////////////////////////////////////////////////// @@ -117,17 +140,4 @@ namespace boost { namespace python { namespace indexing { } } } -///////////////////////////////////////////////////////////////////////// -// Visitor helper function (foward to value_traits_ version) -///////////////////////////////////////////////////////////////////////// - -template -template -void -boost::python::indexing::base_container_traits -::visitor_helper (PythonClass &pyClass, Policy const &policy) -{ - value_traits_::visitor_helper (pyClass, policy); -} - #endif // BOOST_PYTHON_INDEXING_CONTAINER_SUITE_HPP diff --git a/include/boost/python/suite/indexing/deque.hpp b/include/boost/python/suite/indexing/deque.hpp index c1d86f7c..ee58abde 100755 --- a/include/boost/python/suite/indexing/deque.hpp +++ b/include/boost/python/suite/indexing/deque.hpp @@ -19,11 +19,13 @@ #define BOOST_PYTHON_INDEXING_DEQUE_HPP #include +#include #include #include #include namespace boost { namespace python { namespace indexing { +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for std::deque instances @@ -42,6 +44,12 @@ namespace boost { namespace python { namespace indexing { typedef default_algorithms const_algorithms; }; } +#endif + + template > + struct deque_suite : container_suite > + { + }; } } } diff --git a/include/boost/python/suite/indexing/element_proxy.hpp b/include/boost/python/suite/indexing/element_proxy.hpp index 0eaac8ac..97aa0fd4 100755 --- a/include/boost/python/suite/indexing/element_proxy.hpp +++ b/include/boost/python/suite/indexing/element_proxy.hpp @@ -1,4 +1,3 @@ -// // Header file element_proxy.hpp // // Proxy objects for invidivual elements in a container wrapped by @@ -28,13 +27,17 @@ namespace boost { namespace python { namespace indexing { template class element_proxy { +#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + public: +#else template friend struct const_element_proxy; +#endif - typedef ContainerProxy container_proxy; - typedef typename container_proxy::shared_proxy proxy_type; + typedef ContainerProxy container_proxy_; + typedef typename container_proxy_::shared_proxy proxy_type; typedef boost::shared_ptr proxy_pointer; - typedef typename container_proxy::raw_value_type raw_value_type; - typedef typename container_proxy::size_type size_type; + typedef typename container_proxy_::raw_value_type raw_value_type; + typedef typename container_proxy_::size_type size_type; proxy_pointer m_ptr; @@ -76,8 +79,8 @@ namespace boost { namespace python { namespace indexing { element_proxy &operator= (value_type const ©) { - proxy_type &proxy (*m_ptr); - container_proxy *container = proxy.owner(); + proxy_type &proxy = *m_ptr; + container_proxy_ *container = proxy.owner(); size_type index = proxy.index(); if (container) @@ -117,10 +120,10 @@ namespace boost { namespace python { namespace indexing { template struct const_element_proxy { - typedef ContainerProxy container_proxy; - typedef typename container_proxy::shared_proxy proxy_type; + typedef ContainerProxy container_proxy_; + typedef typename container_proxy_::shared_proxy proxy_type; typedef boost::shared_ptr proxy_pointer; - typedef typename container_proxy::raw_value_type raw_value_type; + typedef typename container_proxy_::raw_value_type raw_value_type; proxy_pointer m_ptr; @@ -135,7 +138,7 @@ namespace boost { namespace python { namespace indexing { explicit const_element_proxy (proxy_type *ptr) : m_ptr (ptr) { } const_element_proxy (proxy_pointer const &ptr) : m_ptr (ptr) { } - const_element_proxy (element_proxy const ©) + const_element_proxy (element_proxy const ©) : m_ptr (copy.m_ptr) { } diff --git a/include/boost/python/suite/indexing/element_proxy_traits.hpp b/include/boost/python/suite/indexing/element_proxy_traits.hpp index a45d8a3a..c0aee1d4 100755 --- a/include/boost/python/suite/indexing/element_proxy_traits.hpp +++ b/include/boost/python/suite/indexing/element_proxy_traits.hpp @@ -23,9 +23,17 @@ #include namespace boost { namespace python { namespace indexing { +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct value_traits > - : public value_traits + : public value_traits < + BOOST_DEDUCED_TYPENAME ContainerProxy::raw_value_type> +#else + template + struct element_proxy_traits + : public value_traits < + BOOST_DEDUCED_TYPENAME ContainerProxy::raw_value_type> +#endif { template static void visitor_helper (PythonClass &, Policy const &) diff --git a/include/boost/python/suite/indexing/int_slice_helper.hpp b/include/boost/python/suite/indexing/int_slice_helper.hpp index 37c8a24d..5eeafb59 100755 --- a/include/boost/python/suite/indexing/int_slice_helper.hpp +++ b/include/boost/python/suite/indexing/int_slice_helper.hpp @@ -18,7 +18,8 @@ #ifndef BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP #define BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP -#include +# include +# include namespace boost { namespace python { namespace indexing { template @@ -117,6 +118,13 @@ namespace boost { namespace python { namespace indexing { template struct maybe_insert { template static void apply ( +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + // Can't explicitly instantiate member function - must let + // the compiler deduce the argument type from a dummy + // parameter. Same applies throughout + Algorithms *, +# endif typename Algorithms::container & , typename Algorithms::index_param , typename Algorithms::value_param) @@ -132,6 +140,10 @@ namespace boost { namespace python { namespace indexing { template<> struct maybe_insert { template static void apply ( +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + Algorithms *, +# endif typename Algorithms::container &c , typename Algorithms::index_param i , typename Algorithms::value_param v) @@ -155,7 +167,14 @@ namespace boost { namespace python { namespace indexing { else { detail::maybe_insert - ::template apply (*m_ptr, m_pos, val); + ::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE apply +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + (static_cast(0), +# else + ( +# endif + *m_ptr, m_pos, val); ++m_pos; // Advance for any subsequent inserts } @@ -165,6 +184,10 @@ namespace boost { namespace python { namespace indexing { template struct maybe_erase { template static void apply ( +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + Algorithms *, +# endif typename Algorithms::container & , typename Algorithms::index_param , typename Algorithms::index_param) @@ -179,6 +202,10 @@ namespace boost { namespace python { namespace indexing { template<> struct maybe_erase { template static void apply ( +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + Algorithms *, +# endif typename Algorithms::container &c , typename Algorithms::index_param from , typename Algorithms::index_param to) @@ -202,9 +229,17 @@ namespace boost { namespace python { namespace indexing { else { detail::maybe_erase - ::template apply (*m_ptr, m_pos, m_slice.stop()); + ::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE apply +# if defined (BOOST_NO_MEMBER_TEMPLATES) \ + && defined (BOOST_MSVC6_MEMBER_TEMPLATES) + (static_cast(0), +# else + ( +# endif + *m_ptr, m_pos, m_slice.stop()); } } + } } } #endif // BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP diff --git a/include/boost/python/suite/indexing/iterator_range.hpp b/include/boost/python/suite/indexing/iterator_range.hpp index 982d5934..bfb1b23b 100755 --- a/include/boost/python/suite/indexing/iterator_range.hpp +++ b/include/boost/python/suite/indexing/iterator_range.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,9 @@ namespace boost { namespace python { namespace indexing { class iterator_range { private: - typedef typename boost::call_traits::param_type iterator_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + iterator_param; + typedef ::boost::detail::iterator_traits std_traits; public: @@ -73,12 +76,26 @@ namespace boost { namespace python { namespace indexing { iterator m_end; }; - // Array support functions - template T *begin (T (&array)[N]); - template T *end (T (&array)[N]); + // Array support function(s). + template iterator_range make_iterator_range (T *, T*); + +#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1200) template iterator_range make_iterator_range ( T (&array)[N]); + template T *begin (T (&array)[N]); + template T *end (T (&array)[N]); + +# define BOOST_MAKE_ITERATOR_RANGE \ + ::boost::python::indexing::make_iterator_range + +#else + // For compilers that can't deduce template argument array bounds +# define BOOST_MAKE_ITERATOR_RANGE(array) \ + ::boost::python::indexing::make_iterator_range ( \ + (array), ((array) + sizeof(array) / sizeof((array)[0]))) +#endif + template iterator_range::iterator_range ( iterator_param begin, iterator_param end) @@ -141,6 +158,12 @@ namespace boost { namespace python { namespace indexing { } } + template iterator_range make_iterator_range (T *p1, T* p2) + { + return iterator_range (p1, p2); + } + +#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1200) template T *begin (T (&array)[N]) { return array; @@ -155,7 +178,9 @@ namespace boost { namespace python { namespace indexing { iterator_range make_iterator_range (T (&array)[N]) { return iterator_range(begin (array), end (array)); } +#endif +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for iterator_range instances @@ -174,6 +199,13 @@ namespace boost { namespace python { namespace indexing { typedef default_algorithms const_algorithms; }; } +#endif + + template > + struct iterator_range_suite + : container_suite > + { + }; } } } diff --git a/include/boost/python/suite/indexing/iterator_traits.hpp b/include/boost/python/suite/indexing/iterator_traits.hpp index f63d726c..466d4deb 100755 --- a/include/boost/python/suite/indexing/iterator_traits.hpp +++ b/include/boost/python/suite/indexing/iterator_traits.hpp @@ -23,6 +23,7 @@ #define BOOST_PYTHON_INDEXING_ITERATOR_TRAITS_HPP #include +#include #include #include @@ -77,7 +78,14 @@ namespace boost { namespace python { namespace indexing { }; namespace iterator_detail { - template struct traits_by_category { }; + template struct traits_by_category { +# if defined(BOOST_MPL_MSVC_60_ETI_BUG) + // MSVC6 needs compilable traits in the unspecialized traits_by_category + template struct traits { + typedef traits type; + }; +# endif + }; template<> struct traits_by_category { @@ -113,7 +121,7 @@ namespace boost { namespace python { namespace indexing { template class deduced_traits { - typedef BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY< + typedef BOOST_DEDUCED_TYPENAME ::boost::BOOST_ITERATOR_CATEGORY< Iterator>::type category; typedef BOOST_DEDUCED_TYPENAME ::boost::detail::std_category < @@ -121,7 +129,7 @@ namespace boost { namespace python { namespace indexing { public: typedef typename traits_by_category - ::template traits::type type; + ::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE traits::type type; }; } diff --git a/include/boost/python/suite/indexing/list.hpp b/include/boost/python/suite/indexing/list.hpp index 71f0eaad..eb7712ac 100755 --- a/include/boost/python/suite/indexing/list.hpp +++ b/include/boost/python/suite/indexing/list.hpp @@ -19,6 +19,7 @@ #define BOOST_PYTHON_INDEXING_LIST_HPP #include +#include #include #include #include @@ -49,6 +50,7 @@ namespace boost { namespace python { namespace indexing { // static void sort (container &, PyObject *); }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for std::list instances @@ -67,6 +69,12 @@ namespace boost { namespace python { namespace indexing { typedef list_algorithms const_algorithms; }; } +#endif + + template > + struct list_suite : container_suite > + { + }; ///////////////////////////////////////////////////////////////////////// // Reverse the contents of a list (using member function) diff --git a/include/boost/python/suite/indexing/map.hpp b/include/boost/python/suite/indexing/map.hpp index 83ee82fb..e2b306a0 100755 --- a/include/boost/python/suite/indexing/map.hpp +++ b/include/boost/python/suite/indexing/map.hpp @@ -19,8 +19,11 @@ #define BOOST_PYTHON_INDEXING_MAP_HPP #include +#include #include #include +#include +#include #include namespace boost { namespace python { namespace indexing { @@ -31,14 +34,22 @@ namespace boost { namespace python { namespace indexing { template struct map_traits : public default_container_traits { +# if BOOST_WORKAROUND (BOOST_MSVC, <= 1200) + // MSVC6 has a nonstandard name for mapped_type in std::map + typedef typename Container::referent_type value_type; +# else typedef typename Container::mapped_type value_type; +# endif typedef value_type & reference; typedef typename Container::key_type index_type; // operator[] typedef typename Container::key_type key_type; // find, count, ... - typedef typename boost::call_traits::param_type value_param; - typedef typename boost::call_traits::param_type key_param; - typedef typename boost::call_traits::param_type index_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + value_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + key_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + index_param; BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); BOOST_STATIC_CONSTANT (bool, has_find = true); @@ -77,6 +88,7 @@ namespace boost { namespace python { namespace indexing { static void insert (container &, index_param, value_param); }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for std::map instances @@ -112,13 +124,19 @@ namespace boost { namespace python { namespace indexing { typedef map_algorithms const_algorithms; }; } +#endif + + template > + struct map_suite : container_suite > + { + }; ///////////////////////////////////////////////////////////////////////// // Index into a container (map version) ///////////////////////////////////////////////////////////////////////// template - typename map_algorithms::reference + BOOST_DEDUCED_TYPENAME map_algorithms::reference map_algorithms::get (container &c, index_param ix) { return most_derived::find_or_throw (c, ix)->second; @@ -147,8 +165,8 @@ namespace boost { namespace python { namespace indexing { container &c, index_param ix, value_param val) { typedef std::pair - + pair_type; // Can't use std::make_pair, because param types may be references diff --git a/include/boost/python/suite/indexing/proxy_iterator.hpp b/include/boost/python/suite/indexing/proxy_iterator.hpp index 16e5c4ab..e6bc5af9 100755 --- a/include/boost/python/suite/indexing/proxy_iterator.hpp +++ b/include/boost/python/suite/indexing/proxy_iterator.hpp @@ -18,23 +18,46 @@ #define BOOST_PYTHON_INDEXING_PROXY_ITERATOR_HPP #include +#include +#include +#include namespace boost { namespace python { namespace indexing { - template + + template class proxy_iterator + : public boost::iterator < + std::random_access_iterator_tag + , ElementProxy + , typename Traits::difference_type + , ElementProxy * + , ElementProxy // Already has reference semantics + > { +#if !defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template friend class container_proxy; +#endif + + typedef boost::iterator < + std::random_access_iterator_tag + , ElementProxy + , typename Traits::difference_type + , ElementProxy * + , ElementProxy + > base_type; public: typedef ContainerProxy container_proxy_; - typedef typename container_proxy_::raw_iterator_traits raw_iterator_traits; - typedef typename raw_iterator_traits::difference_type difference_type; - typedef typename container_proxy_::size_type size_type; - typedef typename container_proxy_::value_type value_type; - typedef typename container_proxy_::raw_iterator raw_iterator; + + typedef Iter raw_iterator; + typedef Traits raw_iterator_traits; + typedef Size size_type; + typedef typename base_type::value_type value_type; + typedef typename base_type::difference_type difference_type; + typedef value_type *pointer; - typedef value_type reference; // Already has reference semantics - typedef std::random_access_iterator_tag iterator_category; + typedef value_type reference; // Already has reference semantics proxy_iterator (container_proxy_ *p, size_type i) : ptr (p), index (i) { } @@ -90,10 +113,18 @@ namespace boost { namespace python { namespace indexing { return index < other.index; } + bool operator<= (proxy_iterator const &other) const { + return index <= other.index; + } + bool operator> (proxy_iterator const &other) const { return index > other.index; } + bool operator>= (proxy_iterator const &other) const { + return index >= other.index; + } + void iter_swap (proxy_iterator const &other) const { ptr->swap_elements (index, other.index); } @@ -102,20 +133,28 @@ namespace boost { namespace python { namespace indexing { // Extensions to the normal iterator interface // void replace (value_type const ©) { ptr->replace (index, copy); } +#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + // Can't declare container_proxy as friend, so make data public + public: +#else private: +#endif container_proxy_ *ptr; size_type index; }; } } } +#if !BOOST_WORKAROUND (BOOST_MSVC, == 1300) +// MSVC7.0 can't decide between this and the unspecialized version namespace std { - template + template void iter_swap ( - boost::python::indexing::proxy_iterator const &first - , boost::python::indexing::proxy_iterator const &second) + boost::python::indexing::proxy_iterator const &first + , boost::python::indexing::proxy_iterator const &second) { first.iter_swap (second); } } +#endif #endif // BOOST_PYTHON_INDEXING_PROXY_ITERATOR_HPP diff --git a/include/boost/python/suite/indexing/set.hpp b/include/boost/python/suite/indexing/set.hpp index 270efa83..0dd2bd8b 100755 --- a/include/boost/python/suite/indexing/set.hpp +++ b/include/boost/python/suite/indexing/set.hpp @@ -19,6 +19,7 @@ #define BOOST_PYTHON_INDEXING_SET_HPP #include +#include #include #include #include @@ -35,9 +36,12 @@ namespace boost { namespace python { namespace indexing { typedef typename Container::key_type index_type; // operator[] typedef typename Container::key_type key_type; // find, count, ... - typedef typename boost::call_traits::param_type value_param; - typedef typename boost::call_traits::param_type key_param; - typedef typename boost::call_traits::param_type index_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + value_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + key_param; + typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS ::param_type + index_param; BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); BOOST_STATIC_CONSTANT (bool, has_find = true); @@ -72,6 +76,7 @@ namespace boost { namespace python { namespace indexing { static void insert (container &, index_param); }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for std::set instances @@ -107,6 +112,12 @@ namespace boost { namespace python { namespace indexing { typedef set_algorithms const_algorithms; }; } +#endif + + template > + struct set_suite : container_suite > + { + }; ///////////////////////////////////////////////////////////////////////// // Insert an element into a set diff --git a/include/boost/python/suite/indexing/shared_proxy_impl.hpp b/include/boost/python/suite/indexing/shared_proxy_impl.hpp index c57889c7..ef8a23e1 100755 --- a/include/boost/python/suite/indexing/shared_proxy_impl.hpp +++ b/include/boost/python/suite/indexing/shared_proxy_impl.hpp @@ -46,13 +46,16 @@ namespace boost { namespace python { namespace indexing { shared_proxy_impl (value_type const ©); // Creates value-only (detached) proxy +#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + public: +#else private: template friend class container_proxy; +#endif shared_proxy_impl (ContainerProxy *, size_t); void detach (); - private: ContainerProxy *m_owner_ptr; // When attached size_t m_index; // When attached std::auto_ptr m_element_ptr; // When detached @@ -85,14 +88,15 @@ namespace boost { namespace python { namespace indexing { shared_proxy_impl::operator* () const { return m_owner_ptr - ? m_owner_ptr->raw_container().BOOST_INDEXING_AT (m_index) + ? m_owner_ptr->raw_container().BOOST_PYTHON_INDEXING_AT (m_index) : *m_element_ptr; } template void shared_proxy_impl::detach () { - m_element_ptr.reset (new value_type (**this)); + BOOST_PYTHON_INDEXING_RESET_AUTO_PTR ( + m_element_ptr, new value_type (**this)); m_owner_ptr = 0; m_index = static_cast(-1); } diff --git a/include/boost/python/suite/indexing/slice.hpp b/include/boost/python/suite/indexing/slice.hpp index 469551cf..8bbda407 100755 --- a/include/boost/python/suite/indexing/slice.hpp +++ b/include/boost/python/suite/indexing/slice.hpp @@ -1,5 +1,3 @@ -// -*- mode:c++ -*- -// // Header file slice.hpp // // Copyright (c) 2003 Raoul M. Gough @@ -29,9 +27,20 @@ namespace boost { namespace python { namespace indexing { // so that it is possible to register a special converter for // PySlice_Type and overload C++ functions on slice - slice (slice const &); - +#if defined (BOOST_NO_MEMBER_TEMPLATES) + // MSVC6 doesn't seem to be able to invoke the templated + // constructor, so provide explicit overloads to match the + // (currently) known boost::python::object constructors + explicit slice (::boost::python::handle<> const&); + explicit slice (::boost::python::detail::borrowed_reference); + explicit slice (::boost::python::detail::new_reference); + explicit slice (::boost::python::detail::new_non_null_reference); +#else + // Better compilers make life easier template inline slice (T const &ref); +#endif + + slice (slice const &); // Copy constructor }; struct BOOST_PYTHON_DECL integer_slice @@ -62,6 +71,7 @@ namespace boost { namespace python { namespace indexing { }; } } } +#if !defined (BOOST_NO_MEMBER_TEMPLATES) template boost::python::indexing::slice::slice (T const &ref) : boost::python::object (ref) @@ -74,6 +84,7 @@ boost::python::indexing::slice::slice (T const &ref) boost::python::throw_error_already_set(); } } +#endif namespace boost { namespace python { namespace converter { // Specialized converter to handle PySlice_Type objects diff --git a/include/boost/python/suite/indexing/slice_handler.hpp b/include/boost/python/suite/indexing/slice_handler.hpp index 5a9d4721..ed950996 100755 --- a/include/boost/python/suite/indexing/slice_handler.hpp +++ b/include/boost/python/suite/indexing/slice_handler.hpp @@ -18,6 +18,7 @@ #ifndef BOOST_PYTHON_INDEXING_SLICE_HANDLER_HPP #define BOOST_PYTHON_INDEXING_SLICE_HANDLER_HPP +#include #include #include #include @@ -46,10 +47,13 @@ namespace boost { namespace python { namespace indexing { static void set_slice (container &, slice, boost::python::object); static void del_slice (container &, slice); static void extend (container &, boost::python::object); + }; + namespace detail { + template struct postcall_override { - // This class overrides our Policy's postcall function and + // This class overrides the Policy's postcall function and // result_conveter to handle the list returned from get_slice. // The Policy's result_converter is removed, since it gets // applied within get_slice. Our postcall override applies the @@ -57,7 +61,7 @@ namespace boost { namespace python { namespace indexing { // from get_slice. typedef boost::python::default_result_converter result_converter; - typedef typename Policy::argument_package argument_package; // ? + typedef typename Policy::argument_package argument_package; postcall_override (Policy const &p); @@ -67,48 +71,6 @@ namespace boost { namespace python { namespace indexing { private: Policy m_base; }; - }; - - ////////////////////////////////////////////////////////////////////////// - // postcall_override constructor - ////////////////////////////////////////////////////////////////////////// - - template - slice_handler - ::postcall_override::postcall_override (Policy const &p) - : m_base (p) - { - } - - ////////////////////////////////////////////////////////////////////////// - // precall forwarder - ////////////////////////////////////////////////////////////////////////// - - template - bool - slice_handler - ::postcall_override::precall (PyObject *args) - { - return m_base.precall (args); - } - - ////////////////////////////////////////////////////////////////////////// - // Apply base postcall to each element of the list returend by get_slice - ////////////////////////////////////////////////////////////////////////// - - template - PyObject * - slice_handler - ::postcall_override::postcall (PyObject *args, PyObject *result) - { - int size = PyList_Size (result); - - for (int count = 0; count < size; ++count) - { - m_base.postcall (args, PyList_GetItem (result, count)); - } - - return result; } ////////////////////////////////////////////////////////////////////////// @@ -121,7 +83,8 @@ namespace boost { namespace python { namespace indexing { ::make_getitem (Policy const &policy) { return - boost::python::make_function (get_slice, postcall_override (policy)); + boost::python::make_function ( + get_slice, detail::postcall_override (policy)); } ////////////////////////////////////////////////////////////////////////// @@ -163,6 +126,46 @@ namespace boost { namespace python { namespace indexing { return boost::python::make_function (extend, policy); } + namespace detail { + //////////////////////////////////////////////////////////////////////// + // postcall_override constructor + //////////////////////////////////////////////////////////////////////// + + template + postcall_override::postcall_override (Policy const &p) + : m_base (p) + { + } + + //////////////////////////////////////////////////////////////////////// + // precall forwarder + //////////////////////////////////////////////////////////////////////// + + template + bool postcall_override::precall (PyObject *args) + { + return m_base.precall (args); + } + + //////////////////////////////////////////////////////////////////////// + // Apply base postcall to each element of the list returend by get_slice + //////////////////////////////////////////////////////////////////////// + + template + PyObject * + postcall_override::postcall (PyObject *args, PyObject *result) + { + int size = PyList_Size (result); + + for (int count = 0; count < size; ++count) + { + m_base.postcall (args, PyList_GetItem (result, count)); + } + + return result; + } + } // namespace detail + ////////////////////////////////////////////////////////////////////////// // Implementation for the slice version of __getitem__ ////////////////////////////////////////////////////////////////////////// @@ -174,7 +177,9 @@ namespace boost { namespace python { namespace indexing { { typedef typename Policy::result_converter converter_type; typedef typename Algorithms::reference reference; - typename boost::mpl::apply1::type converter; + + typename boost::mpl::apply1::type + converter; boost::python::list result; @@ -214,11 +219,11 @@ namespace boost { namespace python { namespace indexing { // a reference to existing object, if possible and sensible) and the // second allowing implicit conversions. - typedef boost::python::extract - extractor1; + typedef boost::python::extract < + BOOST_DEDUCED_TYPENAME Algorithms::value_param> extractor1; - typedef boost::python::extract - extractor2; + typedef boost::python::extract < + BOOST_DEDUCED_TYPENAME Algorithms::value_type> extractor2; // Note: any error during this operation will probably leave the // container partially updated. This can occur (for example) if the diff --git a/include/boost/python/suite/indexing/suite_utils.hpp b/include/boost/python/suite/indexing/suite_utils.hpp index 47303678..267a94d6 100755 --- a/include/boost/python/suite/indexing/suite_utils.hpp +++ b/include/boost/python/suite/indexing/suite_utils.hpp @@ -45,7 +45,7 @@ namespace boost { namespace python { namespace indexing { typedef typename boost::remove_reference::type maybe_const; public: - static bool const value = ! boost::is_const::value; + BOOST_STATIC_CONSTANT (bool, value = !boost::is_const::value); }; // make_signed attempts to identify the signed version of any diff --git a/include/boost/python/suite/indexing/value_traits.hpp b/include/boost/python/suite/indexing/value_traits.hpp index d8522e35..045b1b66 100755 --- a/include/boost/python/suite/indexing/value_traits.hpp +++ b/include/boost/python/suite/indexing/value_traits.hpp @@ -21,13 +21,15 @@ #ifndef BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP #define BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP +#include + namespace boost { namespace python { namespace indexing { template struct value_traits { - static bool const equality_comparable = true; + BOOST_STATIC_CONSTANT (bool, equality_comparable = true); // Meaning from C++98 standard section 20.1.1 - static bool const lessthan_comparable = true; + BOOST_STATIC_CONSTANT (bool, lessthan_comparable = true); // static bool const has_less = true; // etc... diff --git a/include/boost/python/suite/indexing/vector.hpp b/include/boost/python/suite/indexing/vector.hpp index 5f933c39..684f81d0 100755 --- a/include/boost/python/suite/indexing/vector.hpp +++ b/include/boost/python/suite/indexing/vector.hpp @@ -19,11 +19,13 @@ #define BOOST_PYTHON_INDEXING_VECTOR_HPP #include +#include #include #include #include namespace boost { namespace python { namespace indexing { +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { /////////////////////////////////////////////////////////////////////// // algo_selector support for std::vector instances @@ -42,6 +44,12 @@ namespace boost { namespace python { namespace indexing { typedef default_algorithms const_algorithms; }; } +#endif + + template > + struct vector_suite : container_suite > + { + }; } } } diff --git a/include/boost/python/suite/indexing/visitor.hpp b/include/boost/python/suite/indexing/visitor.hpp index 0b00ba6a..578c952f 100755 --- a/include/boost/python/suite/indexing/visitor.hpp +++ b/include/boost/python/suite/indexing/visitor.hpp @@ -1,5 +1,3 @@ -// -*- mode:c++ -*- -// // Header file visitor.hpp // // Copyright (c) 2003 Raoul M. Gough @@ -23,6 +21,7 @@ #include #include +#include #include #include #include @@ -228,11 +227,12 @@ namespace boost { namespace python { namespace indexing { static void apply ( PythonClass &pyClass , Algorithms const & - , Policy const &policy) + , Policy const &) { - // *FIXME* seperate precall and postcall portions of the + // Should maybe separate precall and postcall portions of the // policy (precall when generating the range object, postcall - // when returing from range.next()) + // when returing from range.next())? + pyClass.def ( "__iter__" , boost::python::range ( diff --git a/include/boost/python/suite/indexing/workaround.hpp b/include/boost/python/suite/indexing/workaround.hpp index fea2cd5a..045bc7a8 100755 --- a/include/boost/python/suite/indexing/workaround.hpp +++ b/include/boost/python/suite/indexing/workaround.hpp @@ -1,5 +1,3 @@ -// -*- mode:c++ -*- -// // Header file workaround.hpp // // Indexing-specific workarounds for compiler problems. @@ -20,14 +18,35 @@ #ifndef BOOST_PYTHON_INDEXING_WORKAROUND_HPP #define BOOST_PYTHON_INDEXING_WORKAROUND_HPP +#include #include # if (BOOST_WORKAROUND (__GNUC__, < 3)) # // gcc versions before 3 (like 2.95.3) don't have the "at" member # // function in std::vector or std::deque -# define BOOST_INDEXING_AT operator[] +# define BOOST_PYTHON_INDEXING_AT operator[] # else -# define BOOST_INDEXING_AT at +# define BOOST_PYTHON_INDEXING_AT at +# endif + +# if BOOST_WORKAROUND (BOOST_MSVC, <= 1300) +// visualc.hpp never seems to define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +// so BOOST_NESTED_TEMPLATE ends up expanding to "template" instead of +// being empty. This causes some compile errors with MSVC[67] +# define BOOST_PYTHON_INDEXING_NESTED_TEMPLATE + +// Workaround the lack of a reset member function in std::auto_ptr +namespace boost { namespace python { namespace indexing { +template void reset_auto_ptr (T &aptr, T::element_type *pptr) { + aptr = T (pptr); +} +} } } +# define BOOST_PYTHON_INDEXING_RESET_AUTO_PTR \ + ::boost::python::indexing::reset_auto_ptr +# else +# define BOOST_PYTHON_INDEXING_NESTED_TEMPLATE BOOST_NESTED_TEMPLATE +# define BOOST_PYTHON_INDEXING_RESET_AUTO_PTR( aptr, pptr ) \ + (aptr).reset(pptr) # endif #endif // BOOST_PYTHON_INDEXING_WORKAROUND_HPP diff --git a/src/indexing/python_iterator.cpp b/src/indexing/python_iterator.cpp index 9bedf0db..1d7c6969 100755 --- a/src/indexing/python_iterator.cpp +++ b/src/indexing/python_iterator.cpp @@ -16,6 +16,7 @@ // #include +#include //////////////////////////////////////////////////////////////////////////// // python_iterator factory @@ -24,11 +25,13 @@ std::auto_ptr boost::python::indexing::make_iterator (boost::python::object temp) { - std::auto_ptr result; + typedef std::auto_ptr ptr_type; + ptr_type result; try { - result.reset (new python_iter_iterator (temp)); + BOOST_PYTHON_INDEXING_RESET_AUTO_PTR ( + result, (python_iterator *) new python_iter_iterator (temp)); } catch (boost::python::error_already_set const &) @@ -37,7 +40,8 @@ boost::python::indexing::make_iterator (boost::python::object temp) try { - result.reset (new python_getitem_iterator (temp)); + BOOST_PYTHON_INDEXING_RESET_AUTO_PTR ( + result, (python_iterator *) new python_getitem_iterator (temp)); } catch (boost::python::error_already_set const &) diff --git a/src/indexing/slice.cpp b/src/indexing/slice.cpp index d98649dd..00d2712d 100755 --- a/src/indexing/slice.cpp +++ b/src/indexing/slice.cpp @@ -1,5 +1,3 @@ -// -*- mode:c++ -*- -// // Module slice.cpp // // Copyright (c) 2003 Raoul M. Gough @@ -18,6 +16,19 @@ #include #include +///////////////////////////////////////////////////////////////////////////// +// MSVC6 workarounds +///////////////////////////////////////////////////////////////////////////// + +#if defined (BOOST_NO_MEMBER_TEMPLATES) +namespace boost { namespace python { namespace indexing { + slice::slice (::boost::python::handle<> const &p) : object (p) { } + slice::slice (::boost::python::detail::borrowed_reference p) : object (p) { } + slice::slice (::boost::python::detail::new_reference p) : object (p) { } + slice::slice (::boost::python::detail::new_non_null_reference p) : object (p) { } +} } } +#endif + ///////////////////////////////////////////////////////////////////////////// // slice copy constructor ///////////////////////////////////////////////////////////////////////////// diff --git a/test/int_wrapper.hpp b/test/int_wrapper.hpp index 119e9e59..a14f0597 100755 --- a/test/int_wrapper.hpp +++ b/test/int_wrapper.hpp @@ -23,6 +23,7 @@ #include #include #include +#include struct int_wrapper { static bool our_trace_flag; @@ -42,6 +43,8 @@ struct int_wrapper { inline static void setTrace (bool onoff); }; +BOOST_TT_BROKEN_COMPILER_SPEC (int_wrapper) + inline bool operator== (int_wrapper const &lhs, int_wrapper const &rhs); inline bool operator!= (int_wrapper const &lhs, int_wrapper const &rhs); inline bool operator< (int_wrapper const &lhs, int_wrapper const &rhs); diff --git a/test/test_array_ext.cpp b/test/test_array_ext.cpp index b0cf8475..926a0e6e 100755 --- a/test/test_array_ext.cpp +++ b/test/test_array_ext.cpp @@ -30,7 +30,7 @@ boost::python::indexing::iterator_range get_array_plain() { static int array[] = { 8, 6, 4, 2, 1, 3, 5, 7, 0 }; - return boost::python::indexing::make_iterator_range (array); + return BOOST_MAKE_ITERATOR_RANGE (array); } boost::python::indexing::iterator_range get_array_wrap() @@ -40,11 +40,13 @@ boost::python::indexing::iterator_range get_array_wrap() , int_wrapper(1), int_wrapper(3), int_wrapper(5) , int_wrapper(7), int_wrapper(0) }; - return boost::python::indexing::make_iterator_range (array); + return BOOST_MAKE_ITERATOR_RANGE (array); } BOOST_PYTHON_MODULE(test_array_ext) { + namespace indexing = boost::python::indexing; + boost::python::implicitly_convertible (); boost::python::def ("setTrace", &int_wrapper::setTrace); @@ -55,15 +57,23 @@ BOOST_PYTHON_MODULE(test_array_ext) .def ("__cmp__", compare) ; - typedef boost::python::indexing::iterator_range Container1; + typedef indexing::iterator_range Container1; + typedef indexing::iterator_range Container2; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; + typedef indexing::container_suite Suite2; +#else + typedef indexing::iterator_range_suite Suite1; + typedef indexing::iterator_range_suite Suite2; +#endif boost::python::class_ ("Array", boost::python::init()) - .def (boost::python::indexing::container_suite()); + .def (Suite1()); boost::python::def ("get_array_plain", get_array_plain); - typedef boost::python::indexing::iterator_range Container2; // reference_existing_object is safe in this case, because the array // is static, and we never manually destroy any array elements. There @@ -72,9 +82,9 @@ BOOST_PYTHON_MODULE(test_array_ext) // lifetimes of the array elements. boost::python::class_ ("Array_ref", boost::python::init()) - .def (boost::python::indexing::container_suite - ::with_policies(boost::python::return_value_policy - ())); + .def (Suite2::with_policies ( + boost::python::return_value_policy < + boost::python::reference_existing_object>())); boost::python::def ("get_array_wrap", get_array_wrap); } diff --git a/test/test_container_proxy.cpp b/test/test_container_proxy.cpp index 44f84640..dec7370d 100755 --- a/test/test_container_proxy.cpp +++ b/test/test_container_proxy.cpp @@ -16,7 +16,9 @@ // $Id$ // +#include #include +#include #include #include #include @@ -27,6 +29,21 @@ bool int_wrapper::our_trace_flag = true; unsigned int_wrapper::our_object_counter = 0; +#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1300) +// Works with element_proxy instances because of the reference +// conversion operator +static void increment (int_wrapper &int_wrap, int val) { + int_wrap.increment (val); +} +#else +// The implicit conversion provided by element_proxy doesn't work +// with MSVC[67]. Instead use the element_proxy operator-> +template +static void increment (T const &proxy, int val) { + proxy->increment (val); +} +#endif + template void initial_tests (ProxyContainer &proxy_container) { @@ -60,7 +77,7 @@ void initial_tests (ProxyContainer &proxy_container) BOOST_CHECK (proxy_container.is_valid()); BOOST_CHECK (ref0.use_count() == 2); - ((int_wrapper &) proxy_container[0]).increment (2); + increment (proxy_container[0], 2); BOOST_CHECK (ref0 == int_wrapper (3)); BOOST_CHECK (proxy_container[0] == int_wrapper (3)); @@ -97,14 +114,15 @@ void test_direct_proxy () reference ref0 ((*proxy_auto_p)[0]); reference refn ((*proxy_auto_p)[proxy_auto_p->size() - 1]); - static_cast(ref0).increment (5); - static_cast(refn).increment (10); + increment (ref0, 5); + increment (refn, 10); BOOST_CHECK (ref0 == int_wrapper (5)); BOOST_CHECK (refn == int_wrapper (10)); BOOST_CHECK (ref0.use_count() == 2); BOOST_CHECK (refn.use_count() == 2); - proxy_auto_p.reset(); // Invoke container_proxy destructor + // Invoke container_proxy destructor + BOOST_PYTHON_INDEXING_RESET_AUTO_PTR (proxy_auto_p, 0); BOOST_CHECK (ref0.use_count() == 1); // Detached BOOST_CHECK (refn.use_count() == 1); // Detached @@ -121,8 +139,7 @@ void test_direct_proxy () BOOST_CHECK (proxy_container.size() == raw_container.size()); reference ref1 (proxy_container[1]); - static_cast(ref1).increment (5); - + increment (ref1, 5); proxy_container_type temp; temp.push_back (int_wrapper (10)); reference ref2 (temp[0]); @@ -163,7 +180,7 @@ void test_indirect_proxy () reference ref2 (proxy_container[2]); BOOST_CHECK (ref2.use_count() == 2); // Still attached - static_cast(proxy_container[2]).increment (5); + increment (proxy_container[2], 5); BOOST_CHECK (ref2 == int_wrapper (5)); // Notify proxy of insert in raw container (*after* insert) @@ -171,7 +188,7 @@ void test_indirect_proxy () proxy_container.notify_insertion (0, 1); BOOST_CHECK (proxy_container.is_valid()); BOOST_CHECK (ref2.use_count() == 2); // Still attached - static_cast(proxy_container[3]).increment (5); + increment (proxy_container[3], 5); BOOST_CHECK (ref2 == int_wrapper (10)); // Create reference to about-to-be-erased value @@ -186,7 +203,7 @@ void test_indirect_proxy () BOOST_CHECK (ref0.use_count() == 1); // Ref to erased value detached BOOST_CHECK (ref0 == int_wrapper (7)); // Value copied before erase BOOST_CHECK (ref2.use_count() == 2); // Other ref still attached - static_cast(proxy_container[1]).increment (5); + increment (proxy_container[1], 5); BOOST_CHECK (ref2 == int_wrapper (15)); // Notify proxy of replacement in raw container (*before* assignment) @@ -214,6 +231,10 @@ struct deque_generator { }; }; +// Make the indirect holders work with broken compilers +BOOST_TT_BROKEN_COMPILER_SPEC (std::vector) +BOOST_TT_BROKEN_COMPILER_SPEC (std::deque) + int test_main (int argc, char *argv[]) { namespace indexing = boost::python::indexing; diff --git a/test/test_deque_ext.cpp b/test/test_deque_ext.cpp index b902b54c..607252aa 100755 --- a/test/test_deque_ext.cpp +++ b/test/test_deque_ext.cpp @@ -54,24 +54,28 @@ BOOST_PYTHON_MODULE(test_deque_ext) ; typedef std::deque Container1; - - boost::python::class_("Deque") - .def (indexing::container_suite()) - ; - typedef std::deque Container2; + typedef indexing::container_proxy< + Container2, indexing::identity, deque_generator> Container3; + +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; + typedef indexing::container_suite Suite2; + typedef indexing::container_suite Suite3; +#else + typedef indexing::deque_suite Suite1; + typedef indexing::deque_suite Suite2; + typedef indexing::container_proxy_suite Suite3; +#endif + + boost::python::class_("Deque").def (Suite1()); // Returning internal references to elements of a deque is // dangerous - the references can be invalidated by inserts or // deletes! boost::python::class_("Deque_ref") - .def (indexing::container_suite + .def (Suite2 ::with_policies (boost::python::return_internal_reference<>())); - typedef indexing::container_proxy< - Container2, indexing::identity, deque_generator> Container3; - - boost::python::class_("Deque_proxy") - .def (indexing::container_suite()) - ; + boost::python::class_("Deque_proxy").def (Suite3()); } diff --git a/test/test_indexing_const.cpp b/test/test_indexing_const.cpp index b5738149..592e1625 100755 --- a/test/test_indexing_const.cpp +++ b/test/test_indexing_const.cpp @@ -37,12 +37,18 @@ std::vector get_vector () , int_wrapper(7), int_wrapper(0) }; return std::vector +#if BOOST_WORKAROUND (BOOST_MSVC, <=1200) + (array, array + sizeof(array) / sizeof (array[0])); +#else (boost::python::indexing::begin(array) , boost::python::indexing::end(array)); +#endif } BOOST_PYTHON_MODULE(test_indexing_const_ext) { + namespace indexing = boost::python::indexing; + boost::python::implicitly_convertible (); boost::python::def ("setTrace", &int_wrapper::setTrace); @@ -56,8 +62,14 @@ BOOST_PYTHON_MODULE(test_indexing_const_ext) typedef std::vector Container1; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; +#else + typedef indexing::vector_suite Suite1; +#endif + boost::python::class_("Vector_const") - .def (boost::python::indexing::container_suite()) + .def (Suite1()) ; boost::python::def ("get_vector", get_vector); diff --git a/test/test_list_ext.cpp b/test/test_list_ext.cpp index 518be94b..4f0553a4 100755 --- a/test/test_list_ext.cpp +++ b/test/test_list_ext.cpp @@ -29,6 +29,8 @@ unsigned int_wrapper::our_object_counter = 0; BOOST_PYTHON_MODULE(test_list_ext) { + namespace indexing = boost::python::indexing; + boost::python::implicitly_convertible (); boost::python::def ("setTrace", &int_wrapper::setTrace); @@ -41,6 +43,12 @@ BOOST_PYTHON_MODULE(test_list_ext) typedef std::list Container1; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; +#else + typedef indexing::list_suite Suite1; +#endif + boost::python::class_("List") - .def (boost::python::indexing::container_suite()); + .def (Suite1()); } diff --git a/test/test_vector_ext.cpp b/test/test_vector_ext.cpp index 1133cd3f..db27fd6c 100755 --- a/test/test_vector_ext.cpp +++ b/test/test_vector_ext.cpp @@ -33,6 +33,8 @@ unsigned int_wrapper::our_object_counter = 0; BOOST_PYTHON_MODULE(test_vector_ext) { + namespace indexing = boost::python::indexing; + boost::python::implicitly_convertible (); boost::python::def ("setTrace", &int_wrapper::setTrace); @@ -44,40 +46,33 @@ BOOST_PYTHON_MODULE(test_vector_ext) ; typedef std::vector Container1; + typedef std::vector Container2; + typedef indexing::container_proxy< std::vector > Container3; + +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; + typedef indexing::container_suite Suite2; + typedef indexing::container_suite Suite3; +#else + typedef indexing::vector_suite Suite1; + typedef indexing::vector_suite Suite2; + typedef indexing::container_proxy_suite Suite3; +#endif boost::python::class_("Vector") - .def (boost::python::indexing::container_suite()) + .def (Suite1()) .def ("reserve", &Container1::reserve) ; - typedef std::vector Container2; - // Returning internal references to elements of a vector is // dangerous - the references can be invalidated by inserts or // deletes! boost::python::class_("Vector_ref") - .def (boost::python::indexing::container_suite + .def (Suite2 ::with_policies (boost::python::return_internal_reference<>())); - typedef boost::python::indexing::container_proxy< std::vector > - Container3; - boost::python::class_("Vector_proxy") - .def (boost::python::indexing::container_suite()) + .def (Suite3()) .def ("reserve", &Container3::reserve) ; - - /* The no-partial-specialization version for vector - - using namespace boost::python; - using namespace indexing; - - class_ > ("vector_int") - .def (visitor < - default_algorithms < - default_sequence_traits < - std::vector > >, - return_value_policy - >()); - */ } diff --git a/test/test_vector_shared.cpp b/test/test_vector_shared.cpp index ec0adb86..5557b21b 100755 --- a/test/test_vector_shared.cpp +++ b/test/test_vector_shared.cpp @@ -15,13 +15,19 @@ #include "int_wrapper.hpp" #include +#include +typedef boost::shared_ptr int_wrapper_holder; + +#if !BOOST_WORKAROUND (BOOST_MSVC, == 1200) // Declare overloads for correct sort and find of int_wrappers via // shared pointers -typedef boost::shared_ptr int_wrapper_holder; bool operator< (int_wrapper_holder const &, int_wrapper_holder const &); bool operator== (int_wrapper_holder const &, int_wrapper_holder const &); bool operator!= (int_wrapper_holder const &, int_wrapper_holder const &); +#endif + +BOOST_TT_BROKEN_COMPILER_SPEC (boost::shared_ptr) #include #include @@ -35,6 +41,7 @@ bool operator!= (int_wrapper_holder const &, int_wrapper_holder const &); bool int_wrapper::our_trace_flag = true; unsigned int_wrapper::our_object_counter = 0; +#if !BOOST_WORKAROUND (BOOST_MSVC, == 1200) bool operator< (int_wrapper_holder const &lhs, int_wrapper_holder const &rhs) { return (*lhs) < (*rhs); @@ -49,6 +56,56 @@ bool operator!= (int_wrapper_holder const &lhs, int_wrapper_holder const &rhs) { return (*lhs) != (*rhs); } +#endif + +namespace indexing = boost::python::indexing; + +typedef std::vector Container1; + +#if BOOST_WORKAROUND (BOOST_MSVC, == 1200) +// Unfortunately, the comparison operator overloads don't work under +// MSVC6, so we have to use a sledgehammer and replace the +// implementations of some of the search functions + +struct bound_compare { + int_wrapper_holder m_lhs; + bound_compare (int_wrapper_holder const &lhs) : m_lhs (lhs) { } + bool operator()(int_wrapper_holder const &rhs) { return (*m_lhs) == (*rhs); } +}; + +struct msvc6_vector_shared_algorithms + : public indexing::default_algorithms < + indexing::default_sequence_traits + , msvc6_vector_shared_algorithms + > +{ + typedef indexing::default_algorithms < + indexing::default_sequence_traits + , msvc6_vector_shared_algorithms + > base_type; + + typedef msvc6_vector_shared_algorithms self_type; + + // key_param will be boost::shared_ptr or ref to same + + static bool less_than (key_param lhs, key_param rhs) { + return (*lhs) < (*rhs); + } + + static iterator find (container &c, key_param k) { + return std::find_if (c.begin(), c.end(), bound_compare (k)); + } + + static size_type count (container &c, key_param k) { + return std::count_if (c.begin(), c.end(), bound_compare (k)); + } + + static void sort (container &c) { + std::sort (c.begin(), c.end(), self_type::less_than); + } +}; + +#endif BOOST_PYTHON_MODULE(test_vector_shared_ext) { @@ -63,10 +120,22 @@ BOOST_PYTHON_MODULE(test_vector_shared_ext) .def ("__cmp__", compare) ; - typedef std::vector Container1; +#if BOOST_WORKAROUND (BOOST_MSVC, == 1200) + // MSVC6 version here + typedef indexing::container_suite < + Container1, msvc6_vector_shared_algorithms> Suite1; + +#elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + // Normal version here + typedef indexing::container_suite Suite1; + +#else + // For any other compilers that don't have partial specialization + typedef indexing::vector_suite Suite1; +#endif boost::python::class_("Vector_shared") - .def (boost::python::indexing::container_suite()) + .def (Suite1()) .def ("reserve", &Container1::reserve) ; } diff --git a/test/testnonlinear.cpp b/test/testnonlinear.cpp index 5866e08b..b6af800e 100755 --- a/test/testnonlinear.cpp +++ b/test/testnonlinear.cpp @@ -30,6 +30,8 @@ unsigned int_wrapper::our_object_counter = 0; BOOST_PYTHON_MODULE(testnonlinear) { + namespace indexing = boost::python::indexing; + boost::python::implicitly_convertible (); boost::python::def ("setTrace", &int_wrapper::setTrace); @@ -43,21 +45,12 @@ BOOST_PYTHON_MODULE(testnonlinear) typedef std::map Container1; typedef std::set Container2; -#if !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - typedef boost::python::indexing::container_suite Suite1; - typedef boost::python::indexing::container_suite Suite2; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef indexing::container_suite Suite1; + typedef indexing::container_suite Suite2; #else - typedef boost::python::indexing::container_suite - > > Suite1; - - typedef boost::python::indexing::container_suite - > > Suite2; + typedef indexing::map_suite Suite1; + typedef indexing::set_suite Suite2; #endif boost::python::class_("Map").def (Suite1());