From fbf82cc6e9e6262517fcef416680dab0cf3ea30f Mon Sep 17 00:00:00 2001 From: Raoul Gough Date: Tue, 14 Oct 2003 12:48:35 +0000 Subject: [PATCH] Add optional override parameter to all algorithm templates [SVN r20378] --- .../python/suite/indexing/algorithms.hpp | 345 ++++++++++-------- 1 file changed, 200 insertions(+), 145 deletions(-) diff --git a/include/boost/python/suite/indexing/algorithms.hpp b/include/boost/python/suite/indexing/algorithms.hpp index 1e0a27f9..2e5e7b36 100755 --- a/include/boost/python/suite/indexing/algorithms.hpp +++ b/include/boost/python/suite/indexing/algorithms.hpp @@ -26,16 +26,37 @@ #include #include #include +#include #include #include #include #include namespace boost { namespace python { namespace indexing { - template - struct default_algorithms + namespace detail { + struct no_override { }; + + template + struct maybe_override + { + // Probably need to disable this if there is no partial + // specialization support, because Override is almost certain to + // be an incomplete type. If that is right, the workaround + // version would just have to do "typedef Base type;" + + typedef typename mpl::if_ + , Base, Override> + ::type type; + }; + } + + template + class default_algorithms { - typedef default_algorithms self_type; + typedef default_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + + public: typedef ContainerTraits container_traits; // Import typedefs from the container_traits for convenience @@ -91,11 +112,17 @@ namespace boost { namespace python { namespace indexing { // Special cases for std::list ///////////////////////////////////////////////////////////////////////// - template - struct list_algorithms : public default_algorithms + template + class list_algorithms + : public default_algorithms + , Ovr> + ::type> { - private: - typedef default_algorithms Parent; + typedef list_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef default_algorithms Parent; public: typedef typename Parent::container container; @@ -110,12 +137,17 @@ namespace boost { namespace python { namespace indexing { // Base class for associative containers ///////////////////////////////////////////////////////////////////////// - template - struct assoc_algorithms : public default_algorithms + template + class assoc_algorithms + : public default_algorithms + , Ovr> + ::type> { - private: - typedef default_algorithms Parent; - typedef assoc_algorithms self_type; + typedef assoc_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef default_algorithms Parent; public: typedef typename Parent::iterator iterator; @@ -142,12 +174,17 @@ namespace boost { namespace python { namespace indexing { // Special case for sets ///////////////////////////////////////////////////////////////////////// - template - struct set_algorithms : public assoc_algorithms + template + class set_algorithms + : public assoc_algorithms + , Ovr> + ::type> { - private: - typedef assoc_algorithms Parent; - typedef set_algorithms self_type; + typedef set_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef assoc_algorithms Parent; public: typedef typename Parent::container container; @@ -162,12 +199,17 @@ namespace boost { namespace python { namespace indexing { // Special case for map ///////////////////////////////////////////////////////////////////////// - template - struct map_algorithms : public assoc_algorithms + template + class map_algorithms + : public assoc_algorithms + , Ovr> + ::type> { - private: - typedef assoc_algorithms Parent; - typedef map_algorithms self_type; + typedef map_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef assoc_algorithms Parent; public: typedef typename Parent::container container; @@ -186,9 +228,9 @@ namespace boost { namespace python { namespace indexing { // Get the size of a container ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::size_type - default_algorithms::size (container &c) + template + typename default_algorithms::size_type + default_algorithms::size (container &c) { return c.size(); } @@ -197,15 +239,15 @@ namespace boost { namespace python { namespace indexing { // Range check an index and throw out_of_range if necessary ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::size_type - default_algorithms::bounds_check (container &c - , index_param ix - , char const *msg - , bool one_past - , bool truncate) + template + typename default_algorithms::size_type + default_algorithms::bounds_check (container &c + , index_param ix + , char const *msg + , bool one_past + , bool truncate) { - size_type bound = size(c) + (one_past ? 1 : 0); + size_type bound = most_derived::size(c) + (one_past ? 1 : 0); size_type result; if (truncate) @@ -253,26 +295,26 @@ namespace boost { namespace python { namespace indexing { // Find an element in a container (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::iterator - default_algorithms::find (container &c - , key_param key) + template + typename default_algorithms::iterator + default_algorithms::find (container &c + , key_param key) { - return std::find (begin(c), end(c), key); + return std::find (most_derived::begin(c), most_derived::end(c), key); } ///////////////////////////////////////////////////////////////////////// // Find an element and return its index (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::size_type - default_algorithms::get_index (container &c - , key_param key) + template + typename default_algorithms::size_type + default_algorithms::get_index (container &c + , key_param key) { - iterator temp (find (c, key)); + iterator temp (most_derived::find (c, key)); - if (temp == end(c)) + if (temp == most_derived::end(c)) { PyErr_SetString (PyExc_ValueError , "get_index: element not found"); @@ -280,66 +322,66 @@ namespace boost { namespace python { namespace indexing { boost::python::throw_error_already_set (); } - return std::distance (begin (c), temp); + return std::distance (most_derived::begin (c), temp); } ///////////////////////////////////////////////////////////////////////// // Count occurances of an element in a container (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::size_type - default_algorithms::count (container &c - , key_param key) + template + typename default_algorithms::size_type + default_algorithms::count (container &c + , key_param key) { - return std::count (begin(c), end(c), key); + return std::count (most_derived::begin(c), most_derived::end(c), key); } ///////////////////////////////////////////////////////////////////////// // Check whether a container contains the given element (std algo ver) ///////////////////////////////////////////////////////////////////////// - template + template bool - default_algorithms::contains (container &c - , key_param key) + default_algorithms::contains (container &c + , key_param key) { - return find (c, key) != end(c); + return most_derived::find (c, key) != most_derived::end(c); } ///////////////////////////////////////////////////////////////////////// // Index into a container (generic version) ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::reference - default_algorithms::get (container &c - , index_param ix) + template + typename default_algorithms::reference + default_algorithms::get (container &c + , index_param ix) { - return c[bounds_check (c, ix, "get")]; + return c[most_derived::bounds_check (c, ix, "get")]; } ///////////////////////////////////////////////////////////////////////// // Assign a value at a particular index (generic version) ///////////////////////////////////////////////////////////////////////// - template + template void - default_algorithms::assign (container &c - , index_param ix - , value_param val) + default_algorithms::assign (container &c + , index_param ix + , value_param val) { - c[bounds_check (c, ix, "assign")] = val; + c[most_derived::bounds_check (c, ix, "assign")] = val; } ///////////////////////////////////////////////////////////////////////// // Insert at end of a container (generic version) ///////////////////////////////////////////////////////////////////////// - template + template void - default_algorithms::push_back (container &c - , value_param v) + default_algorithms::push_back (container &c + , value_param v) { c.push_back (v); } @@ -348,16 +390,18 @@ namespace boost { namespace python { namespace indexing { // Insert at an index in the container (generic version) ///////////////////////////////////////////////////////////////////////// - template + template void - default_algorithms::insert (container &c - , index_param i - , value_param v) + default_algorithms::insert (container &c + , index_param i + , value_param v) { - iterator insert_pos (c.begin()); + iterator insert_pos (most_derived::begin(c)); // Index may range up to c.size() inclusive to allow inserting at end - std::advance (insert_pos, bounds_check (c, i, "insert", true, true)); + std::advance (insert_pos + , most_derived::bounds_check (c, i, "insert", true, true)); + c.insert (insert_pos, v); } @@ -365,70 +409,80 @@ namespace boost { namespace python { namespace indexing { // Erase between given indexes in the container (generic version) ///////////////////////////////////////////////////////////////////////// - template + template void - default_algorithms::erase_range (container &c - , index_param from - , index_param to) + default_algorithms::erase_range (container &c + , index_param from + , index_param to) { - // End index is one-past-the-end, so may range up to c.size() inclusive + iterator start (most_derived::begin(c)); + iterator finish (most_derived::begin(c)); - c.erase (c.begin() + bounds_check (c, from, "erase_range (from)") - , c.begin() + bounds_check (c, to, "erase_range (to)", true)); + // Start index must be properly in bounds + std::advance + (start, most_derived::bounds_check (c, from, "erase_range (from)")); + + // End index is one-past-the-end, so may range up to c.size() inclusive + std::advance + (finish, most_derived::bounds_check (c, to, "erase_range (to)", true)); + + c.erase (start, finish); } ///////////////////////////////////////////////////////////////////////// // Erase one element at the given index in the container (generic version) ///////////////////////////////////////////////////////////////////////// - template + template void - default_algorithms::erase_one (container &c - , index_param ix) + default_algorithms::erase_one (container &c + , index_param ix) { - c.erase (c.begin() + bounds_check (c, ix, "erase_one")); + iterator iter (most_derived::begin(c)); + std::advance (iter, most_derived::bounds_check (c, ix, "erase_one")); + c.erase (iter); } ///////////////////////////////////////////////////////////////////////// // Reverse the contents of a container (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - void default_algorithms::reverse (container &c) + template + void default_algorithms::reverse (container &c) { - std::reverse (begin(c), end(c)); + std::reverse (most_derived::begin(c), most_derived::end(c)); } ///////////////////////////////////////////////////////////////////////// // Sort the contents of a container (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - void default_algorithms::sort (container &c) + template + void default_algorithms::sort (container &c) { - std::sort (begin(c), end(c)); + std::sort (most_derived::begin(c), most_derived::end(c)); } ///////////////////////////////////////////////////////////////////////// // slice_helper factory function (default version) ///////////////////////////////////////////////////////////////////////// - template - typename default_algorithms::slice_helper - default_algorithms + template + typename default_algorithms::slice_helper + default_algorithms ::make_slice_helper (container &c, slice const &sl) { - return slice_helper (c, integer_slice (sl, size (c))); + return slice_helper (c, integer_slice (sl, most_derived::size (c))); } ///////////////////////////////////////////////////////////////////////// // Visitor helper function (default version) ///////////////////////////////////////////////////////////////////////// - template + template template void - default_algorithms + default_algorithms ::visitor_helper (PythonClass &pyClass, Policy const &policy) { container_traits::visitor_helper (pyClass, policy); @@ -438,8 +492,8 @@ namespace boost { namespace python { namespace indexing { // Reverse the contents of a list (member function version) ///////////////////////////////////////////////////////////////////////// - template - void list_algorithms::reverse (container &c) + template + void list_algorithms::reverse (container &c) { c.reverse(); } @@ -448,8 +502,8 @@ namespace boost { namespace python { namespace indexing { // Sort the contents of a container (std algorithm version) ///////////////////////////////////////////////////////////////////////// - template - void list_algorithms::sort (container &c) + template + void list_algorithms::sort (container &c) { c.sort(); } @@ -458,32 +512,32 @@ namespace boost { namespace python { namespace indexing { // Index into a container (associative version) ///////////////////////////////////////////////////////////////////////// - template - typename assoc_algorithms::reference - assoc_algorithms::get (container &c, index_param ix) + template + typename assoc_algorithms::reference + assoc_algorithms::get (container &c, index_param ix) { - return *find_or_throw (c, ix); + return *most_derived::find_or_throw (c, ix); } ///////////////////////////////////////////////////////////////////////// // Index into a container (map version) ///////////////////////////////////////////////////////////////////////// - template - typename map_algorithms::reference - map_algorithms::get (container &c, index_param ix) + template + typename map_algorithms::reference + map_algorithms::get (container &c, index_param ix) { - return self_type::find_or_throw (c, ix)->second; + return most_derived::find_or_throw (c, ix)->second; } ///////////////////////////////////////////////////////////////////////// // Erase elements with the given key (associative version) ///////////////////////////////////////////////////////////////////////// - template + template void - assoc_algorithms::erase_one (container &c - , key_param key) + assoc_algorithms::erase_one (container &c + , key_param key) { if (c.erase (key) == 0) { @@ -495,26 +549,26 @@ namespace boost { namespace python { namespace indexing { } ///////////////////////////////////////////////////////////////////////// - // Assign a value at a particular index (set version) + // Assign a value at a particular index (set version with dummy param) ///////////////////////////////////////////////////////////////////////// - template + template void - set_algorithms::assign (container &c - , index_param ix - , value_param val) + set_algorithms::assign (container &c + , index_param ix + , value_param dummy) { - insert (c, ix); // Ignore dummy value parameter + most_derived::insert (c, ix); // Ignore dummy value parameter } ///////////////////////////////////////////////////////////////////////// // Insert an element into a set ///////////////////////////////////////////////////////////////////////// - template + template void - set_algorithms::insert (container &c - , index_param ix) + set_algorithms::insert (container &c + , index_param ix) { if (!c.insert (ix).second) { @@ -529,11 +583,11 @@ namespace boost { namespace python { namespace indexing { // Assign a value at a particular index (map version) ///////////////////////////////////////////////////////////////////////// - template + template void - map_algorithms::assign (container &c - , index_param ix - , value_param val) + map_algorithms::assign (container &c + , index_param ix + , value_param val) { c[ix] = val; // Handles overwrite and insert } @@ -542,11 +596,11 @@ namespace boost { namespace python { namespace indexing { // Insert a new key, value pair into a map ///////////////////////////////////////////////////////////////////////// - template + template void - map_algorithms::insert (container &c - , index_param ix - , value_param val) + map_algorithms::insert (container &c + , index_param ix + , value_param val) { typedef std::pair - typename assoc_algorithms::iterator - assoc_algorithms::find (container &c, key_param key) + template + typename assoc_algorithms::iterator + assoc_algorithms + ::find (container &c, key_param key) { return c.find (key); } @@ -579,12 +634,12 @@ namespace boost { namespace python { namespace indexing { // Find an element in an associative container ///////////////////////////////////////////////////////////////////////// - template + template bool - assoc_algorithms::contains (container &c - , key_param key) + assoc_algorithms::contains (container &c + , key_param key) { - return self_type::find (c, key) != self_type::end(c); + return most_derived::find (c, key) != most_derived::end(c); } ///////////////////////////////////////////////////////////////////////// @@ -592,14 +647,14 @@ namespace boost { namespace python { namespace indexing { // not found ///////////////////////////////////////////////////////////////////////// - template - typename assoc_algorithms::iterator - assoc_algorithms::find_or_throw (container &c - , index_param ix) + template + typename assoc_algorithms::iterator + assoc_algorithms::find_or_throw (container &c + , index_param ix) { - iterator iter = self_type::find (c, ix); + iterator iter = most_derived::find (c, ix); - if (iter == self_type::end(c)) + if (iter == most_derived::end(c)) { PyErr_SetString (PyExc_ValueError , "associative container: key not found"); @@ -614,10 +669,10 @@ namespace boost { namespace python { namespace indexing { // Count occurances of an element in a container (associative version) ///////////////////////////////////////////////////////////////////////// - template - typename assoc_algorithms::size_type - assoc_algorithms::count (container &c - , key_param key) + template + typename assoc_algorithms::size_type + assoc_algorithms::count (container &c + , key_param key) { return c.count (key); }