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

MSVC6 and 7 compatibility fixes

[SVN r20779]
This commit is contained in:
Raoul Gough
2003-11-10 18:06:41 +00:00
parent 997467c29f
commit 91db6f2d50
34 changed files with 773 additions and 284 deletions

View File

@@ -21,9 +21,19 @@
#ifndef BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP
#define BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP
#include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace indexing {
namespace detail {
template<typename Container> class selector_impl;
template<typename Container> class selector_impl
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
{
// Bogus types to prevent compile errors due to ETI
typedef selector_impl<Container> mutable_algorithms;
typedef selector_impl<Container> const_algorithms;
}
#endif
;
// selector_impl specializations should include *two* publically
// accessible typedefs, called mutable_algorithms and
@@ -41,12 +51,14 @@ namespace boost { namespace python { namespace indexing {
{
};
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
// Partial specialization for const containers
template<class Container>
struct algo_selector<Container const>
: public detail::selector_impl<Container>::const_algorithms
{
};
#endif
} } }
#endif // BOOST_PYTHON_INDEXING_ALGO_SELECTOR_HPP

View File

@@ -53,7 +53,8 @@ namespace boost { namespace python { namespace indexing {
class default_algorithms
{
typedef default_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef typename detail::maybe_override<self_type, Ovr>
::type most_derived;
public:
typedef ContainerTraits container_traits;
@@ -93,9 +94,18 @@ namespace boost { namespace python { namespace indexing {
// Default visitor_helper
template<typename PythonClass, typename Policy>
static void visitor_helper (PythonClass &, Policy const &);
static void visitor_helper (PythonClass &pyClass, Policy const &policy)
{
container_traits::visitor_helper (pyClass, policy);
}
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// MSVC6 and 7.0 seem to complain about most_derived::bounds_check
// for an instantiation of list_algorithms.
public:
#else
private:
#endif
static size_type bounds_check (
container &, index_param, char const *msg
, bool one_past = false
@@ -116,12 +126,13 @@ namespace boost { namespace python { namespace indexing {
class assoc_algorithms
: public default_algorithms
<ContainerTraits
, typename detail::maybe_override
, BOOST_DEDUCED_TYPENAME detail::maybe_override
<assoc_algorithms<ContainerTraits, Ovr>, Ovr>
::type>
{
typedef assoc_algorithms<ContainerTraits, Ovr> self_type;
typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
typedef typename detail::maybe_override<self_type, Ovr>
::type most_derived;
typedef default_algorithms<ContainerTraits, most_derived> Parent;
public:
@@ -150,7 +161,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::size_type
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
default_algorithms<ContainerTraits, Ovr>::size (container &c)
{
return c.size();
@@ -161,7 +172,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::size_type
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
default_algorithms<ContainerTraits, Ovr>::bounds_check (
container &c
, index_param ix
@@ -218,7 +229,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::iterator
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::iterator
default_algorithms<ContainerTraits, Ovr>::find (
container &c, key_param key)
{
@@ -230,13 +241,13 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::size_type
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
default_algorithms<ContainerTraits, Ovr>::get_index (
container &c, key_param key)
{
iterator temp (most_derived::find (c, key));
iterator found (most_derived::find (c, key));
if (temp == most_derived::end(c))
if (found == most_derived::end(c))
{
PyErr_SetString (
PyExc_ValueError, "get_index: element not found");
@@ -244,7 +255,8 @@ namespace boost { namespace python { namespace indexing {
boost::python::throw_error_already_set ();
}
return std::distance (most_derived::begin (c), temp);
iterator start (most_derived::begin (c));
return std::distance (start, found);
}
/////////////////////////////////////////////////////////////////////////
@@ -252,7 +264,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::size_type
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
default_algorithms<ContainerTraits, Ovr>::count (
container &c, key_param key)
{
@@ -276,7 +288,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::reference
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::reference
default_algorithms<ContainerTraits, Ovr>::get (
container &c, index_param ix)
{
@@ -387,32 +399,19 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename default_algorithms<ContainerTraits, Ovr>::slice_helper
BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::slice_helper
default_algorithms<ContainerTraits, Ovr>
::make_slice_helper (container &c, slice const &sl)
{
return slice_helper (c, integer_slice (sl, most_derived::size (c)));
}
/////////////////////////////////////////////////////////////////////////
// Visitor helper function (default version)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
template<typename PythonClass, typename Policy>
void
default_algorithms<ContainerTraits, Ovr>
::visitor_helper (PythonClass &pyClass, Policy const &policy)
{
container_traits::visitor_helper (pyClass, policy);
}
/////////////////////////////////////////////////////////////////////////
// Index into a container (associative version)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename assoc_algorithms<ContainerTraits, Ovr>::reference
BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::reference
assoc_algorithms<ContainerTraits, Ovr>::get (container &c, index_param ix)
{
return *most_derived::find_or_throw (c, ix);
@@ -441,7 +440,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename assoc_algorithms<ContainerTraits, Ovr>::iterator
BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::iterator
assoc_algorithms<ContainerTraits, Ovr>
::find (container &c, key_param key)
{
@@ -466,7 +465,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename assoc_algorithms<ContainerTraits, Ovr>::iterator
BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::iterator
assoc_algorithms<ContainerTraits, Ovr>::find_or_throw (
container &c, index_param ix)
{
@@ -488,7 +487,7 @@ namespace boost { namespace python { namespace indexing {
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename assoc_algorithms<ContainerTraits, Ovr>::size_type
BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::size_type
assoc_algorithms<ContainerTraits, Ovr>::count (
container &c, key_param key)
{

View File

@@ -36,6 +36,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
@@ -82,8 +83,11 @@ namespace boost { namespace python { namespace indexing {
typedef typename Container::iterator raw_iterator;
typedef ::boost::detail::iterator_traits<raw_iterator> raw_iterator_traits;
#if !defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class C> friend class shared_proxy_impl;
template<class C> friend class proxy_iterator;
template<class C, typename E, typename T, typename S, typename I>
friend class proxy_iterator;
#endif
public:
typedef typename Holder::held_type held_type;
@@ -101,14 +105,22 @@ namespace boost { namespace python { namespace indexing {
typedef const_element_proxy<self_type> const_value_type;
typedef const_value_type const_reference; // Ref. semantics
typedef proxy_iterator<self_type> iterator;
typedef proxy_iterator<self_type> const_iterator; // ??
typedef proxy_iterator <self_type, value_type, raw_iterator_traits
, size_type, raw_iterator> iterator;
typedef iterator const_iterator; // No const_iterator yet implemented
public:
// Constructors
template<typename Iter> container_proxy (Iter start, Iter finish)
// Define inline for MSVC6 compatibility
: m_held_obj (Holder::create())
, m_proxies ()
{
insert (begin(), start, finish);
}
container_proxy ();
explicit container_proxy (held_type const &h);
template<typename Iter> container_proxy (Iter, Iter);
container_proxy (container_proxy const &);
container_proxy &operator= (container_proxy const &);
@@ -133,7 +145,14 @@ namespace boost { namespace python { namespace indexing {
iterator erase (iterator);
iterator erase (iterator, iterator);
iterator insert (iterator, raw_value_type const &);
template<typename Iter> void insert (iterator, Iter, Iter);
template<typename Iter> void insert (iterator iter, Iter from, Iter to)
// Define here for MSVC6 compatibility
{
// Forward insertion to the right overloaded version
typedef typename BOOST_ITERATOR_CATEGORY<Iter>::type category;
insert (iter, from, to, category());
}
void push_back (raw_value_type const &copy) { insert (end(), copy); }
@@ -163,7 +182,7 @@ namespace boost { namespace python { namespace indexing {
public:
// Convenient replacement of elements (automatic proxy detachment)
void replace (size_type index, raw_value_type const &);
template<typename Iter> void replace (size_type index, Iter, Iter);
// template<typename Iter> void replace (size_type index, Iter, Iter);
void swap_elements (size_type index1, size_type index2);
@@ -172,20 +191,87 @@ namespace boost { namespace python { namespace indexing {
private:
// Overloads for insertions with/without useful std::distance
template<typename Iter>
void insert (iterator, Iter, Iter, std::forward_iterator_tag);
void insert (iterator iter, Iter from, Iter to, std::forward_iterator_tag)
// Define here for MSVC6 compatibility
{
assert (iter.ptr == this);
size_type count = std::distance (from, to);
// Add empty proxy pointers for the new value(s) (could throw)
m_proxies.insert (m_proxies.begin() + iter.index, count, pointer_impl());
try
{
// Insert the new element(s) into the real container (could throw)
raw_container().insert (
raw_container().begin() + iter.index
, from
, to);
try
{
// Create new proxies for the new elements (could throw)
write_proxies (iter.index, iter.index + count);
}
catch (...)
{
raw_container().erase (
raw_container().begin() + iter.index
, raw_container().begin() + iter.index + count);
throw;
}
}
catch (...)
{
m_proxies.erase (
m_proxies.begin() + iter.index
, m_proxies.begin() + iter.index + count);
throw;
}
// Adjust any proxies after the inserted elements (nothrow)
adjust_proxies (
m_proxies.begin() + iter.index + count
, m_proxies.end()
, static_cast<difference_type> (count));
}
template<typename Iter>
void insert (iterator, Iter, Iter, std::input_iterator_tag);
void insert (iterator iter, Iter from, Iter to, std::input_iterator_tag)
// Define here for MSVC6 compatibility
{
// insert overload for iterators where we *can't* get distance()
// so just insert elements one at a time
while (from != to)
{
iter = insert (iter, *from++) + 1;
}
}
private:
typedef boost::shared_ptr<shared_proxy> pointer_impl;
typedef typename Generator::template apply<pointer_impl>::type
pointer_container;
#if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
// Ignore the Generator argument, to avoid an MSVC6 fatal error
// (C1001 internal compiler error).
typedef std::vector<pointer_impl> pointer_container;
#else
typedef typename Generator::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE
apply<pointer_impl>::type pointer_container;
#endif
typedef typename pointer_container::iterator pointer_iterator;
private:
#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
// Proxies need mutable access, and can't be friends with MSVC6
public:
#endif
Container &raw_container();
private:
void adjust_proxies (pointer_iterator, pointer_iterator, difference_type);
void write_proxies (size_type, size_type);
bool clear_proxy (pointer_impl &); // detach and do not reset
@@ -214,6 +300,7 @@ namespace boost { namespace python { namespace indexing {
write_proxies (0, size());
}
/*
template<class Container, class Holder, class Generator>
template<typename Iter>
container_proxy<Container, Holder, Generator>
@@ -223,6 +310,7 @@ namespace boost { namespace python { namespace indexing {
{
insert (begin(), start, finish);
}
*/
template<class Container, class Holder, class Generator>
container_proxy<Container, Holder, Generator>
@@ -238,6 +326,8 @@ namespace boost { namespace python { namespace indexing {
container_proxy<Container, Holder, Generator>
::operator= (container_proxy const &copy)
{
// *FIXME* - provide an exception safety guarantee
// Copy original values into any proxies being shared by external pointers
clear_proxies (0, size());
@@ -282,22 +372,22 @@ namespace boost { namespace python { namespace indexing {
}
template<class Container, class Holder, class Generator>
typename container_proxy<Container, Holder, Generator>::reference
BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::reference
container_proxy<Container, Holder, Generator>
::at (size_type index)
{
pointer_impl const &ptr (m_proxies.BOOST_INDEXING_AT (index));
pointer_impl const &ptr = m_proxies.BOOST_PYTHON_INDEXING_AT (index);
assert (ptr->owner() == this);
assert (ptr->index() == index);
return reference (ptr);
}
template<class Container, class Holder, class Generator>
typename container_proxy<Container, Holder, Generator>::const_reference
BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::const_reference
container_proxy<Container, Holder, Generator>
::at (size_type index) const
{
pointer_impl const &ptr (m_proxies.BOOST_INDEXING_AT (index));
pointer_impl const &ptr (m_proxies.BOOST_PYTHON_INDEXING_AT (index));
assert (ptr->owner() == this);
assert (ptr->index() == index);
return const_reference (ptr);
@@ -309,10 +399,11 @@ namespace boost { namespace python { namespace indexing {
::replace (size_type index, raw_value_type const &copy)
{
detach_proxy (index);
raw_container().BOOST_INDEXING_AT (index) = copy;
raw_container().BOOST_PYTHON_INDEXING_AT (index) = copy;
write_proxies (index, index + 1);
}
/*
template<class Container, class Holder, class Generator>
template<typename Iter>
void
@@ -324,14 +415,15 @@ namespace boost { namespace python { namespace indexing {
replace (index++, *from++);
}
}
*/
template<class Container, class Holder, class Generator>
void
container_proxy<Container, Holder, Generator>
::swap_elements (size_type index1, size_type index2)
{
pointer_impl &ptr1 (m_proxies[index1]);
pointer_impl &ptr2 (m_proxies[index2]);
pointer_impl &ptr1 = m_proxies[index1];
pointer_impl &ptr2 = m_proxies[index2];
assert (ptr1->owner() == this);
assert (ptr2->owner() == this);
@@ -363,14 +455,14 @@ namespace boost { namespace python { namespace indexing {
}
template<class Container, class Holder, class Generator>
typename container_proxy<Container, Holder, Generator>::iterator
BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
container_proxy<Container, Holder, Generator>::erase (iterator iter)
{
return erase (iter, iter + 1);
}
template<class Container, class Holder, class Generator>
typename container_proxy<Container, Holder, Generator>::iterator
BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
container_proxy<Container, Holder, Generator>::erase (
iterator from, iterator to)
{
@@ -389,6 +481,7 @@ namespace boost { namespace python { namespace indexing {
return iterator (this, result);
}
/*
template<class Container, class Holder, class Generator>
template<typename Iter>
void container_proxy<Container, Holder, Generator>::insert (
@@ -440,18 +533,6 @@ namespace boost { namespace python { namespace indexing {
, static_cast<difference_type> (count));
}
template<class Container, class Holder, class Generator>
typename container_proxy<Container, Holder, Generator>::iterator
container_proxy<Container, Holder, Generator>::insert (
iterator iter, raw_value_type const &copy)
{
// Use the iterator-based version by treating the value as an
// array of size one (see section 5.7/4 of the C++98 standard)
insert (iter, &copy, (&copy) + 1, std::random_access_iterator_tag());
return iter;
}
template<class Container, class Holder, class Generator>
template<typename Iter>
void container_proxy<Container, Holder, Generator>::insert (
@@ -474,6 +555,19 @@ namespace boost { namespace python { namespace indexing {
typedef typename BOOST_ITERATOR_CATEGORY<Iter>::type category;
insert (iter, from, to, category());
}
*/
template<class Container, class Holder, class Generator>
BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
container_proxy<Container, Holder, Generator>::insert (
iterator iter, raw_value_type const &copy)
{
// Use the iterator-based version by treating the value as an
// array of size one (see section 5.7/4 of the C++98 standard)
insert (iter, &copy, (&copy) + 1, std::random_access_iterator_tag());
return iter;
}
template<class Container, class Holder, class Generator>
bool container_proxy<Container, Holder, Generator>::clear_proxy (
@@ -514,7 +608,7 @@ namespace boost { namespace python { namespace indexing {
void container_proxy<Container, Holder, Generator>
::detach_proxy (size_type index)
{
pointer_impl &ptr (m_proxies[index]);
pointer_impl &ptr = m_proxies[index];
assert (ptr->index() == index);
@@ -608,7 +702,7 @@ namespace boost { namespace python { namespace indexing {
while (from != to)
{
pointer_impl &ptr (m_proxies[from]);
pointer_impl &ptr = m_proxies[from];
if ((ptr.get() == 0) || (!ptr.unique()))
{
@@ -635,7 +729,7 @@ namespace boost { namespace python { namespace indexing {
for (size_type count = 0; ok && (count < size()); ++count)
{
pointer_impl const &ptr (m_proxies[count]);
pointer_impl const &ptr = m_proxies[count];
ok = ptr.get() && (ptr->owner() == this) && (ptr->index() == count)
&& !ptr->m_element_ptr.get();
@@ -654,19 +748,33 @@ namespace boost { namespace python { namespace indexing {
typedef Container container;
typedef typename container::raw_value_type value_type; // insert, ...
typedef typename container::raw_value_type key_type; // find, count, ...
typedef typename container::reference reference; // return values
typedef typename container::reference reference; // return values
typedef typename boost::call_traits<value_type>::param_type value_param;
typedef typename boost::call_traits<key_type>::param_type key_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
value_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
key_param;
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef value_traits<reference> value_traits_;
#else
typedef element_proxy_traits<Container> value_traits_;
// Forward visitor_helper to eleemnt_proxy_traits
template<typename PythonClass, typename Policy>
static void visitor_helper (PythonClass &pyClass, Policy const &policy)
{
value_traits_::visitor_helper (pyClass, policy);
}
#endif
// Get value_traits for the reference type (i.e. element_proxy)
// to get the custom visitor_helper
};
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::list instances
// algo_selector support for container_proxy instances
///////////////////////////////////////////////////////////////////////
template <typename RawContainer, typename Holder, typename Generator>
@@ -682,6 +790,13 @@ namespace boost { namespace python { namespace indexing {
typedef default_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = container_proxy_traits<Container> >
struct container_proxy_suite
: container_suite<Container, default_algorithms<Traits> >
{
};
} } }
#endif // BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP

View File

@@ -29,7 +29,11 @@ namespace boost { namespace python { namespace indexing {
typedef boost::python::return_value_policy<boost::python::return_by_value>
default_container_policies;
template<class Container, class Algorithms = algo_selector<Container> >
template <
class Container
, class Algorithms
= algo_selector<Container>
>
struct container_suite
: public visitor<Algorithms, default_container_policies>
{

View File

@@ -28,8 +28,25 @@
#include <boost/type_traits.hpp>
#include <boost/call_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/ice.hpp>
#define ICE_AND(a, b) type_traits::ice_and<(a), (b)>::value
namespace boost { namespace python { namespace indexing {
#if BOOST_WORKAROUND (BOOST_MSVC, <= 1200)
// MSVC6 has problems with get_signature if parameter types have
// top-level const qualification (e.g. int const). Unfortunately,
// this is exactly what happens with boost::call_traits, so we
// substitute a really dumb version of it instead.
template<typename T> struct broken_call_traits {
typedef T const & param_type;
};
# define BOOST_PYTHON_INDEXING_CALL_TRAITS broken_call_traits
#else
# define BOOST_PYTHON_INDEXING_CALL_TRAITS ::boost::call_traits
#endif
/////////////////////////////////////////////////////////////////////////
// Lowest common denominator traits - applicable to real containers
// and iterator pairs
@@ -38,19 +55,19 @@ namespace boost { namespace python { namespace indexing {
template<typename Container>
struct base_container_traits
: public ::boost::python::indexing::iterator_traits <
typename mpl::if_ <
BOOST_DEDUCED_TYPENAME mpl::if_ <
is_const<Container>
, typename Container::const_iterator
, typename Container::iterator
, BOOST_DEDUCED_TYPENAME Container::const_iterator
, BOOST_DEDUCED_TYPENAME Container::iterator
>::type
>
{
protected:
typedef ::boost::python::indexing::iterator_traits <
typename mpl::if_ <
BOOST_DEDUCED_TYPENAME mpl::if_ <
is_const<Container>
, typename Container::const_iterator
, typename Container::iterator
, BOOST_DEDUCED_TYPENAME Container::const_iterator
, BOOST_DEDUCED_TYPENAME Container::iterator
>::type
> base_type;
@@ -61,20 +78,23 @@ namespace boost { namespace python { namespace indexing {
typedef Container container;
typedef typename container::size_type size_type;
typedef typename base_type::value_type value_type; // insert, etc.
typedef typename base_type::value_type key_type; // find, count, ...
typedef typename base_type::value_type value_type; // insert
typedef typename base_type::value_type key_type; // find
typedef typename make_signed<size_type>::type index_type;
// at(), operator[]. Signed to support Python -ve indexes
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;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
value_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
key_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <index_type>::param_type
index_param;
typedef value_traits<typename base_type::value_type> value_traits_;
BOOST_STATIC_CONSTANT (bool, has_mutable_ref
= base_type::has_mutable_ref && is_mutable);
= ICE_AND (base_type::has_mutable_ref, is_mutable));
BOOST_STATIC_CONSTANT (bool, has_find
= value_traits_::equality_comparable);
@@ -87,7 +107,10 @@ namespace boost { namespace python { namespace indexing {
// Forward visitor_helper to value_traits_
template<typename PythonClass, typename Policy>
static void visitor_helper (PythonClass &, Policy const &);
static void visitor_helper (PythonClass &pyClass, Policy const &policy)
{
value_traits_::visitor_helper (pyClass, policy);
}
};
/////////////////////////////////////////////////////////////////////////
@@ -117,17 +140,4 @@ namespace boost { namespace python { namespace indexing {
} } }
/////////////////////////////////////////////////////////////////////////
// Visitor helper function (foward to value_traits_ version)
/////////////////////////////////////////////////////////////////////////
template<typename Container>
template<typename PythonClass, typename Policy>
void
boost::python::indexing::base_container_traits<Container>
::visitor_helper (PythonClass &pyClass, Policy const &policy)
{
value_traits_::visitor_helper (pyClass, policy);
}
#endif // BOOST_PYTHON_INDEXING_CONTAINER_SUITE_HPP

View File

@@ -19,11 +19,13 @@
#define BOOST_PYTHON_INDEXING_DEQUE_HPP
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <deque>
namespace boost { namespace python { namespace indexing {
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::deque instances
@@ -42,6 +44,12 @@ namespace boost { namespace python { namespace indexing {
typedef default_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = default_sequence_traits<Container> >
struct deque_suite : container_suite<Container, default_algorithms<Traits> >
{
};
} } }

View File

@@ -1,4 +1,3 @@
//
// Header file element_proxy.hpp
//
// Proxy objects for invidivual elements in a container wrapped by
@@ -28,13 +27,17 @@ namespace boost { namespace python { namespace indexing {
template<typename ContainerProxy>
class element_proxy
{
#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
public:
#else
template<typename T> friend struct const_element_proxy;
#endif
typedef ContainerProxy container_proxy;
typedef typename container_proxy::shared_proxy proxy_type;
typedef ContainerProxy container_proxy_;
typedef typename container_proxy_::shared_proxy proxy_type;
typedef boost::shared_ptr<proxy_type> proxy_pointer;
typedef typename container_proxy::raw_value_type raw_value_type;
typedef typename container_proxy::size_type size_type;
typedef typename container_proxy_::raw_value_type raw_value_type;
typedef typename container_proxy_::size_type size_type;
proxy_pointer m_ptr;
@@ -76,8 +79,8 @@ namespace boost { namespace python { namespace indexing {
element_proxy &operator= (value_type const &copy)
{
proxy_type &proxy (*m_ptr);
container_proxy *container = proxy.owner();
proxy_type &proxy = *m_ptr;
container_proxy_ *container = proxy.owner();
size_type index = proxy.index();
if (container)
@@ -117,10 +120,10 @@ namespace boost { namespace python { namespace indexing {
template<typename ContainerProxy>
struct const_element_proxy
{
typedef ContainerProxy container_proxy;
typedef typename container_proxy::shared_proxy proxy_type;
typedef ContainerProxy container_proxy_;
typedef typename container_proxy_::shared_proxy proxy_type;
typedef boost::shared_ptr<proxy_type> proxy_pointer;
typedef typename container_proxy::raw_value_type raw_value_type;
typedef typename container_proxy_::raw_value_type raw_value_type;
proxy_pointer m_ptr;
@@ -135,7 +138,7 @@ namespace boost { namespace python { namespace indexing {
explicit const_element_proxy (proxy_type *ptr) : m_ptr (ptr) { }
const_element_proxy (proxy_pointer const &ptr) : m_ptr (ptr) { }
const_element_proxy (element_proxy<container_proxy> const &copy)
const_element_proxy (element_proxy<container_proxy_> const &copy)
: m_ptr (copy.m_ptr)
{
}

View File

@@ -23,9 +23,17 @@
#include <boost/python/implicit.hpp>
namespace boost { namespace python { namespace indexing {
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template<typename ContainerProxy>
struct value_traits<element_proxy<ContainerProxy> >
: public value_traits<typename ContainerProxy::raw_value_type>
: public value_traits <
BOOST_DEDUCED_TYPENAME ContainerProxy::raw_value_type>
#else
template<typename ContainerProxy>
struct element_proxy_traits
: public value_traits <
BOOST_DEDUCED_TYPENAME ContainerProxy::raw_value_type>
#endif
{
template<typename PythonClass, typename Policy>
static void visitor_helper (PythonClass &, Policy const &)

View File

@@ -18,7 +18,8 @@
#ifndef BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
#define BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
#include <boost/python/errors.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/suite/indexing/workaround.hpp>
namespace boost { namespace python { namespace indexing {
template<typename Algorithms, typename SliceType>
@@ -117,6 +118,13 @@ namespace boost { namespace python { namespace indexing {
template<bool doit> struct maybe_insert {
template<class Algorithms>
static void apply (
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
// Can't explicitly instantiate member function - must let
// the compiler deduce the argument type from a dummy
// parameter. Same applies throughout
Algorithms *,
# endif
typename Algorithms::container &
, typename Algorithms::index_param
, typename Algorithms::value_param)
@@ -132,6 +140,10 @@ namespace boost { namespace python { namespace indexing {
template<> struct maybe_insert<true> {
template<class Algorithms>
static void apply (
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
Algorithms *,
# endif
typename Algorithms::container &c
, typename Algorithms::index_param i
, typename Algorithms::value_param v)
@@ -155,7 +167,14 @@ namespace boost { namespace python { namespace indexing {
else
{
detail::maybe_insert<container_traits::has_insert>
::template apply<Algorithms> (*m_ptr, m_pos, val);
::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE apply
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
(static_cast<Algorithms *>(0),
# else
<Algorithms> (
# endif
*m_ptr, m_pos, val);
++m_pos; // Advance for any subsequent inserts
}
@@ -165,6 +184,10 @@ namespace boost { namespace python { namespace indexing {
template<bool doit> struct maybe_erase {
template<class Algorithms>
static void apply (
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
Algorithms *,
# endif
typename Algorithms::container &
, typename Algorithms::index_param
, typename Algorithms::index_param)
@@ -179,6 +202,10 @@ namespace boost { namespace python { namespace indexing {
template<> struct maybe_erase<true> {
template<class Algorithms>
static void apply (
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
Algorithms *,
# endif
typename Algorithms::container &c
, typename Algorithms::index_param from
, typename Algorithms::index_param to)
@@ -202,9 +229,17 @@ namespace boost { namespace python { namespace indexing {
else
{
detail::maybe_erase<container_traits::has_erase>
::template apply<Algorithms> (*m_ptr, m_pos, m_slice.stop());
::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE apply
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
(static_cast<Algorithms *>(0),
# else
<Algorithms> (
# endif
*m_ptr, m_pos, m_slice.stop());
}
}
} } }
#endif // BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP

View File

@@ -26,6 +26,7 @@
#include <boost/type_traits.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
@@ -34,7 +35,9 @@ namespace boost { namespace python { namespace indexing {
class iterator_range
{
private:
typedef typename boost::call_traits<Iterator>::param_type iterator_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <Iterator>::param_type
iterator_param;
typedef ::boost::detail::iterator_traits<Iterator> std_traits;
public:
@@ -73,12 +76,26 @@ 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]);
// Array support function(s).
template<typename T> iterator_range<T *> make_iterator_range (T *, T*);
#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1200)
template<typename T, std::size_t N> iterator_range<T *> make_iterator_range (
T (&array)[N]);
template<typename T, std::size_t N> T *begin (T (&array)[N]);
template<typename T, std::size_t N> T *end (T (&array)[N]);
# define BOOST_MAKE_ITERATOR_RANGE \
::boost::python::indexing::make_iterator_range
#else
// For compilers that can't deduce template argument array bounds
# define BOOST_MAKE_ITERATOR_RANGE(array) \
::boost::python::indexing::make_iterator_range ( \
(array), ((array) + sizeof(array) / sizeof((array)[0])))
#endif
template<typename Iterator>
iterator_range<Iterator>::iterator_range (
iterator_param begin, iterator_param end)
@@ -141,6 +158,12 @@ namespace boost { namespace python { namespace indexing {
}
}
template<typename T> iterator_range<T *> make_iterator_range (T *p1, T* p2)
{
return iterator_range<T *> (p1, p2);
}
#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1200)
template<typename T, std::size_t N>
T *begin (T (&array)[N]) {
return array;
@@ -155,7 +178,9 @@ namespace boost { namespace python { namespace indexing {
iterator_range<T *> make_iterator_range (T (&array)[N]) {
return iterator_range<T *>(begin (array), end (array));
}
#endif
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for iterator_range instances
@@ -174,6 +199,13 @@ namespace boost { namespace python { namespace indexing {
typedef default_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = base_container_traits<Container> >
struct iterator_range_suite
: container_suite<Container, default_algorithms<Traits> >
{
};
} } }

View File

@@ -23,6 +23,7 @@
#define BOOST_PYTHON_INDEXING_ITERATOR_TRAITS_HPP
#include <boost/python/suite/indexing/suite_utils.hpp>
#include <boost/python/suite/indexing/workaround.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits.hpp>
@@ -77,7 +78,14 @@ namespace boost { namespace python { namespace indexing {
};
namespace iterator_detail {
template<typename TraversalTag> struct traits_by_category { };
template<typename TraversalTag> struct traits_by_category {
# if defined(BOOST_MPL_MSVC_60_ETI_BUG)
// MSVC6 needs compilable traits in the unspecialized traits_by_category
template<typename Iter> struct traits {
typedef traits<Iter> type;
};
# endif
};
template<>
struct traits_by_category<std::input_iterator_tag> {
@@ -113,7 +121,7 @@ namespace boost { namespace python { namespace indexing {
template<typename Iterator>
class deduced_traits {
typedef BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<
typedef BOOST_DEDUCED_TYPENAME ::boost::BOOST_ITERATOR_CATEGORY<
Iterator>::type category;
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::std_category <
@@ -121,7 +129,7 @@ namespace boost { namespace python { namespace indexing {
public:
typedef typename traits_by_category <max_category>
::template traits<Iterator>::type type;
::BOOST_PYTHON_INDEXING_NESTED_TEMPLATE traits<Iterator>::type type;
};
}

View File

@@ -19,6 +19,7 @@
#define BOOST_PYTHON_INDEXING_LIST_HPP
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <list>
@@ -49,6 +50,7 @@ namespace boost { namespace python { namespace indexing {
// static void sort (container &, PyObject *);
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::list instances
@@ -67,6 +69,12 @@ namespace boost { namespace python { namespace indexing {
typedef list_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = default_sequence_traits<Container> >
struct list_suite : container_suite<Container, list_algorithms<Traits> >
{
};
/////////////////////////////////////////////////////////////////////////
// Reverse the contents of a list (using member function)

View File

@@ -19,8 +19,11 @@
#define BOOST_PYTHON_INDEXING_MAP_HPP
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <boost/detail/workaround.hpp>
#include <map>
namespace boost { namespace python { namespace indexing {
@@ -31,14 +34,22 @@ namespace boost { namespace python { namespace indexing {
template<typename Container>
struct map_traits : public default_container_traits<Container>
{
# if BOOST_WORKAROUND (BOOST_MSVC, <= 1200)
// MSVC6 has a nonstandard name for mapped_type in std::map
typedef typename Container::referent_type value_type;
# else
typedef typename Container::mapped_type value_type;
# endif
typedef value_type & reference;
typedef typename Container::key_type index_type; // operator[]
typedef typename Container::key_type key_type; // find, count, ...
typedef typename boost::call_traits<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;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
value_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
key_param;
typedef typename BOOST_PYTHON_INDEXING_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);
@@ -77,6 +88,7 @@ namespace boost { namespace python { namespace indexing {
static void insert (container &, index_param, value_param);
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::map instances
@@ -112,13 +124,19 @@ namespace boost { namespace python { namespace indexing {
typedef map_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = map_traits<Container> >
struct map_suite : container_suite<Container, map_algorithms<Traits> >
{
};
/////////////////////////////////////////////////////////////////////////
// Index into a container (map version)
/////////////////////////////////////////////////////////////////////////
template<typename ContainerTraits, typename Ovr>
typename map_algorithms<ContainerTraits, Ovr>::reference
BOOST_DEDUCED_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;
@@ -147,8 +165,8 @@ namespace boost { namespace python { namespace indexing {
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>
<BOOST_DEDUCED_TYPENAME self_type::container_traits::index_type
, BOOST_DEDUCED_TYPENAME self_type::container_traits::value_type>
pair_type;
// Can't use std::make_pair, because param types may be references

View File

@@ -18,23 +18,46 @@
#define BOOST_PYTHON_INDEXING_PROXY_ITERATOR_HPP
#include <iterator>
#include <boost/config.hpp>
#include <boost/iterator.hpp>
#include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace indexing {
template<class ContainerProxy>
template <class ContainerProxy, typename ElementProxy, typename Traits
, typename Size, typename Iter>
class proxy_iterator
: public boost::iterator <
std::random_access_iterator_tag
, ElementProxy
, typename Traits::difference_type
, ElementProxy *
, ElementProxy // Already has reference semantics
>
{
#if !defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class C, class H, class G> friend class container_proxy;
#endif
typedef boost::iterator <
std::random_access_iterator_tag
, ElementProxy
, typename Traits::difference_type
, ElementProxy *
, ElementProxy
> base_type;
public:
typedef ContainerProxy container_proxy_;
typedef typename container_proxy_::raw_iterator_traits raw_iterator_traits;
typedef typename raw_iterator_traits::difference_type difference_type;
typedef typename container_proxy_::size_type size_type;
typedef typename container_proxy_::value_type value_type;
typedef typename container_proxy_::raw_iterator raw_iterator;
typedef Iter raw_iterator;
typedef Traits raw_iterator_traits;
typedef Size size_type;
typedef typename base_type::value_type value_type;
typedef typename base_type::difference_type difference_type;
typedef value_type *pointer;
typedef value_type reference; // Already has reference semantics
typedef std::random_access_iterator_tag iterator_category;
typedef value_type reference; // Already has reference semantics
proxy_iterator (container_proxy_ *p, size_type i) : ptr (p), index (i) { }
@@ -90,10 +113,18 @@ namespace boost { namespace python { namespace indexing {
return index < other.index;
}
bool operator<= (proxy_iterator const &other) const {
return index <= other.index;
}
bool operator> (proxy_iterator const &other) const {
return index > other.index;
}
bool operator>= (proxy_iterator const &other) const {
return index >= other.index;
}
void iter_swap (proxy_iterator const &other) const {
ptr->swap_elements (index, other.index);
}
@@ -102,20 +133,28 @@ namespace boost { namespace python { namespace indexing {
// Extensions to the normal iterator interface
// void replace (value_type const &copy) { ptr->replace (index, copy); }
#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
// Can't declare container_proxy as friend, so make data public
public:
#else
private:
#endif
container_proxy_ *ptr;
size_type index;
};
} } }
#if !BOOST_WORKAROUND (BOOST_MSVC, == 1300)
// MSVC7.0 can't decide between this and the unspecialized version
namespace std {
template<class C>
template <class C, typename E, typename T, typename S, typename I>
void iter_swap (
boost::python::indexing::proxy_iterator<C> const &first
, boost::python::indexing::proxy_iterator<C> const &second)
boost::python::indexing::proxy_iterator<C, E, T, S, I> const &first
, boost::python::indexing::proxy_iterator<C, E, T, S, I> const &second)
{
first.iter_swap (second);
}
}
#endif
#endif // BOOST_PYTHON_INDEXING_PROXY_ITERATOR_HPP

View File

@@ -19,6 +19,7 @@
#define BOOST_PYTHON_INDEXING_SET_HPP
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <set>
@@ -35,9 +36,12 @@ namespace boost { namespace python { namespace indexing {
typedef typename Container::key_type index_type; // operator[]
typedef typename Container::key_type key_type; // find, count, ...
typedef typename boost::call_traits<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;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
value_param;
typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
key_param;
typedef typename BOOST_PYTHON_INDEXING_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);
@@ -72,6 +76,7 @@ namespace boost { namespace python { namespace indexing {
static void insert (container &, index_param);
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::set instances
@@ -107,6 +112,12 @@ namespace boost { namespace python { namespace indexing {
typedef set_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = set_traits<Container> >
struct set_suite : container_suite<Container, set_algorithms<Traits> >
{
};
/////////////////////////////////////////////////////////////////////////
// Insert an element into a set

View File

@@ -46,13 +46,16 @@ namespace boost { namespace python { namespace indexing {
shared_proxy_impl (value_type const &copy);
// Creates value-only (detached) proxy
#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
public:
#else
private:
template<class C, class A, class G> friend class container_proxy;
#endif
shared_proxy_impl (ContainerProxy *, size_t);
void detach ();
private:
ContainerProxy *m_owner_ptr; // When attached
size_t m_index; // When attached
std::auto_ptr<value_type> m_element_ptr; // When detached
@@ -85,14 +88,15 @@ namespace boost { namespace python { namespace indexing {
shared_proxy_impl<ContainerProxy>::operator* () const
{
return m_owner_ptr
? m_owner_ptr->raw_container().BOOST_INDEXING_AT (m_index)
? m_owner_ptr->raw_container().BOOST_PYTHON_INDEXING_AT (m_index)
: *m_element_ptr;
}
template<class ContainerProxy>
void shared_proxy_impl<ContainerProxy>::detach ()
{
m_element_ptr.reset (new value_type (**this));
BOOST_PYTHON_INDEXING_RESET_AUTO_PTR (
m_element_ptr, new value_type (**this));
m_owner_ptr = 0;
m_index = static_cast<size_t>(-1);
}

View File

@@ -1,5 +1,3 @@
// -*- mode:c++ -*-
//
// Header file slice.hpp
//
// Copyright (c) 2003 Raoul M. Gough
@@ -29,9 +27,20 @@ namespace boost { namespace python { namespace indexing {
// so that it is possible to register a special converter for
// PySlice_Type and overload C++ functions on slice
slice (slice const &);
#if defined (BOOST_NO_MEMBER_TEMPLATES)
// MSVC6 doesn't seem to be able to invoke the templated
// constructor, so provide explicit overloads to match the
// (currently) known boost::python::object constructors
explicit slice (::boost::python::handle<> const&);
explicit slice (::boost::python::detail::borrowed_reference);
explicit slice (::boost::python::detail::new_reference);
explicit slice (::boost::python::detail::new_non_null_reference);
#else
// Better compilers make life easier
template<typename T> inline slice (T const &ref);
#endif
slice (slice const &); // Copy constructor
};
struct BOOST_PYTHON_DECL integer_slice
@@ -62,6 +71,7 @@ namespace boost { namespace python { namespace indexing {
};
} } }
#if !defined (BOOST_NO_MEMBER_TEMPLATES)
template<typename T>
boost::python::indexing::slice::slice (T const &ref)
: boost::python::object (ref)
@@ -74,6 +84,7 @@ boost::python::indexing::slice::slice (T const &ref)
boost::python::throw_error_already_set();
}
}
#endif
namespace boost { namespace python { namespace converter {
// Specialized converter to handle PySlice_Type objects

View File

@@ -18,6 +18,7 @@
#ifndef BOOST_PYTHON_INDEXING_SLICE_HANDLER_HPP
#define BOOST_PYTHON_INDEXING_SLICE_HANDLER_HPP
#include <boost/python/handle.hpp>
#include <boost/python/object.hpp>
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>
@@ -46,10 +47,13 @@ namespace boost { namespace python { namespace indexing {
static void set_slice (container &, slice, boost::python::object);
static void del_slice (container &, slice);
static void extend (container &, boost::python::object);
};
namespace detail {
template<typename Policy>
struct postcall_override
{
// This class overrides our Policy's postcall function and
// This class overrides the Policy's postcall function and
// result_conveter to handle the list returned from get_slice.
// The Policy's result_converter is removed, since it gets
// applied within get_slice. Our postcall override applies the
@@ -57,7 +61,7 @@ namespace boost { namespace python { namespace indexing {
// from get_slice.
typedef boost::python::default_result_converter result_converter;
typedef typename Policy::argument_package argument_package; // ?
typedef typename Policy::argument_package argument_package;
postcall_override (Policy const &p);
@@ -67,48 +71,6 @@ namespace boost { namespace python { namespace indexing {
private:
Policy m_base;
};
};
//////////////////////////////////////////////////////////////////////////
// postcall_override constructor
//////////////////////////////////////////////////////////////////////////
template<class Algorithms, class Policy>
slice_handler<Algorithms, Policy>
::postcall_override::postcall_override (Policy const &p)
: m_base (p)
{
}
//////////////////////////////////////////////////////////////////////////
// precall forwarder
//////////////////////////////////////////////////////////////////////////
template<class Algorithms, class Policy>
bool
slice_handler<Algorithms, Policy>
::postcall_override::precall (PyObject *args)
{
return m_base.precall (args);
}
//////////////////////////////////////////////////////////////////////////
// Apply base postcall to each element of the list returend by get_slice
//////////////////////////////////////////////////////////////////////////
template<class Algorithms, class Policy>
PyObject *
slice_handler<Algorithms, Policy>
::postcall_override::postcall (PyObject *args, PyObject *result)
{
int size = PyList_Size (result);
for (int count = 0; count < size; ++count)
{
m_base.postcall (args, PyList_GetItem (result, count));
}
return result;
}
//////////////////////////////////////////////////////////////////////////
@@ -121,7 +83,8 @@ namespace boost { namespace python { namespace indexing {
::make_getitem (Policy const &policy)
{
return
boost::python::make_function (get_slice, postcall_override (policy));
boost::python::make_function (
get_slice, detail::postcall_override<Policy> (policy));
}
//////////////////////////////////////////////////////////////////////////
@@ -163,6 +126,46 @@ namespace boost { namespace python { namespace indexing {
return boost::python::make_function (extend, policy);
}
namespace detail {
////////////////////////////////////////////////////////////////////////
// postcall_override constructor
////////////////////////////////////////////////////////////////////////
template<class Policy>
postcall_override<Policy>::postcall_override (Policy const &p)
: m_base (p)
{
}
////////////////////////////////////////////////////////////////////////
// precall forwarder
////////////////////////////////////////////////////////////////////////
template<class Policy>
bool postcall_override<Policy>::precall (PyObject *args)
{
return m_base.precall (args);
}
////////////////////////////////////////////////////////////////////////
// Apply base postcall to each element of the list returend by get_slice
////////////////////////////////////////////////////////////////////////
template<class Policy>
PyObject *
postcall_override<Policy>::postcall (PyObject *args, PyObject *result)
{
int size = PyList_Size (result);
for (int count = 0; count < size; ++count)
{
m_base.postcall (args, PyList_GetItem (result, count));
}
return result;
}
} // namespace detail
//////////////////////////////////////////////////////////////////////////
// Implementation for the slice version of __getitem__
//////////////////////////////////////////////////////////////////////////
@@ -174,7 +177,9 @@ namespace boost { namespace python { namespace indexing {
{
typedef typename Policy::result_converter converter_type;
typedef typename Algorithms::reference reference;
typename boost::mpl::apply1<converter_type, reference>::type converter;
typename boost::mpl::apply1<converter_type, reference>::type
converter;
boost::python::list result;
@@ -214,11 +219,11 @@ namespace boost { namespace python { namespace indexing {
// a reference to existing object, if possible and sensible) and the
// second allowing implicit conversions.
typedef boost::python::extract<typename Algorithms::value_param>
extractor1;
typedef boost::python::extract <
BOOST_DEDUCED_TYPENAME Algorithms::value_param> extractor1;
typedef boost::python::extract<typename Algorithms::value_type>
extractor2;
typedef boost::python::extract <
BOOST_DEDUCED_TYPENAME Algorithms::value_type> extractor2;
// Note: any error during this operation will probably leave the
// container partially updated. This can occur (for example) if the

View File

@@ -45,7 +45,7 @@ namespace boost { namespace python { namespace indexing {
typedef typename boost::remove_reference<T>::type maybe_const;
public:
static bool const value = ! boost::is_const<maybe_const>::value;
BOOST_STATIC_CONSTANT (bool, value = !boost::is_const<maybe_const>::value);
};
// make_signed attempts to identify the signed version of any

View File

@@ -21,13 +21,15 @@
#ifndef BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP
#define BOOST_PYTHON_INDEXING_VALUE_TRAITS_HPP
#include <boost/config.hpp>
namespace boost { namespace python { namespace indexing {
template<typename T>
struct value_traits {
static bool const equality_comparable = true;
BOOST_STATIC_CONSTANT (bool, equality_comparable = true);
// Meaning from C++98 standard section 20.1.1
static bool const lessthan_comparable = true;
BOOST_STATIC_CONSTANT (bool, lessthan_comparable = true);
// static bool const has_less = true;
// etc...

View File

@@ -19,11 +19,13 @@
#define BOOST_PYTHON_INDEXING_VECTOR_HPP
#include <boost/python/suite/indexing/container_traits.hpp>
#include <boost/python/suite/indexing/container_suite.hpp>
#include <boost/python/suite/indexing/algorithms.hpp>
#include <boost/python/suite/indexing/algo_selector.hpp>
#include <vector>
namespace boost { namespace python { namespace indexing {
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
///////////////////////////////////////////////////////////////////////
// algo_selector support for std::vector instances
@@ -42,6 +44,12 @@ namespace boost { namespace python { namespace indexing {
typedef default_algorithms<const_traits> const_algorithms;
};
}
#endif
template<class Container, class Traits = default_sequence_traits<Container> >
struct vector_suite : container_suite<Container, default_algorithms<Traits> >
{
};
} } }

View File

@@ -1,5 +1,3 @@
// -*- mode:c++ -*-
//
// Header file visitor.hpp
//
// Copyright (c) 2003 Raoul M. Gough
@@ -23,6 +21,7 @@
#include <boost/python/def_visitor.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/default_call_policies.hpp>
#include <boost/type_traits/ice.hpp>
#include <boost/bind.hpp>
#include <functional>
@@ -228,11 +227,12 @@ namespace boost { namespace python { namespace indexing {
static void apply (
PythonClass &pyClass
, Algorithms const &
, Policy const &policy)
, Policy const &)
{
// *FIXME* seperate precall and postcall portions of the
// Should maybe separate precall and postcall portions of the
// policy (precall when generating the range object, postcall
// when returing from range.next())
// when returing from range.next())?
pyClass.def (
"__iter__"
, boost::python::range<Policy> (

View File

@@ -1,5 +1,3 @@
// -*- mode:c++ -*-
//
// Header file workaround.hpp
//
// Indexing-specific workarounds for compiler problems.
@@ -20,14 +18,35 @@
#ifndef BOOST_PYTHON_INDEXING_WORKAROUND_HPP
#define BOOST_PYTHON_INDEXING_WORKAROUND_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
# if (BOOST_WORKAROUND (__GNUC__, < 3))
# // gcc versions before 3 (like 2.95.3) don't have the "at" member
# // function in std::vector or std::deque
# define BOOST_INDEXING_AT operator[]
# define BOOST_PYTHON_INDEXING_AT operator[]
# else
# define BOOST_INDEXING_AT at
# define BOOST_PYTHON_INDEXING_AT at
# endif
# if BOOST_WORKAROUND (BOOST_MSVC, <= 1300)
// visualc.hpp never seems to define BOOST_NO_MEMBER_TEMPLATE_KEYWORD
// so BOOST_NESTED_TEMPLATE ends up expanding to "template" instead of
// being empty. This causes some compile errors with MSVC[67]
# define BOOST_PYTHON_INDEXING_NESTED_TEMPLATE
// Workaround the lack of a reset member function in std::auto_ptr
namespace boost { namespace python { namespace indexing {
template<typename T> void reset_auto_ptr (T &aptr, T::element_type *pptr) {
aptr = T (pptr);
}
} } }
# define BOOST_PYTHON_INDEXING_RESET_AUTO_PTR \
::boost::python::indexing::reset_auto_ptr
# else
# define BOOST_PYTHON_INDEXING_NESTED_TEMPLATE BOOST_NESTED_TEMPLATE
# define BOOST_PYTHON_INDEXING_RESET_AUTO_PTR( aptr, pptr ) \
(aptr).reset(pptr)
# endif
#endif // BOOST_PYTHON_INDEXING_WORKAROUND_HPP