mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 18:12:43 +00:00
MSVC6 and 7 compatibility fixes
[SVN r20779]
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 ©) { 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 ©)
|
||||
{
|
||||
// *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 ©)
|
||||
{
|
||||
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 ©)
|
||||
{
|
||||
// Use the iterator-based version by treating the value as an
|
||||
// array of size one (see section 5.7/4 of the C++98 standard)
|
||||
insert (iter, ©, (©) + 1, std::random_access_iterator_tag());
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
template<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 ©)
|
||||
{
|
||||
// Use the iterator-based version by treating the value as an
|
||||
// array of size one (see section 5.7/4 of the C++98 standard)
|
||||
insert (iter, ©, (©) + 1, std::random_access_iterator_tag());
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
template<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
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> >
|
||||
{
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
|
||||
@@ -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 ©)
|
||||
{
|
||||
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 ©)
|
||||
const_element_proxy (element_proxy<container_proxy_> const ©)
|
||||
: m_ptr (copy.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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 &)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> >
|
||||
{
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ©) { 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,13 +46,16 @@ namespace boost { namespace python { namespace indexing {
|
||||
shared_proxy_impl (value_type const ©);
|
||||
// Creates value-only (detached) proxy
|
||||
|
||||
#if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
template<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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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...
|
||||
|
||||
@@ -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> >
|
||||
{
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
|
||||
@@ -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> (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
//
|
||||
|
||||
#include <boost/python/suite/indexing/python_iterator.hpp>
|
||||
#include <boost/python/suite/indexing/workaround.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// python_iterator factory
|
||||
@@ -24,11 +25,13 @@
|
||||
std::auto_ptr<boost::python::indexing::python_iterator>
|
||||
boost::python::indexing::make_iterator (boost::python::object temp)
|
||||
{
|
||||
std::auto_ptr<python_iterator> result;
|
||||
typedef std::auto_ptr<python_iterator> ptr_type;
|
||||
ptr_type result;
|
||||
|
||||
try
|
||||
{
|
||||
result.reset (new python_iter_iterator (temp));
|
||||
BOOST_PYTHON_INDEXING_RESET_AUTO_PTR (
|
||||
result, (python_iterator *) new python_iter_iterator (temp));
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
@@ -37,7 +40,8 @@ boost::python::indexing::make_iterator (boost::python::object temp)
|
||||
|
||||
try
|
||||
{
|
||||
result.reset (new python_getitem_iterator (temp));
|
||||
BOOST_PYTHON_INDEXING_RESET_AUTO_PTR (
|
||||
result, (python_iterator *) new python_getitem_iterator (temp));
|
||||
}
|
||||
|
||||
catch (boost::python::error_already_set const &)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// -*- mode:c++ -*-
|
||||
//
|
||||
// Module slice.cpp
|
||||
//
|
||||
// Copyright (c) 2003 Raoul M. Gough
|
||||
@@ -18,6 +16,19 @@
|
||||
#include <boost/python/suite/indexing/slice.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// MSVC6 workarounds
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined (BOOST_NO_MEMBER_TEMPLATES)
|
||||
namespace boost { namespace python { namespace indexing {
|
||||
slice::slice (::boost::python::handle<> const &p) : object (p) { }
|
||||
slice::slice (::boost::python::detail::borrowed_reference p) : object (p) { }
|
||||
slice::slice (::boost::python::detail::new_reference p) : object (p) { }
|
||||
slice::slice (::boost::python::detail::new_non_null_reference p) : object (p) { }
|
||||
} } }
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// slice copy constructor
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
struct int_wrapper {
|
||||
static bool our_trace_flag;
|
||||
@@ -42,6 +43,8 @@ struct int_wrapper {
|
||||
inline static void setTrace (bool onoff);
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC (int_wrapper)
|
||||
|
||||
inline bool operator== (int_wrapper const &lhs, int_wrapper const &rhs);
|
||||
inline bool operator!= (int_wrapper const &lhs, int_wrapper const &rhs);
|
||||
inline bool operator< (int_wrapper const &lhs, int_wrapper const &rhs);
|
||||
|
||||
@@ -30,7 +30,7 @@ boost::python::indexing::iterator_range<int *> get_array_plain()
|
||||
{
|
||||
static int array[] = { 8, 6, 4, 2, 1, 3, 5, 7, 0 };
|
||||
|
||||
return boost::python::indexing::make_iterator_range (array);
|
||||
return BOOST_MAKE_ITERATOR_RANGE (array);
|
||||
}
|
||||
|
||||
boost::python::indexing::iterator_range<int_wrapper *> get_array_wrap()
|
||||
@@ -40,11 +40,13 @@ boost::python::indexing::iterator_range<int_wrapper *> get_array_wrap()
|
||||
, int_wrapper(1), int_wrapper(3), int_wrapper(5)
|
||||
, int_wrapper(7), int_wrapper(0) };
|
||||
|
||||
return boost::python::indexing::make_iterator_range (array);
|
||||
return BOOST_MAKE_ITERATOR_RANGE (array);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(test_array_ext)
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
boost::python::implicitly_convertible <int, int_wrapper>();
|
||||
|
||||
boost::python::def ("setTrace", &int_wrapper::setTrace);
|
||||
@@ -55,15 +57,23 @@ BOOST_PYTHON_MODULE(test_array_ext)
|
||||
.def ("__cmp__", compare)
|
||||
;
|
||||
|
||||
typedef boost::python::indexing::iterator_range<int *> Container1;
|
||||
typedef indexing::iterator_range<int *> Container1;
|
||||
typedef indexing::iterator_range<int_wrapper *> Container2;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
typedef indexing::container_suite<Container2> Suite2;
|
||||
#else
|
||||
typedef indexing::iterator_range_suite<Container1> Suite1;
|
||||
typedef indexing::iterator_range_suite<Container2> Suite2;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>
|
||||
("Array", boost::python::init<int *, int *>())
|
||||
.def (boost::python::indexing::container_suite<Container1>());
|
||||
.def (Suite1());
|
||||
|
||||
boost::python::def ("get_array_plain", get_array_plain);
|
||||
|
||||
typedef boost::python::indexing::iterator_range<int_wrapper *> Container2;
|
||||
|
||||
// reference_existing_object is safe in this case, because the array
|
||||
// is static, and we never manually destroy any array elements. There
|
||||
@@ -72,9 +82,9 @@ BOOST_PYTHON_MODULE(test_array_ext)
|
||||
// lifetimes of the array elements.
|
||||
boost::python::class_<Container2>
|
||||
("Array_ref", boost::python::init<int_wrapper *, int_wrapper *>())
|
||||
.def (boost::python::indexing::container_suite<Container2>
|
||||
::with_policies(boost::python::return_value_policy
|
||||
<boost::python::reference_existing_object>()));
|
||||
.def (Suite2::with_policies (
|
||||
boost::python::return_value_policy <
|
||||
boost::python::reference_existing_object>()));
|
||||
|
||||
boost::python::def ("get_array_wrap", get_array_wrap);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
// $Id$
|
||||
//
|
||||
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
#include <boost/python/suite/indexing/container_proxy.hpp>
|
||||
#include <boost/python/suite/indexing/workaround.hpp>
|
||||
#include <boost/test/minimal.hpp>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
@@ -27,6 +29,21 @@
|
||||
bool int_wrapper::our_trace_flag = true;
|
||||
unsigned int_wrapper::our_object_counter = 0;
|
||||
|
||||
#if !BOOST_WORKAROUND (BOOST_MSVC, <= 1300)
|
||||
// Works with element_proxy instances because of the reference
|
||||
// conversion operator
|
||||
static void increment (int_wrapper &int_wrap, int val) {
|
||||
int_wrap.increment (val);
|
||||
}
|
||||
#else
|
||||
// The implicit conversion provided by element_proxy doesn't work
|
||||
// with MSVC[67]. Instead use the element_proxy operator->
|
||||
template<typename T>
|
||||
static void increment (T const &proxy, int val) {
|
||||
proxy->increment (val);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename ProxyContainer>
|
||||
void initial_tests (ProxyContainer &proxy_container)
|
||||
{
|
||||
@@ -60,7 +77,7 @@ void initial_tests (ProxyContainer &proxy_container)
|
||||
BOOST_CHECK (proxy_container.is_valid());
|
||||
|
||||
BOOST_CHECK (ref0.use_count() == 2);
|
||||
((int_wrapper &) proxy_container[0]).increment (2);
|
||||
increment (proxy_container[0], 2);
|
||||
BOOST_CHECK (ref0 == int_wrapper (3));
|
||||
BOOST_CHECK (proxy_container[0] == int_wrapper (3));
|
||||
|
||||
@@ -97,14 +114,15 @@ void test_direct_proxy ()
|
||||
|
||||
reference ref0 ((*proxy_auto_p)[0]);
|
||||
reference refn ((*proxy_auto_p)[proxy_auto_p->size() - 1]);
|
||||
static_cast<int_wrapper &>(ref0).increment (5);
|
||||
static_cast<int_wrapper &>(refn).increment (10);
|
||||
increment (ref0, 5);
|
||||
increment (refn, 10);
|
||||
BOOST_CHECK (ref0 == int_wrapper (5));
|
||||
BOOST_CHECK (refn == int_wrapper (10));
|
||||
BOOST_CHECK (ref0.use_count() == 2);
|
||||
BOOST_CHECK (refn.use_count() == 2);
|
||||
|
||||
proxy_auto_p.reset(); // Invoke container_proxy destructor
|
||||
// Invoke container_proxy destructor
|
||||
BOOST_PYTHON_INDEXING_RESET_AUTO_PTR (proxy_auto_p, 0);
|
||||
|
||||
BOOST_CHECK (ref0.use_count() == 1); // Detached
|
||||
BOOST_CHECK (refn.use_count() == 1); // Detached
|
||||
@@ -121,8 +139,7 @@ void test_direct_proxy ()
|
||||
BOOST_CHECK (proxy_container.size() == raw_container.size());
|
||||
|
||||
reference ref1 (proxy_container[1]);
|
||||
static_cast<int_wrapper &>(ref1).increment (5);
|
||||
|
||||
increment (ref1, 5);
|
||||
proxy_container_type temp;
|
||||
temp.push_back (int_wrapper (10));
|
||||
reference ref2 (temp[0]);
|
||||
@@ -163,7 +180,7 @@ void test_indirect_proxy ()
|
||||
|
||||
reference ref2 (proxy_container[2]);
|
||||
BOOST_CHECK (ref2.use_count() == 2); // Still attached
|
||||
static_cast<int_wrapper &>(proxy_container[2]).increment (5);
|
||||
increment (proxy_container[2], 5);
|
||||
BOOST_CHECK (ref2 == int_wrapper (5));
|
||||
|
||||
// Notify proxy of insert in raw container (*after* insert)
|
||||
@@ -171,7 +188,7 @@ void test_indirect_proxy ()
|
||||
proxy_container.notify_insertion (0, 1);
|
||||
BOOST_CHECK (proxy_container.is_valid());
|
||||
BOOST_CHECK (ref2.use_count() == 2); // Still attached
|
||||
static_cast<int_wrapper &>(proxy_container[3]).increment (5);
|
||||
increment (proxy_container[3], 5);
|
||||
BOOST_CHECK (ref2 == int_wrapper (10));
|
||||
|
||||
// Create reference to about-to-be-erased value
|
||||
@@ -186,7 +203,7 @@ void test_indirect_proxy ()
|
||||
BOOST_CHECK (ref0.use_count() == 1); // Ref to erased value detached
|
||||
BOOST_CHECK (ref0 == int_wrapper (7)); // Value copied before erase
|
||||
BOOST_CHECK (ref2.use_count() == 2); // Other ref still attached
|
||||
static_cast<int_wrapper &>(proxy_container[1]).increment (5);
|
||||
increment (proxy_container[1], 5);
|
||||
BOOST_CHECK (ref2 == int_wrapper (15));
|
||||
|
||||
// Notify proxy of replacement in raw container (*before* assignment)
|
||||
@@ -214,6 +231,10 @@ struct deque_generator {
|
||||
};
|
||||
};
|
||||
|
||||
// Make the indirect holders work with broken compilers
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC (std::vector<int_wrapper>)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC (std::deque<int_wrapper>)
|
||||
|
||||
int test_main (int argc, char *argv[])
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
@@ -54,24 +54,28 @@ BOOST_PYTHON_MODULE(test_deque_ext)
|
||||
;
|
||||
|
||||
typedef std::deque<int> Container1;
|
||||
|
||||
boost::python::class_<Container1>("Deque")
|
||||
.def (indexing::container_suite<Container1>())
|
||||
;
|
||||
|
||||
typedef std::deque<int_wrapper> Container2;
|
||||
typedef indexing::container_proxy<
|
||||
Container2, indexing::identity<Container2>, deque_generator> Container3;
|
||||
|
||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
typedef indexing::container_suite<Container2> Suite2;
|
||||
typedef indexing::container_suite<Container3> Suite3;
|
||||
#else
|
||||
typedef indexing::deque_suite<Container1> Suite1;
|
||||
typedef indexing::deque_suite<Container2> Suite2;
|
||||
typedef indexing::container_proxy_suite<Container3> Suite3;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("Deque").def (Suite1());
|
||||
|
||||
// Returning internal references to elements of a deque is
|
||||
// dangerous - the references can be invalidated by inserts or
|
||||
// deletes!
|
||||
boost::python::class_<Container2>("Deque_ref")
|
||||
.def (indexing::container_suite<Container2>
|
||||
.def (Suite2
|
||||
::with_policies (boost::python::return_internal_reference<>()));
|
||||
|
||||
typedef indexing::container_proxy<
|
||||
Container2, indexing::identity<Container2>, deque_generator> Container3;
|
||||
|
||||
boost::python::class_<Container3>("Deque_proxy")
|
||||
.def (indexing::container_suite<Container3>())
|
||||
;
|
||||
boost::python::class_<Container3>("Deque_proxy").def (Suite3());
|
||||
}
|
||||
|
||||
@@ -37,12 +37,18 @@ std::vector<int_wrapper> get_vector ()
|
||||
, int_wrapper(7), int_wrapper(0) };
|
||||
|
||||
return std::vector<int_wrapper>
|
||||
#if BOOST_WORKAROUND (BOOST_MSVC, <=1200)
|
||||
(array, array + sizeof(array) / sizeof (array[0]));
|
||||
#else
|
||||
(boost::python::indexing::begin(array)
|
||||
, boost::python::indexing::end(array));
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(test_indexing_const_ext)
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
boost::python::implicitly_convertible <int, int_wrapper>();
|
||||
|
||||
boost::python::def ("setTrace", &int_wrapper::setTrace);
|
||||
@@ -56,8 +62,14 @@ BOOST_PYTHON_MODULE(test_indexing_const_ext)
|
||||
|
||||
typedef std::vector<int_wrapper> Container1;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1 const> Suite1;
|
||||
#else
|
||||
typedef indexing::vector_suite<Container1 const> Suite1;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("Vector_const")
|
||||
.def (boost::python::indexing::container_suite<Container1 const>())
|
||||
.def (Suite1())
|
||||
;
|
||||
|
||||
boost::python::def ("get_vector", get_vector);
|
||||
|
||||
@@ -29,6 +29,8 @@ unsigned int_wrapper::our_object_counter = 0;
|
||||
|
||||
BOOST_PYTHON_MODULE(test_list_ext)
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
boost::python::implicitly_convertible <int, int_wrapper>();
|
||||
|
||||
boost::python::def ("setTrace", &int_wrapper::setTrace);
|
||||
@@ -41,6 +43,12 @@ BOOST_PYTHON_MODULE(test_list_ext)
|
||||
|
||||
typedef std::list<int_wrapper> Container1;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
#else
|
||||
typedef indexing::list_suite<Container1> Suite1;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("List")
|
||||
.def (boost::python::indexing::container_suite<Container1>());
|
||||
.def (Suite1());
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ unsigned int_wrapper::our_object_counter = 0;
|
||||
|
||||
BOOST_PYTHON_MODULE(test_vector_ext)
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
boost::python::implicitly_convertible <int, int_wrapper>();
|
||||
|
||||
boost::python::def ("setTrace", &int_wrapper::setTrace);
|
||||
@@ -44,40 +46,33 @@ BOOST_PYTHON_MODULE(test_vector_ext)
|
||||
;
|
||||
|
||||
typedef std::vector<int> Container1;
|
||||
typedef std::vector<int_wrapper> Container2;
|
||||
typedef indexing::container_proxy< std::vector<int_wrapper> > Container3;
|
||||
|
||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
typedef indexing::container_suite<Container2> Suite2;
|
||||
typedef indexing::container_suite<Container3> Suite3;
|
||||
#else
|
||||
typedef indexing::vector_suite<Container1> Suite1;
|
||||
typedef indexing::vector_suite<Container2> Suite2;
|
||||
typedef indexing::container_proxy_suite<Container3> Suite3;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("Vector")
|
||||
.def (boost::python::indexing::container_suite<Container1>())
|
||||
.def (Suite1())
|
||||
.def ("reserve", &Container1::reserve)
|
||||
;
|
||||
|
||||
typedef std::vector<int_wrapper> Container2;
|
||||
|
||||
// Returning internal references to elements of a vector is
|
||||
// dangerous - the references can be invalidated by inserts or
|
||||
// deletes!
|
||||
boost::python::class_<Container2>("Vector_ref")
|
||||
.def (boost::python::indexing::container_suite<Container2>
|
||||
.def (Suite2
|
||||
::with_policies (boost::python::return_internal_reference<>()));
|
||||
|
||||
typedef boost::python::indexing::container_proxy< std::vector<int_wrapper> >
|
||||
Container3;
|
||||
|
||||
boost::python::class_<Container3>("Vector_proxy")
|
||||
.def (boost::python::indexing::container_suite<Container3>())
|
||||
.def (Suite3())
|
||||
.def ("reserve", &Container3::reserve)
|
||||
;
|
||||
|
||||
/* The no-partial-specialization version for vector<int>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace indexing;
|
||||
|
||||
class_<std::vector<int> > ("vector_int")
|
||||
.def (visitor <
|
||||
default_algorithms <
|
||||
default_sequence_traits <
|
||||
std::vector <int> > >,
|
||||
return_value_policy <return_by_value>
|
||||
>());
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -15,13 +15,19 @@
|
||||
|
||||
#include "int_wrapper.hpp"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
typedef boost::shared_ptr<int_wrapper> int_wrapper_holder;
|
||||
|
||||
#if !BOOST_WORKAROUND (BOOST_MSVC, == 1200)
|
||||
// Declare overloads for correct sort and find of int_wrappers via
|
||||
// shared pointers
|
||||
typedef boost::shared_ptr<int_wrapper> int_wrapper_holder;
|
||||
bool operator< (int_wrapper_holder const &, int_wrapper_holder const &);
|
||||
bool operator== (int_wrapper_holder const &, int_wrapper_holder const &);
|
||||
bool operator!= (int_wrapper_holder const &, int_wrapper_holder const &);
|
||||
#endif
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC (boost::shared_ptr<int_wrapper>)
|
||||
|
||||
#include <boost/python/suite/indexing/container_suite.hpp>
|
||||
#include <boost/python/suite/indexing/vector.hpp>
|
||||
@@ -35,6 +41,7 @@ bool operator!= (int_wrapper_holder const &, int_wrapper_holder const &);
|
||||
bool int_wrapper::our_trace_flag = true;
|
||||
unsigned int_wrapper::our_object_counter = 0;
|
||||
|
||||
#if !BOOST_WORKAROUND (BOOST_MSVC, == 1200)
|
||||
bool operator< (int_wrapper_holder const &lhs, int_wrapper_holder const &rhs)
|
||||
{
|
||||
return (*lhs) < (*rhs);
|
||||
@@ -49,6 +56,56 @@ bool operator!= (int_wrapper_holder const &lhs, int_wrapper_holder const &rhs)
|
||||
{
|
||||
return (*lhs) != (*rhs);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
typedef std::vector<int_wrapper_holder> Container1;
|
||||
|
||||
#if BOOST_WORKAROUND (BOOST_MSVC, == 1200)
|
||||
// Unfortunately, the comparison operator overloads don't work under
|
||||
// MSVC6, so we have to use a sledgehammer and replace the
|
||||
// implementations of some of the search functions
|
||||
|
||||
struct bound_compare {
|
||||
int_wrapper_holder m_lhs;
|
||||
bound_compare (int_wrapper_holder const &lhs) : m_lhs (lhs) { }
|
||||
bool operator()(int_wrapper_holder const &rhs) { return (*m_lhs) == (*rhs); }
|
||||
};
|
||||
|
||||
struct msvc6_vector_shared_algorithms
|
||||
: public indexing::default_algorithms <
|
||||
indexing::default_sequence_traits<Container1>
|
||||
, msvc6_vector_shared_algorithms
|
||||
>
|
||||
{
|
||||
typedef indexing::default_algorithms <
|
||||
indexing::default_sequence_traits<Container1>
|
||||
, msvc6_vector_shared_algorithms
|
||||
> base_type;
|
||||
|
||||
typedef msvc6_vector_shared_algorithms self_type;
|
||||
|
||||
// key_param will be boost::shared_ptr<int_wrapper> or ref to same
|
||||
|
||||
static bool less_than (key_param lhs, key_param rhs) {
|
||||
return (*lhs) < (*rhs);
|
||||
}
|
||||
|
||||
static iterator find (container &c, key_param k) {
|
||||
return std::find_if (c.begin(), c.end(), bound_compare (k));
|
||||
}
|
||||
|
||||
static size_type count (container &c, key_param k) {
|
||||
return std::count_if (c.begin(), c.end(), bound_compare (k));
|
||||
}
|
||||
|
||||
static void sort (container &c) {
|
||||
std::sort (c.begin(), c.end(), self_type::less_than);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_PYTHON_MODULE(test_vector_shared_ext)
|
||||
{
|
||||
@@ -63,10 +120,22 @@ BOOST_PYTHON_MODULE(test_vector_shared_ext)
|
||||
.def ("__cmp__", compare)
|
||||
;
|
||||
|
||||
typedef std::vector<int_wrapper_holder> Container1;
|
||||
#if BOOST_WORKAROUND (BOOST_MSVC, == 1200)
|
||||
// MSVC6 version here
|
||||
typedef indexing::container_suite <
|
||||
Container1, msvc6_vector_shared_algorithms> Suite1;
|
||||
|
||||
#elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
// Normal version here
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
|
||||
#else
|
||||
// For any other compilers that don't have partial specialization
|
||||
typedef indexing::vector_suite<Container1> Suite1;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("Vector_shared")
|
||||
.def (boost::python::indexing::container_suite<Container1>())
|
||||
.def (Suite1())
|
||||
.def ("reserve", &Container1::reserve)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ unsigned int_wrapper::our_object_counter = 0;
|
||||
|
||||
BOOST_PYTHON_MODULE(testnonlinear)
|
||||
{
|
||||
namespace indexing = boost::python::indexing;
|
||||
|
||||
boost::python::implicitly_convertible <int, int_wrapper>();
|
||||
|
||||
boost::python::def ("setTrace", &int_wrapper::setTrace);
|
||||
@@ -43,21 +45,12 @@ BOOST_PYTHON_MODULE(testnonlinear)
|
||||
typedef std::map<std::string, int_wrapper> Container1;
|
||||
typedef std::set<std::string> Container2;
|
||||
|
||||
#if !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
typedef boost::python::indexing::container_suite<Container1> Suite1;
|
||||
typedef boost::python::indexing::container_suite<Container2> Suite2;
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
typedef indexing::container_suite<Container1> Suite1;
|
||||
typedef indexing::container_suite<Container2> Suite2;
|
||||
#else
|
||||
typedef boost::python::indexing::container_suite
|
||||
<Container1
|
||||
, boost::python::indexing::map_algorithms
|
||||
<boost::python::indexing::map_traits
|
||||
<Container1> > > Suite1;
|
||||
|
||||
typedef boost::python::indexing::container_suite
|
||||
<Container2
|
||||
, boost::python::indexing::set_algorithms
|
||||
<boost::python::indexing::set_traits
|
||||
<Container2> > > Suite2;
|
||||
typedef indexing::map_suite<Container1> Suite1;
|
||||
typedef indexing::set_suite<Container2> Suite2;
|
||||
#endif
|
||||
|
||||
boost::python::class_<Container1>("Map").def (Suite1());
|
||||
|
||||
Reference in New Issue
Block a user