diff --git a/include/boost/python/suite/indexing/algo_selector.hpp b/include/boost/python/suite/indexing/algo_selector.hpp index c83b9d43..47f96db8 100755 --- a/include/boost/python/suite/indexing/algo_selector.hpp +++ b/include/boost/python/suite/indexing/algo_selector.hpp @@ -1,15 +1,16 @@ // Header file algo_selector.hpp // -// Automatic selection of container algorithms (and traits) for known -// container types (basically, all STL container instances, as well as -// iterator_range instances). -// // Copyright (c) 2003 Raoul M. Gough // // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy // at http://www.boost.org/LICENSE_1_0.txt) // +// Declarations for automatic selection of container algorithms and +// traits for known container types. Specialized versions of +// selector_impl exist in the STL container support headers (set.hpp, +// vector.hpp, etc.) +// // History // ======= // 2003/ 9/11 rmg File creation @@ -20,164 +21,18 @@ #ifndef BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP #define BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP -#include -// Include this early to ensure the declaration of the get_pointer -// overload for element_proxy is in-scope for both name-lookup phases - -#include -#include -#include - -// Definitions of further supported types -#include -#include -#include -#include -#include -#include - namespace boost { namespace python { namespace indexing { - ///////////////////////////////////////////////////////////////////////// - // Automated algorithm and trait selection - ///////////////////////////////////////////////////////////////////////// - namespace detail { template class selector_impl; - // selector_impl instances should include *two* publically - // accessible typedefs, one for the non-const version of the - // container, and one for the const version. This saves having to - // have two specializations of selector_impl for every kind of - // container. - - // std::set - template - class selector_impl > - { - typedef std::set Container; - - typedef set_traits mutable_traits; - typedef set_traits const_traits; - - public: - typedef set_algorithms mutable_algorithms; - typedef set_algorithms const_algorithms; - }; - - // std::multiset - template - class selector_impl > - { - typedef std::multiset Container; - - typedef set_traits mutable_traits; - typedef set_traits const_traits; - - public: - typedef set_algorithms mutable_algorithms; - typedef set_algorithms const_algorithms; - }; - - // std::map - template - class selector_impl > - { - typedef std::map Container; - - typedef map_traits mutable_traits; - typedef map_traits const_traits; - - public: - typedef map_algorithms mutable_algorithms; - typedef map_algorithms const_algorithms; - }; - - // std::multimap - template - class selector_impl > - { - typedef std::multimap Container; - - typedef map_traits mutable_traits; - typedef map_traits const_traits; - - public: - typedef map_algorithms mutable_algorithms; - typedef map_algorithms const_algorithms; - }; - - // std::vector - template - class selector_impl > - { - typedef std::vector Container; - - typedef default_sequence_traits mutable_traits; - typedef default_sequence_traits const_traits; - - public: - typedef default_algorithms mutable_algorithms; - typedef default_algorithms const_algorithms; - }; - - // std::deque - template - class selector_impl > - { - typedef std::deque Container; - - typedef default_sequence_traits mutable_traits; - typedef default_sequence_traits const_traits; - - public: - typedef default_algorithms mutable_algorithms; - typedef default_algorithms const_algorithms; - }; - - // std::list - template - class selector_impl > - { - typedef std::list Container; - - typedef default_sequence_traits mutable_traits; - typedef default_sequence_traits const_traits; - - public: - typedef list_algorithms mutable_algorithms; - typedef list_algorithms const_algorithms; - }; - - // Iterator ranges - template - class selector_impl > - { - typedef iterator_range Container; - - typedef iterator_range_traits mutable_traits; - typedef iterator_range_traits const_traits; // ? - - public: - typedef default_algorithms mutable_algorithms; - typedef default_algorithms const_algorithms; - }; - - // Container proxies - template - class selector_impl > - { - typedef container_proxy Container; - - typedef container_proxy_traits mutable_traits; - typedef container_proxy_traits const_traits; - - public: - typedef default_algorithms mutable_algorithms; - typedef default_algorithms const_algorithms; - }; + // selector_impl specializations should include *two* publically + // accessible typedefs, called mutable_algorithms and + // const_algorithms. This saves having to have separate + // specializations for const and non-const containers. } - // Select the right algorithms for each supported kind of container + // Select the right algorithms for any const or non-const container + // that has a specialization of selector_impl // Generic version (mutable containers) template diff --git a/include/boost/python/suite/indexing/algorithms.hpp b/include/boost/python/suite/indexing/algorithms.hpp index e199bae2..9bf24822 100755 --- a/include/boost/python/suite/indexing/algorithms.hpp +++ b/include/boost/python/suite/indexing/algorithms.hpp @@ -1,5 +1,3 @@ -// -*- mode:c++ -*- -// // Header file algorithms.hpp // // Uniform interface layer for all containers. @@ -13,6 +11,7 @@ // History // ======= // 2003/ 9/11 rmg File creation from suite_utils.hpp +// 2003/10/28 rmg Split container-specific versions into separate headers // // $Id$ // @@ -109,31 +108,6 @@ namespace boost { namespace python { namespace indexing { // from the upper bound backwards and are bounds-checked. }; - ///////////////////////////////////////////////////////////////////////// - // Special cases for std::list - ///////////////////////////////////////////////////////////////////////// - - template - class list_algorithms - : public default_algorithms - , Ovr> - ::type> - { - typedef list_algorithms self_type; - typedef typename detail::maybe_override::type most_derived; - typedef default_algorithms Parent; - - public: - typedef typename Parent::container container; - - // Use member functions for the following (hiding base class versions) - static void reverse (container &); - static void sort (container &); - // static void sort (container &, PyObject *); - }; - ///////////////////////////////////////////////////////////////////////// // Base class for associative containers ///////////////////////////////////////////////////////////////////////// @@ -171,59 +145,6 @@ namespace boost { namespace python { namespace indexing { static iterator find_or_throw (container &, index_param); }; - ///////////////////////////////////////////////////////////////////////// - // Special case for sets - ///////////////////////////////////////////////////////////////////////// - - template - class set_algorithms - : public assoc_algorithms - , Ovr> - ::type> - { - typedef set_algorithms self_type; - typedef typename detail::maybe_override::type most_derived; - typedef assoc_algorithms Parent; - - public: - typedef typename Parent::container container; - typedef typename Parent::value_param value_param; - typedef typename Parent::index_param index_param; - - static void insert (container &, index_param); - }; - - ///////////////////////////////////////////////////////////////////////// - // Special case for map - ///////////////////////////////////////////////////////////////////////// - - template - class map_algorithms - : public assoc_algorithms - , Ovr> - ::type> - { - typedef map_algorithms self_type; - typedef typename detail::maybe_override::type most_derived; - typedef assoc_algorithms Parent; - - public: - typedef typename Parent::container container; - typedef typename Parent::reference reference; - typedef typename Parent::index_param index_param; - typedef typename Parent::value_param value_param; - - static reference get (container &, index_param); - // Version to return only the mapped type - - static void assign (container &, index_param, value_param); - static void insert (container &, index_param, value_param); - }; - ///////////////////////////////////////////////////////////////////////// // Get the size of a container ///////////////////////////////////////////////////////////////////////// @@ -486,26 +407,6 @@ namespace boost { namespace python { namespace indexing { container_traits::visitor_helper (pyClass, policy); } - ///////////////////////////////////////////////////////////////////////// - // Reverse the contents of a list (member function version) - ///////////////////////////////////////////////////////////////////////// - - template - void list_algorithms::reverse (container &c) - { - c.reverse(); - } - - ///////////////////////////////////////////////////////////////////////// - // Sort the contents of a container (std algorithm version) - ///////////////////////////////////////////////////////////////////////// - - template - void list_algorithms::sort (container &c) - { - c.sort(); - } - ///////////////////////////////////////////////////////////////////////// // Index into a container (associative version) ///////////////////////////////////////////////////////////////////////// @@ -517,17 +418,6 @@ namespace boost { namespace python { namespace indexing { 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) - { - return most_derived::find_or_throw (c, ix)->second; - } - ///////////////////////////////////////////////////////////////////////// // Erase elements with the given key (associative version) ///////////////////////////////////////////////////////////////////////// @@ -546,61 +436,6 @@ namespace boost { namespace python { namespace indexing { } } - ///////////////////////////////////////////////////////////////////////// - // Insert an element into a set - ///////////////////////////////////////////////////////////////////////// - - template - void - set_algorithms::insert ( - container &c, index_param ix) - { - if (!c.insert (ix).second) - { - PyErr_SetString ( - PyExc_ValueError, "Set already holds value for insertion"); - - boost::python::throw_error_already_set (); - } - } - - ///////////////////////////////////////////////////////////////////////// - // Assign a value at a particular index (map version) - ///////////////////////////////////////////////////////////////////////// - - template - void - map_algorithms::assign ( - container &c, index_param ix, value_param val) - { - c[ix] = val; // Handles overwrite and insert - } - - ///////////////////////////////////////////////////////////////////////// - // Insert a new key, value pair into a map - ///////////////////////////////////////////////////////////////////////// - - template - void - map_algorithms::insert ( - 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 - - if (!c.insert (pair_type (ix, val)).second) - { - PyErr_SetString ( - PyExc_ValueError, "Map already holds value for insertion"); - - boost::python::throw_error_already_set (); - } - } - ///////////////////////////////////////////////////////////////////////// // Find an element in an associative container ///////////////////////////////////////////////////////////////////////// diff --git a/include/boost/python/suite/indexing/container_proxy.hpp b/include/boost/python/suite/indexing/container_proxy.hpp index 1347460b..563d93a9 100755 --- a/include/boost/python/suite/indexing/container_proxy.hpp +++ b/include/boost/python/suite/indexing/container_proxy.hpp @@ -29,12 +29,16 @@ #include #include #include +#include #include -#include +#include // Default pointer container #include #include #include +#include +#include +#include namespace boost { namespace python { namespace indexing { template struct identity { @@ -641,6 +645,44 @@ namespace boost { namespace python { namespace indexing { return ok; } + ///////////////////////////////////////////////////////////////////////// + // ContainerTraits implementation for container_proxy instances + ///////////////////////////////////////////////////////////////////////// + + template + struct container_proxy_traits : public default_sequence_traits + { + 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 boost::call_traits::param_type value_param; + typedef typename boost::call_traits::param_type key_param; + + typedef value_traits value_traits_; + // Get value_traits for the reference type (i.e. element_proxy) + // to get the custom visitor_helper + }; + + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::list instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef container_proxy Container; + + typedef container_proxy_traits mutable_traits; + typedef container_proxy_traits const_traits; + + public: + typedef default_algorithms mutable_algorithms; + typedef default_algorithms const_algorithms; + }; + } } } } #endif // BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP diff --git a/include/boost/python/suite/indexing/container_traits.hpp b/include/boost/python/suite/indexing/container_traits.hpp index ffe1e623..d6234acd 100755 --- a/include/boost/python/suite/indexing/container_traits.hpp +++ b/include/boost/python/suite/indexing/container_traits.hpp @@ -13,6 +13,7 @@ // ======= // 2003/ 8/23 rmg File creation as container_suite.hpp // 2003/ 9/ 8 rmg Renamed container_traits.hpp +// 2003/10/28 rmg Split container-specific versions into separate headers // // $Id$ // @@ -72,32 +73,23 @@ namespace boost { namespace python { namespace indexing { typedef value_traits value_traits_; - BOOST_STATIC_CONSTANT (bool, has_mutable_ref + BOOST_STATIC_CONSTANT (bool, has_mutable_ref = base_type::has_mutable_ref && is_mutable); - BOOST_STATIC_CONSTANT (bool, has_find + BOOST_STATIC_CONSTANT (bool, has_find = value_traits_::equality_comparable); // Assume the worst for everything else - BOOST_STATIC_CONSTANT (bool, has_insert = false); - BOOST_STATIC_CONSTANT (bool, has_erase = false); - BOOST_STATIC_CONSTANT (bool, has_pop_back = false); - BOOST_STATIC_CONSTANT (bool, has_push_back = false); + BOOST_STATIC_CONSTANT (bool, has_insert = false); + BOOST_STATIC_CONSTANT (bool, has_erase = false); + BOOST_STATIC_CONSTANT (bool, has_pop_back = false); + BOOST_STATIC_CONSTANT (bool, has_push_back = false); // Forward visitor_helper to value_traits_ template static void visitor_helper (PythonClass &, Policy const &); }; - ///////////////////////////////////////////////////////////////////////// - // Traits for the iterator_range container emulator - ///////////////////////////////////////////////////////////////////////// - - template - struct iterator_range_traits : public base_container_traits - { - }; - ///////////////////////////////////////////////////////////////////////// // Default container traits - almost all "real" containers would meet // at least these requirements @@ -107,8 +99,8 @@ namespace boost { namespace python { namespace indexing { struct default_container_traits : public base_container_traits { typedef default_container_traits self_type; - BOOST_STATIC_CONSTANT (bool, has_insert = self_type::is_mutable); - BOOST_STATIC_CONSTANT (bool, has_erase = self_type::is_mutable); + BOOST_STATIC_CONSTANT (bool, has_insert = self_type::is_mutable); + BOOST_STATIC_CONSTANT (bool, has_erase = self_type::is_mutable); }; ///////////////////////////////////////////////////////////////////////// @@ -119,78 +111,10 @@ namespace boost { namespace python { namespace indexing { struct default_sequence_traits : public default_container_traits { typedef default_sequence_traits self_type; - BOOST_STATIC_CONSTANT (bool, has_pop_back = self_type::is_mutable); - BOOST_STATIC_CONSTANT (bool, has_push_back = self_type::is_mutable); + BOOST_STATIC_CONSTANT (bool, has_pop_back = self_type::is_mutable); + BOOST_STATIC_CONSTANT (bool, has_push_back = self_type::is_mutable); }; - ///////////////////////////////////////////////////////////////////////// - // Sequences within a container_proxy - ///////////////////////////////////////////////////////////////////////// - - template - struct container_proxy_traits : public default_sequence_traits - { - 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 boost::call_traits::param_type value_param; - typedef typename boost::call_traits::param_type key_param; - - typedef value_traits value_traits_; - // Get value_traits for the reference type (i.e. element_proxy) - // to get the custom visitor_helper - }; - - ///////////////////////////////////////////////////////////////////////// - // Associative containers set and multiset - ///////////////////////////////////////////////////////////////////////// - - template - struct set_traits : public default_container_traits - { - typedef typename Container::key_type value_type; // probably unused - 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; - - BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); - BOOST_STATIC_CONSTANT (bool, has_find = true); - - BOOST_STATIC_CONSTANT (bool, has_mutable_ref = false); - BOOST_STATIC_CONSTANT (bool, is_reorderable = false); - // Some compilers seem to deduce has_mutable_ref as true from the - // set iterator traits. The previous two constants explicitly hide - // the bad results of that. - }; - - ///////////////////////////////////////////////////////////////////////// - // Associative containers map and multimap - ///////////////////////////////////////////////////////////////////////// - - template - struct map_traits : public default_container_traits - { - typedef typename Container::mapped_type value_type; - 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; - - BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); - BOOST_STATIC_CONSTANT (bool, has_find = true); - BOOST_STATIC_CONSTANT (bool, is_reorderable = false); - // std::map::reference (reference to the mapped type) is mutable, - // so explicitly override the base-class assumption of - // is_reorderable - }; } } } ///////////////////////////////////////////////////////////////////////// diff --git a/include/boost/python/suite/indexing/deque.hpp b/include/boost/python/suite/indexing/deque.hpp new file mode 100755 index 00000000..c1d86f7c --- /dev/null +++ b/include/boost/python/suite/indexing/deque.hpp @@ -0,0 +1,48 @@ +// Header file deque.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// Indexing algorithms support for std::deque instances +// +// History +// ======= +// 2003/10/28 rmg File creation from algo_selector.hpp +// +// $Id$ +// + +#ifndef BOOST_PYTHON_INDEXING_DEQUE_HPP +#define BOOST_PYTHON_INDEXING_DEQUE_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { namespace indexing { + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::deque instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::deque Container; + + typedef default_sequence_traits mutable_traits; + typedef default_sequence_traits const_traits; + + public: + typedef default_algorithms mutable_algorithms; + typedef default_algorithms const_algorithms; + }; + } + +} } } + +#endif // BOOST_PYTHON_INDEXING_DEQUE_HPP diff --git a/include/boost/python/suite/indexing/iterator_range.hpp b/include/boost/python/suite/indexing/iterator_range.hpp index 4b29a1dd..982d5934 100755 --- a/include/boost/python/suite/indexing/iterator_range.hpp +++ b/include/boost/python/suite/indexing/iterator_range.hpp @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include namespace boost { namespace python { namespace indexing { template @@ -70,6 +73,12 @@ namespace boost { namespace python { namespace indexing { iterator m_end; }; + // Array support functions + template T *begin (T (&array)[N]); + template T *end (T (&array)[N]); + template iterator_range make_iterator_range ( + T (&array)[N]); + template iterator_range::iterator_range ( iterator_param begin, iterator_param end) @@ -133,14 +142,39 @@ namespace boost { namespace python { namespace indexing { } template - T *begin (T(&array)[N]) { + T *begin (T (&array)[N]) { return array; } template - T *end (T(&array)[N]) { + T *end (T (&array)[N]) { return array + N; } + + template + iterator_range make_iterator_range (T (&array)[N]) { + return iterator_range(begin (array), end (array)); + } + + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for iterator_range instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef iterator_range Container; + + typedef base_container_traits mutable_traits; + typedef base_container_traits const_traits; // ? + + public: + typedef default_algorithms mutable_algorithms; + typedef default_algorithms const_algorithms; + }; + } + } } } #endif // BOOST_PYTHON_INDEXING_ITERATOR_RANGE_HPP diff --git a/include/boost/python/suite/indexing/iterator_traits.hpp b/include/boost/python/suite/indexing/iterator_traits.hpp index b5f437ea..f63d726c 100755 --- a/include/boost/python/suite/indexing/iterator_traits.hpp +++ b/include/boost/python/suite/indexing/iterator_traits.hpp @@ -30,24 +30,6 @@ #include namespace boost { namespace python { namespace indexing { -#if !BOOST_MSVC - enum index_style_t { - index_style_none // No random access (iteration only) - , index_style_nonlinear // Random access by key (no slicing) - , index_style_linear // Random access by integer index (allows slicing) - }; -#else - // MSVC seems to have problems with static member variable constants - // of enumerated types, where it doesn't believe that an expression - // like (traits::index_style == index_style_linear) is a - // compile-time constant. However, the problem doesn't exist for - // int. - typedef int index_style_t; - index_style_t const index_style_none = 0; - index_style_t const index_style_nonlinear = 1; - index_style_t const index_style_linear = 2; -#endif - ////////////////////////////////////////////////////////////////////////// // Indexing traits for containers based on iterator pairs ////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/python/suite/indexing/list.hpp b/include/boost/python/suite/indexing/list.hpp new file mode 100755 index 00000000..71f0eaad --- /dev/null +++ b/include/boost/python/suite/indexing/list.hpp @@ -0,0 +1,92 @@ +// Header file list.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// Indexing algorithms support for std::list instances +// +// History +// ======= +// 2003/10/28 rmg File creation from algo_selector.hpp +// +// $Id$ +// + +#ifndef BOOST_PYTHON_INDEXING_LIST_HPP +#define BOOST_PYTHON_INDEXING_LIST_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { namespace indexing { + ///////////////////////////////////////////////////////////////////////// + // Algorithms implementation for std::list instances + ///////////////////////////////////////////////////////////////////////// + + template + class list_algorithms + : public default_algorithms + , Ovr> + ::type> + { + typedef list_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef default_algorithms Parent; + + public: + typedef typename Parent::container container; + + // Use member functions for the following (hiding base class versions) + static void reverse (container &); + static void sort (container &); + // static void sort (container &, PyObject *); + }; + + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::list instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::list Container; + + typedef default_sequence_traits mutable_traits; + typedef default_sequence_traits const_traits; + + public: + typedef list_algorithms mutable_algorithms; + typedef list_algorithms const_algorithms; + }; + } + + ///////////////////////////////////////////////////////////////////////// + // Reverse the contents of a list (using member function) + ///////////////////////////////////////////////////////////////////////// + + template + void list_algorithms::reverse (container &c) + { + c.reverse(); + } + + ///////////////////////////////////////////////////////////////////////// + // Sort the contents of a list (using member function) + ///////////////////////////////////////////////////////////////////////// + + template + void list_algorithms::sort (container &c) + { + c.sort(); + } +} } } + +#endif // BOOST_PYTHON_INDEXING_LIST_HPP diff --git a/include/boost/python/suite/indexing/map.hpp b/include/boost/python/suite/indexing/map.hpp new file mode 100755 index 00000000..83ee82fb --- /dev/null +++ b/include/boost/python/suite/indexing/map.hpp @@ -0,0 +1,166 @@ +// Header file map.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// Indexing algorithms support for std::map instances +// +// History +// ======= +// 2003/10/28 rmg File creation from algo_selector.hpp +// +// $Id$ +// + +#ifndef BOOST_PYTHON_INDEXING_MAP_HPP +#define BOOST_PYTHON_INDEXING_MAP_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { namespace indexing { + ///////////////////////////////////////////////////////////////////////// + // ContainerTraits implementation for std::map instances + ///////////////////////////////////////////////////////////////////////// + + template + struct map_traits : public default_container_traits + { + typedef typename Container::mapped_type value_type; + 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; + + BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); + BOOST_STATIC_CONSTANT (bool, has_find = true); + BOOST_STATIC_CONSTANT (bool, is_reorderable = false); + // std::map::reference (reference to the mapped type) is mutable, + // so explicitly override the base-class assumption of + // is_reorderable + }; + + ///////////////////////////////////////////////////////////////////////// + // Algorithms implementation for std::map instances + ///////////////////////////////////////////////////////////////////////// + + template + class map_algorithms + : public assoc_algorithms + , Ovr> + ::type> + { + typedef map_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef assoc_algorithms Parent; + + public: + typedef typename Parent::container container; + typedef typename Parent::reference reference; + typedef typename Parent::index_param index_param; + typedef typename Parent::value_param value_param; + + static reference get (container &, index_param); + // Version to return only the mapped type + + static void assign (container &, index_param, value_param); + static void insert (container &, index_param, value_param); + }; + + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::map instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::map Container; + + typedef map_traits mutable_traits; + typedef map_traits const_traits; + + public: + typedef map_algorithms mutable_algorithms; + typedef map_algorithms const_algorithms; + }; + + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::multimap instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::multimap Container; + + typedef map_traits mutable_traits; + typedef map_traits const_traits; + + public: + typedef map_algorithms mutable_algorithms; + typedef map_algorithms const_algorithms; + }; + } + + ///////////////////////////////////////////////////////////////////////// + // Index into a container (map version) + ///////////////////////////////////////////////////////////////////////// + + template + typename map_algorithms::reference + map_algorithms::get (container &c, index_param ix) + { + return most_derived::find_or_throw (c, ix)->second; + } + + ///////////////////////////////////////////////////////////////////////// + // Assign a value at a particular index (map version) + ///////////////////////////////////////////////////////////////////////// + + template + void + map_algorithms::assign ( + container &c, index_param ix, value_param val) + { + c[ix] = val; // Handles overwrite and insert + } + + + ///////////////////////////////////////////////////////////////////////// + // Insert a new key, value pair into a map + ///////////////////////////////////////////////////////////////////////// + + template + void + map_algorithms::insert ( + 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 + + if (!c.insert (pair_type (ix, val)).second) + { + PyErr_SetString ( + PyExc_ValueError, "Map already holds value for insertion"); + + boost::python::throw_error_already_set (); + } + } +} } } + +#endif // BOOST_PYTHON_INDEXING_MAP_HPP diff --git a/include/boost/python/suite/indexing/set.hpp b/include/boost/python/suite/indexing/set.hpp new file mode 100755 index 00000000..270efa83 --- /dev/null +++ b/include/boost/python/suite/indexing/set.hpp @@ -0,0 +1,130 @@ +// Header file set.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// Indexing algorithms support for std::set instances +// +// History +// ======= +// 2003/10/28 rmg File creation from algo_selector.hpp +// +// $Id$ +// + +#ifndef BOOST_PYTHON_INDEXING_SET_HPP +#define BOOST_PYTHON_INDEXING_SET_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { namespace indexing { + ///////////////////////////////////////////////////////////////////////// + // ContainerTraits implementation for std::set instances + ///////////////////////////////////////////////////////////////////////// + + template + struct set_traits : public default_container_traits + { + typedef typename Container::key_type value_type; // probably unused + 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; + + BOOST_STATIC_CONSTANT (index_style_t, index_style = index_style_nonlinear); + BOOST_STATIC_CONSTANT (bool, has_find = true); + BOOST_STATIC_CONSTANT (bool, has_mutable_ref = false); + BOOST_STATIC_CONSTANT (bool, is_reorderable = false); + // Some compilers seem to deduce has_mutable_ref as true from the + // set iterator traits. The previous two constants explicitly hide + // the bad results of that. + }; + + ///////////////////////////////////////////////////////////////////////// + // Algorithms implementation for std::set instances + ///////////////////////////////////////////////////////////////////////// + + template + class set_algorithms + : public assoc_algorithms + , Ovr> + ::type> + { + typedef set_algorithms self_type; + typedef typename detail::maybe_override::type most_derived; + typedef assoc_algorithms Parent; + + public: + typedef typename Parent::container container; + typedef typename Parent::value_param value_param; + typedef typename Parent::index_param index_param; + + static void insert (container &, index_param); + }; + + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::set instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::set Container; + + typedef set_traits mutable_traits; + typedef set_traits const_traits; + + public: + typedef set_algorithms mutable_algorithms; + typedef set_algorithms const_algorithms; + }; + + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::multiset instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::multiset Container; + + typedef set_traits mutable_traits; + typedef set_traits const_traits; + + public: + typedef set_algorithms mutable_algorithms; + typedef set_algorithms const_algorithms; + }; + } + + ///////////////////////////////////////////////////////////////////////// + // Insert an element into a set + ///////////////////////////////////////////////////////////////////////// + + template + void + set_algorithms::insert ( + container &c, index_param ix) + { + if (!c.insert (ix).second) + { + PyErr_SetString ( + PyExc_ValueError, "Set already holds value for insertion"); + + boost::python::throw_error_already_set (); + } + } +} } } + +#endif // BOOST_PYTHON_INDEXING_SET_HPP diff --git a/include/boost/python/suite/indexing/vector.hpp b/include/boost/python/suite/indexing/vector.hpp new file mode 100755 index 00000000..5f933c39 --- /dev/null +++ b/include/boost/python/suite/indexing/vector.hpp @@ -0,0 +1,48 @@ +// Header file vector.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) +// +// Indexing algorithms support for std::vector instances +// +// History +// ======= +// 2003/10/28 rmg File creation from algo_selector.hpp +// +// $Id$ +// + +#ifndef BOOST_PYTHON_INDEXING_VECTOR_HPP +#define BOOST_PYTHON_INDEXING_VECTOR_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { namespace indexing { + namespace detail { + /////////////////////////////////////////////////////////////////////// + // algo_selector support for std::vector instances + /////////////////////////////////////////////////////////////////////// + + template + class selector_impl > + { + typedef std::vector Container; + + typedef default_sequence_traits mutable_traits; + typedef default_sequence_traits const_traits; + + public: + typedef default_algorithms mutable_algorithms; + typedef default_algorithms const_algorithms; + }; + } + +} } } + +#endif // BOOST_PYTHON_INDEXING_VECTOR_HPP diff --git a/include/boost/python/suite/indexing/visitor.hpp b/include/boost/python/suite/indexing/visitor.hpp index 4473ead9..0b00ba6a 100755 --- a/include/boost/python/suite/indexing/visitor.hpp +++ b/include/boost/python/suite/indexing/visitor.hpp @@ -19,6 +19,7 @@ #define BOOST_PYTHON_INDEXING_VISITOR_HPP #include +#include // Get index_style_t #include #include