2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-28 07:22:31 +00:00

Container-specific traits and algorithms moved into separate headers

[SVN r20524]
This commit is contained in:
Raoul Gough
2003-10-28 15:22:15 +00:00
parent 5e6f06fde3
commit f415f18574
12 changed files with 587 additions and 430 deletions

View File

@@ -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 <boost/python/suite/indexing/container_proxy.hpp>
// Include this early to ensure the declaration of the get_pointer
// overload for element_proxy is in-scope for both name-lookup phases
#include <boost/python/suite/indexing/element_proxy_traits.hpp>
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
// Definitions of further supported types
#include <boost/python/suite/indexing/iterator_range.hpp>
#include <set>
#include <map>
#include <list>
#include <deque>
#include <vector>
namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
// Automated algorithm and trait selection
/////////////////////////////////////////////////////////////////////////
namespace detail {
template<typename Container> 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 Key, class Compare, class Allocator>
class selector_impl<std::set<Key, Compare, Allocator> >
{
typedef std::set<Key, Compare, Allocator> Container;
typedef set_traits<Container> mutable_traits;
typedef set_traits<Container const> const_traits;
public:
typedef set_algorithms<mutable_traits> mutable_algorithms;
typedef set_algorithms<const_traits> const_algorithms;
};
// std::multiset
template <class Key, class Compare, class Allocator>
class selector_impl<std::multiset<Key, Compare, Allocator> >
{
typedef std::multiset<Key, Compare, Allocator> Container;
typedef set_traits<Container> mutable_traits;
typedef set_traits<Container const> const_traits;
public:
typedef set_algorithms<mutable_traits> mutable_algorithms;
typedef set_algorithms<const_traits> const_algorithms;
};
// std::map
template <class Key, class T, class Compare, class Allocator>
class selector_impl<std::map<Key, T, Compare, Allocator> >
{
typedef std::map<Key, T, Compare, Allocator> Container;
typedef map_traits<Container> mutable_traits;
typedef map_traits<Container const> const_traits;
public:
typedef map_algorithms<mutable_traits> mutable_algorithms;
typedef map_algorithms<const_traits> const_algorithms;
};
// std::multimap
template <class Key, class T, class Compare, class Allocator>
class selector_impl<std::multimap<Key, T, Compare, Allocator> >
{
typedef std::multimap<Key, T, Compare, Allocator> Container;
typedef map_traits<Container> mutable_traits;
typedef map_traits<Container const> const_traits;
public:
typedef map_algorithms<mutable_traits> mutable_algorithms;
typedef map_algorithms<const_traits> const_algorithms;
};
// std::vector
template <class T, class Allocator>
class selector_impl<std::vector<T, Allocator> >
{
typedef std::vector<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
// std::deque
template <class T, class Allocator>
class selector_impl<std::deque<T, Allocator> >
{
typedef std::deque<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
// std::list
template <class T, class Allocator>
class selector_impl<std::list<T, Allocator> >
{
typedef std::list<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef list_algorithms<mutable_traits> mutable_algorithms;
typedef list_algorithms<const_traits> const_algorithms;
};
// Iterator ranges
template <typename Iterator>
class selector_impl<iterator_range<Iterator> >
{
typedef iterator_range<Iterator> Container;
typedef iterator_range_traits<Container> mutable_traits;
typedef iterator_range_traits<Container const> const_traits; // ?
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
// Container proxies
template <typename RawContainer, typename Holder, typename Generator>
class selector_impl<container_proxy<RawContainer, Holder, Generator> >
{
typedef container_proxy<RawContainer, Holder, Generator> Container;
typedef container_proxy_traits<Container> mutable_traits;
typedef container_proxy_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> 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<class Container>

View File

@@ -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<typename ContainerTraits, typename Ovr = detail::no_override>
class list_algorithms
: public default_algorithms
<ContainerTraits
, typename detail::maybe_override
<list_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef list_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef default_algorithms<ContainerTraits, most_derived> 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<typename ContainerTraits, typename Ovr = detail::no_override>
class set_algorithms
: public assoc_algorithms
<ContainerTraits
, typename detail::maybe_override
<set_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef set_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef assoc_algorithms<ContainerTraits, most_derived> 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<typename ContainerTraits, typename Ovr = detail::no_override>
class map_algorithms
: public assoc_algorithms
<ContainerTraits
, typename detail::maybe_override
<map_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef map_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef assoc_algorithms<ContainerTraits, most_derived> 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<typename ContainerTraits, typename Ovr>
void list_algorithms<ContainerTraits, Ovr>::reverse (container &c)
{
c.reverse();
}
/////////////////////////////////////////////////////////////////////////
// Sort the contents of a container (std algorithm version)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
void list_algorithms<ContainerTraits, Ovr>::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 ContainerTraits, typename Ovr>
typename map_algorithms<ContainerTraits, Ovr>::reference
map_algorithms<ContainerTraits, Ovr>::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<typename ContainerTraits, typename Ovr>
void
set_algorithms<ContainerTraits, Ovr>::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<typename ContainerTraits, typename Ovr>
void
map_algorithms<ContainerTraits, Ovr>::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<typename ContainerTraits, typename Ovr>
void
map_algorithms<ContainerTraits, Ovr>::insert (
container &c, index_param ix, value_param val)
{
typedef std::pair
<typename self_type::container_traits::index_type
, typename self_type::container_traits::value_type>
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
/////////////////////////////////////////////////////////////////////////

View File

@@ -29,12 +29,16 @@
#include <boost/python/suite/indexing/proxy_iterator.hpp>
#include <boost/python/suite/indexing/shared_proxy_impl.hpp>
#include <boost/python/suite/indexing/element_proxy.hpp>
#include <boost/python/suite/indexing/element_proxy_traits.hpp>
#include <boost/python/suite/indexing/workaround.hpp>
#include <vector>
#include <vector> // Default pointer container
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
namespace boost { namespace python { namespace indexing {
template<typename T> struct identity {
@@ -641,6 +645,44 @@ namespace boost { namespace python { namespace indexing {
return ok;
}
/////////////////////////////////////////////////////////////////////////
// ContainerTraits implementation for container_proxy instances
/////////////////////////////////////////////////////////////////////////
template<typename Container>
struct container_proxy_traits : public default_sequence_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef value_traits<reference> 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 <typename RawContainer, typename Holder, typename Generator>
class selector_impl<container_proxy<RawContainer, Holder, Generator> >
{
typedef container_proxy<RawContainer, Holder, Generator> Container;
typedef container_proxy_traits<Container> mutable_traits;
typedef container_proxy_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
}
} } }
#endif // BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP

View File

@@ -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<typename base_type::value_type> 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<typename PythonClass, typename Policy>
static void visitor_helper (PythonClass &, Policy const &);
};
/////////////////////////////////////////////////////////////////////////
// Traits for the iterator_range container emulator
/////////////////////////////////////////////////////////////////////////
template<typename IteratorRange>
struct iterator_range_traits : public base_container_traits<IteratorRange>
{
};
/////////////////////////////////////////////////////////////////////////
// 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<Container>
{
typedef default_container_traits<Container> 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<Container>
{
typedef default_sequence_traits<Container> 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<typename Container>
struct container_proxy_traits : public default_sequence_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef value_traits<reference> 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<typename Container>
struct set_traits : public default_container_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef typename boost::call_traits<index_type>::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<typename Container>
struct map_traits : public default_container_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef typename boost::call_traits<index_type>::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
};
} } }
/////////////////////////////////////////////////////////////////////////

View File

@@ -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 <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <deque>
namespace boost { namespace python { namespace indexing {
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::deque instances
///////////////////////////////////////////////////////////////////////
template <class T, class Allocator>
class selector_impl<std::deque<T, Allocator> >
{
typedef std::deque<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
}
} } }
#endif // BOOST_PYTHON_INDEXING_DEQUE_HPP

View File

@@ -25,6 +25,9 @@
#include <utility>
#include <boost/type_traits.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
namespace boost { namespace python { namespace indexing {
template<typename Iterator>
@@ -70,6 +73,12 @@ namespace boost { namespace python { namespace indexing {
iterator m_end;
};
// Array support functions
template<typename T, std::size_t N> T *begin (T (&array)[N]);
template<typename T, std::size_t N> T *end (T (&array)[N]);
template<typename T, std::size_t N> iterator_range<T *> make_iterator_range (
T (&array)[N]);
template<typename Iterator>
iterator_range<Iterator>::iterator_range (
iterator_param begin, iterator_param end)
@@ -133,14 +142,39 @@ namespace boost { namespace python { namespace indexing {
}
template<typename T, std::size_t N>
T *begin (T(&array)[N]) {
T *begin (T (&array)[N]) {
return array;
}
template<typename T, std::size_t N>
T *end (T(&array)[N]) {
T *end (T (&array)[N]) {
return array + N;
}
template<typename T, std::size_t N>
iterator_range<T *> make_iterator_range (T (&array)[N]) {
return iterator_range<T *>(begin (array), end (array));
}
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for iterator_range instances
///////////////////////////////////////////////////////////////////////
template <typename Iterator>
class selector_impl<iterator_range<Iterator> >
{
typedef iterator_range<Iterator> Container;
typedef base_container_traits<Container> mutable_traits;
typedef base_container_traits<Container const> const_traits; // ?
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
}
} } }
#endif // BOOST_PYTHON_INDEXING_ITERATOR_RANGE_HPP

View File

@@ -30,24 +30,6 @@
#include <boost/iterator/iterator_categories.hpp>
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
//////////////////////////////////////////////////////////////////////////

View File

@@ -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 <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <list>
namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
// Algorithms implementation for std::list instances
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr = detail::no_override>
class list_algorithms
: public default_algorithms
<ContainerTraits
, typename detail::maybe_override
<list_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef list_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef default_algorithms<ContainerTraits, most_derived> 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 T, class Allocator>
class selector_impl<std::list<T, Allocator> >
{
typedef std::list<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef list_algorithms<mutable_traits> mutable_algorithms;
typedef list_algorithms<const_traits> const_algorithms;
};
}
/////////////////////////////////////////////////////////////////////////
// Reverse the contents of a list (using member function)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
void list_algorithms<ContainerTraits, Ovr>::reverse (container &c)
{
c.reverse();
}
/////////////////////////////////////////////////////////////////////////
// Sort the contents of a list (using member function)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
void list_algorithms<ContainerTraits, Ovr>::sort (container &c)
{
c.sort();
}
} } }
#endif // BOOST_PYTHON_INDEXING_LIST_HPP

View File

@@ -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 <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <map>
namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
// ContainerTraits implementation for std::map instances
/////////////////////////////////////////////////////////////////////////
template<typename Container>
struct map_traits : public default_container_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef typename boost::call_traits<index_type>::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<typename ContainerTraits, typename Ovr = detail::no_override>
class map_algorithms
: public assoc_algorithms
<ContainerTraits
, typename detail::maybe_override
<map_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef map_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef assoc_algorithms<ContainerTraits, most_derived> 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 Key, class T, class Compare, class Allocator>
class selector_impl<std::map<Key, T, Compare, Allocator> >
{
typedef std::map<Key, T, Compare, Allocator> Container;
typedef map_traits<Container> mutable_traits;
typedef map_traits<Container const> const_traits;
public:
typedef map_algorithms<mutable_traits> mutable_algorithms;
typedef map_algorithms<const_traits> const_algorithms;
};
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::multimap instances
///////////////////////////////////////////////////////////////////////
template <class Key, class T, class Compare, class Allocator>
class selector_impl<std::multimap<Key, T, Compare, Allocator> >
{
typedef std::multimap<Key, T, Compare, Allocator> Container;
typedef map_traits<Container> mutable_traits;
typedef map_traits<Container const> const_traits;
public:
typedef map_algorithms<mutable_traits> mutable_algorithms;
typedef map_algorithms<const_traits> const_algorithms;
};
}
/////////////////////////////////////////////////////////////////////////
// Index into a container (map version)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename map_algorithms<ContainerTraits, Ovr>::reference
map_algorithms<ContainerTraits, Ovr>::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<typename ContainerTraits, typename Ovr>
void
map_algorithms<ContainerTraits, Ovr>::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<typename ContainerTraits, typename Ovr>
void
map_algorithms<ContainerTraits, Ovr>::insert (
container &c, index_param ix, value_param val)
{
typedef std::pair
<typename self_type::container_traits::index_type
, typename self_type::container_traits::value_type>
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

View File

@@ -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 <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <set>
namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
// ContainerTraits implementation for std::set instances
/////////////////////////////////////////////////////////////////////////
template<typename Container>
struct set_traits : public default_container_traits<Container>
{
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<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef typename boost::call_traits<index_type>::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<typename ContainerTraits, typename Ovr = detail::no_override>
class set_algorithms
: public assoc_algorithms
<ContainerTraits
, typename detail::maybe_override
<set_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef set_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef assoc_algorithms<ContainerTraits, most_derived> 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 Key, class Compare, class Allocator>
class selector_impl<std::set<Key, Compare, Allocator> >
{
typedef std::set<Key, Compare, Allocator> Container;
typedef set_traits<Container> mutable_traits;
typedef set_traits<Container const> const_traits;
public:
typedef set_algorithms<mutable_traits> mutable_algorithms;
typedef set_algorithms<const_traits> const_algorithms;
};
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::multiset instances
///////////////////////////////////////////////////////////////////////
template <class Key, class Compare, class Allocator>
class selector_impl<std::multiset<Key, Compare, Allocator> >
{
typedef std::multiset<Key, Compare, Allocator> Container;
typedef set_traits<Container> mutable_traits;
typedef set_traits<Container const> const_traits;
public:
typedef set_algorithms<mutable_traits> mutable_algorithms;
typedef set_algorithms<const_traits> const_algorithms;
};
}
/////////////////////////////////////////////////////////////////////////
// Insert an element into a set
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
void
set_algorithms<ContainerTraits, Ovr>::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

View File

@@ -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 <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <vector>
namespace boost { namespace python { namespace indexing {
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::vector instances
///////////////////////////////////////////////////////////////////////
template <class T, class Allocator>
class selector_impl<std::vector<T, Allocator> >
{
typedef std::vector<T, Allocator> Container;
typedef default_sequence_traits<Container> mutable_traits;
typedef default_sequence_traits<Container const> const_traits;
public:
typedef default_algorithms<mutable_traits> mutable_algorithms;
typedef default_algorithms<const_traits> const_algorithms;
};
}
} } }
#endif // BOOST_PYTHON_INDEXING_VECTOR_HPP

View File

@@ -19,6 +19,7 @@
#define BOOST_PYTHON_INDEXING_VISITOR_HPP
#include <boost/python/suite/indexing/slice_handler.hpp>
#include <boost/python/suite/indexing/suite_utils.hpp> // Get index_style_t
#include <boost/python/def_visitor.hpp>
#include <boost/python/iterator.hpp>