Added boost header
This commit is contained in:
57
test/external/boost/python/suite/indexing/container_utils.hpp
vendored
Normal file
57
test/external/boost/python/suite/indexing/container_utils.hpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
// (C) Copyright Joel de Guzman 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef PY_CONTAINER_UTILS_JDG20038_HPP
|
||||
# define PY_CONTAINER_UTILS_JDG20038_HPP
|
||||
|
||||
# include <utility>
|
||||
# include <boost/foreach.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/extract.hpp>
|
||||
# include <boost/python/stl_iterator.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace container_utils {
|
||||
|
||||
template <typename Container>
|
||||
void
|
||||
extend_container(Container& container, object l)
|
||||
{
|
||||
typedef typename Container::value_type data_type;
|
||||
|
||||
// l must be iterable
|
||||
BOOST_FOREACH(object elem,
|
||||
std::make_pair(
|
||||
boost::python::stl_input_iterator<object>(l),
|
||||
boost::python::stl_input_iterator<object>()
|
||||
))
|
||||
{
|
||||
extract<data_type const&> x(elem);
|
||||
// try if elem is an exact data_type type
|
||||
if (x.check())
|
||||
{
|
||||
container.push_back(x());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert elem to data_type type
|
||||
extract<data_type> x(elem);
|
||||
if (x.check())
|
||||
{
|
||||
container.push_back(x());
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Incompatible Data Type");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::container_utils
|
||||
|
||||
#endif
|
||||
759
test/external/boost/python/suite/indexing/detail/indexing_suite_detail.hpp
vendored
Normal file
759
test/external/boost/python/suite/indexing/detail/indexing_suite_detail.hpp
vendored
Normal file
@@ -0,0 +1,759 @@
|
||||
// (C) Copyright Joel de Guzman 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef INDEXING_SUITE_DETAIL_JDG20036_HPP
|
||||
# define INDEXING_SUITE_DETAIL_JDG20036_HPP
|
||||
|
||||
# include <boost/python/extract.hpp>
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
# include <boost/detail/binary_search.hpp>
|
||||
# include <boost/numeric/conversion/cast.hpp>
|
||||
# include <boost/type_traits/is_pointer.hpp>
|
||||
# include <vector>
|
||||
# include <map>
|
||||
#include <iostream>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT
|
||||
#else
|
||||
#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT check_invariant()
|
||||
#endif
|
||||
|
||||
template <class Proxy>
|
||||
struct compare_proxy_index
|
||||
{
|
||||
// This functor compares a proxy and an index.
|
||||
// This is used by proxy_group::first_proxy to
|
||||
// get first proxy with index i.
|
||||
|
||||
template <class Index>
|
||||
bool operator()(PyObject* prox, Index i) const
|
||||
{
|
||||
typedef typename Proxy::policies_type policies_type;
|
||||
Proxy& proxy = extract<Proxy&>(prox)();
|
||||
return policies_type::
|
||||
compare_index(proxy.get_container(), proxy.get_index(), i);
|
||||
}
|
||||
};
|
||||
|
||||
// The proxy_group class holds a vector of container element
|
||||
// proxies. First, what is a container element proxy? A container
|
||||
// element proxy acts like a smart pointer holding a reference to
|
||||
// a container and an index (see container_element, for details).
|
||||
//
|
||||
// The proxies are held in a vector always sorted by its index.
|
||||
// Various functions manage the addition, removal and searching
|
||||
// of proxies from the vector.
|
||||
//
|
||||
template <class Proxy>
|
||||
class proxy_group
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename std::vector<PyObject*>::const_iterator const_iterator;
|
||||
typedef typename std::vector<PyObject*>::iterator iterator;
|
||||
typedef typename Proxy::index_type index_type;
|
||||
typedef typename Proxy::policies_type policies_type;
|
||||
|
||||
iterator
|
||||
first_proxy(index_type i)
|
||||
{
|
||||
// Return the first proxy with index <= i
|
||||
return boost::detail::lower_bound(
|
||||
proxies.begin(), proxies.end(),
|
||||
i, compare_proxy_index<Proxy>());
|
||||
}
|
||||
|
||||
void
|
||||
remove(Proxy& proxy)
|
||||
{
|
||||
// Remove a proxy
|
||||
for (iterator iter = first_proxy(proxy.get_index());
|
||||
iter != proxies.end(); ++iter)
|
||||
{
|
||||
if (&extract<Proxy&>(*iter)() == &proxy)
|
||||
{
|
||||
proxies.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
void
|
||||
add(PyObject* prox)
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Add a proxy
|
||||
proxies.insert(
|
||||
first_proxy(extract<Proxy&>(prox)().get_index()), prox);
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
void
|
||||
erase(index_type i, mpl::false_)
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Erase the proxy with index i
|
||||
replace(i, i+1, 0);
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
void
|
||||
erase(index_type i, mpl::true_)
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Erase the proxy with index i
|
||||
|
||||
iterator iter = first_proxy(i);
|
||||
extract<Proxy&> p(*iter);
|
||||
|
||||
if (iter != proxies.end() && p().get_index() == i)
|
||||
{
|
||||
extract<Proxy&> p(*iter);
|
||||
p().detach();
|
||||
proxies.erase(iter);
|
||||
}
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
void
|
||||
erase(index_type from, index_type to)
|
||||
{
|
||||
// note: this cannot be called when container is not sliceable
|
||||
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Erase all proxies with indexes from..to
|
||||
replace(from, to, 0);
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
void
|
||||
replace(
|
||||
index_type from,
|
||||
index_type to,
|
||||
typename std::vector<PyObject*>::size_type len)
|
||||
{
|
||||
// note: this cannot be called when container is not sliceable
|
||||
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Erase all proxies with indexes from..to.
|
||||
// Adjust the displaced indexes such that the
|
||||
// final effect is that we have inserted *len*
|
||||
// number of proxies in the vacated region. This
|
||||
// procedure involves adjusting the indexes of
|
||||
// the proxies.
|
||||
|
||||
iterator left = first_proxy(from);
|
||||
iterator right = proxies.end(); // we'll adjust this later
|
||||
|
||||
for (iterator iter = left; iter != right; ++iter)
|
||||
{
|
||||
if (extract<Proxy&>(*iter)().get_index() > to)
|
||||
{
|
||||
right = iter; // adjust right
|
||||
break;
|
||||
}
|
||||
extract<Proxy&> p(*iter);
|
||||
p().detach();
|
||||
}
|
||||
|
||||
typename std::vector<PyObject*>::size_type
|
||||
offset = left-proxies.begin();
|
||||
proxies.erase(left, right);
|
||||
right = proxies.begin()+offset;
|
||||
|
||||
while (right != proxies.end())
|
||||
{
|
||||
typedef typename Proxy::container_type::difference_type difference_type;
|
||||
extract<Proxy&> p(*right);
|
||||
p().set_index(
|
||||
extract<Proxy&>(*right)().get_index()
|
||||
- (difference_type(to) - from - len)
|
||||
);
|
||||
|
||||
++right;
|
||||
}
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
find(index_type i)
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// Find the proxy with *exact* index i.
|
||||
// Return 0 (null) if no proxy with the
|
||||
// given index is found.
|
||||
iterator iter = first_proxy(i);
|
||||
if (iter != proxies.end()
|
||||
&& extract<Proxy&>(*iter)().get_index() == i)
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
return *iter;
|
||||
}
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
typename std::vector<PyObject*>::size_type
|
||||
size() const
|
||||
{
|
||||
BOOST_PYTHON_INDEXING_CHECK_INVARIANT;
|
||||
// How many proxies are there so far?
|
||||
return proxies.size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
void
|
||||
check_invariant() const
|
||||
{
|
||||
for (const_iterator i = proxies.begin(); i != proxies.end(); ++i)
|
||||
{
|
||||
if ((*i)->ob_refcnt <= 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Invariant: Proxy vector in an inconsistent state");
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
if (i+1 != proxies.end())
|
||||
{
|
||||
if (extract<Proxy&>(*(i+1))().get_index() ==
|
||||
extract<Proxy&>(*(i))().get_index())
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Invariant: Proxy vector in an inconsistent state (duplicate proxy)");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<PyObject*> proxies;
|
||||
};
|
||||
|
||||
// proxy_links holds a map of Container pointers (keys)
|
||||
// with proxy_group(s) (data). Various functions manage
|
||||
// the addition, removal and searching of proxies from
|
||||
// the map.
|
||||
//
|
||||
template <class Proxy, class Container>
|
||||
class proxy_links
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<Container*, proxy_group<Proxy> > links_t;
|
||||
typedef typename Proxy::index_type index_type;
|
||||
|
||||
void
|
||||
remove(Proxy& proxy)
|
||||
{
|
||||
// Remove a proxy.
|
||||
typename links_t::iterator r = links.find(&proxy.get_container());
|
||||
if (r != links.end())
|
||||
{
|
||||
r->second.remove(proxy);
|
||||
if (r->second.size() == 0)
|
||||
links.erase(r);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
add(PyObject* prox, Container& container)
|
||||
{
|
||||
// Add a proxy
|
||||
links[&container].add(prox);
|
||||
}
|
||||
|
||||
template <class NoSlice>
|
||||
void erase(Container& container, index_type i, NoSlice no_slice)
|
||||
{
|
||||
// Erase the proxy with index i
|
||||
typename links_t::iterator r = links.find(&container);
|
||||
if (r != links.end())
|
||||
{
|
||||
r->second.erase(i, no_slice);
|
||||
if (r->second.size() == 0)
|
||||
links.erase(r);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
erase(Container& container, index_type from, index_type to)
|
||||
{
|
||||
// Erase all proxies with indexes from..to
|
||||
typename links_t::iterator r = links.find(&container);
|
||||
if (r != links.end())
|
||||
{
|
||||
r->second.erase(from, to);
|
||||
if (r->second.size() == 0)
|
||||
links.erase(r);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
replace(
|
||||
Container& container,
|
||||
index_type from, index_type to, index_type len)
|
||||
{
|
||||
// Erase all proxies with indexes from..to.
|
||||
// Adjust the displaced indexes such that the
|
||||
// final effect is that we have inserted *len*
|
||||
// number of proxies in the vacated region. This
|
||||
// procedure involves adjusting the indexes of
|
||||
// the proxies.
|
||||
|
||||
typename links_t::iterator r = links.find(&container);
|
||||
if (r != links.end())
|
||||
{
|
||||
r->second.replace(from, to, len);
|
||||
if (r->second.size() == 0)
|
||||
links.erase(r);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject*
|
||||
find(Container& container, index_type i)
|
||||
{
|
||||
// Find the proxy with *exact* index i.
|
||||
// Return 0 (null) if no proxy with the given
|
||||
// index is found.
|
||||
typename links_t::iterator r = links.find(&container);
|
||||
if (r != links.end())
|
||||
return r->second.find(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
links_t links;
|
||||
};
|
||||
|
||||
// container_element is our container proxy class.
|
||||
// This class acts like a smart pointer to a container
|
||||
// element. The class holds an index and a reference to
|
||||
// a container. Dereferencing the smart pointer will
|
||||
// retrieve the nth (index) element from the container.
|
||||
//
|
||||
// A container_element can also be detached from the
|
||||
// container. In such a detached state, the container_element
|
||||
// holds a copy of the nth (index) element, which it
|
||||
// returns when dereferenced.
|
||||
//
|
||||
template <class Container, class Index, class Policies>
|
||||
class container_element
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Index index_type;
|
||||
typedef Container container_type;
|
||||
typedef typename Policies::data_type element_type;
|
||||
typedef Policies policies_type;
|
||||
typedef container_element<Container, Index, Policies> self_t;
|
||||
typedef proxy_group<self_t> links_type;
|
||||
|
||||
container_element(object container, Index index)
|
||||
: ptr()
|
||||
, container(container)
|
||||
, index(index)
|
||||
{
|
||||
}
|
||||
|
||||
container_element(container_element const& ce)
|
||||
: ptr(ce.ptr.get() == 0 ? 0 : new element_type(*ce.ptr.get()))
|
||||
, container(ce.container)
|
||||
, index(ce.index)
|
||||
{
|
||||
}
|
||||
|
||||
~container_element()
|
||||
{
|
||||
if (!is_detached())
|
||||
get_links().remove(*this);
|
||||
}
|
||||
|
||||
element_type& operator*() const
|
||||
{
|
||||
if (is_detached())
|
||||
return *get_pointer(ptr);
|
||||
return Policies::get_item(get_container(), index);
|
||||
}
|
||||
|
||||
element_type* get() const
|
||||
{
|
||||
if (is_detached())
|
||||
return get_pointer(ptr);
|
||||
return &Policies::get_item(get_container(), index);
|
||||
}
|
||||
|
||||
void
|
||||
detach()
|
||||
{
|
||||
if (!is_detached())
|
||||
{
|
||||
ptr.reset(
|
||||
new element_type(
|
||||
Policies::get_item(get_container(), index)));
|
||||
container = object(); // free container. reset it to None
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
is_detached() const
|
||||
{
|
||||
return get_pointer(ptr) != 0;
|
||||
}
|
||||
|
||||
Container&
|
||||
get_container() const
|
||||
{
|
||||
return extract<Container&>(container)();
|
||||
}
|
||||
|
||||
Index
|
||||
get_index() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
set_index(Index i)
|
||||
{
|
||||
index = i;
|
||||
}
|
||||
|
||||
static proxy_links<self_t, Container>&
|
||||
get_links()
|
||||
{
|
||||
// All container_element(s) maintain links to
|
||||
// its container in a global map (see proxy_links).
|
||||
// This global "links" map is a singleton.
|
||||
|
||||
static proxy_links<self_t, Container> links;
|
||||
return links; // singleton
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
container_element& operator=(container_element const& ce);
|
||||
|
||||
scoped_ptr<element_type> ptr;
|
||||
object container;
|
||||
Index index;
|
||||
};
|
||||
|
||||
template <
|
||||
class Container
|
||||
, class DerivedPolicies
|
||||
, class ContainerElement
|
||||
, class Index
|
||||
>
|
||||
struct no_proxy_helper
|
||||
{
|
||||
static void
|
||||
register_container_element()
|
||||
{
|
||||
}
|
||||
|
||||
template <class DataType>
|
||||
static object
|
||||
base_get_item_helper(DataType const& p, mpl::true_)
|
||||
{
|
||||
return object(ptr(p));
|
||||
}
|
||||
|
||||
template <class DataType>
|
||||
static object
|
||||
base_get_item_helper(DataType const& x, mpl::false_)
|
||||
{
|
||||
return object(x);
|
||||
}
|
||||
|
||||
static object
|
||||
base_get_item_(back_reference<Container&> const& container, PyObject* i)
|
||||
{
|
||||
return base_get_item_helper(
|
||||
DerivedPolicies::get_item(
|
||||
container.get(), DerivedPolicies::
|
||||
convert_index(container.get(), i))
|
||||
, is_pointer<BOOST_DEDUCED_TYPENAME Container::value_type>()
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
base_replace_indexes(
|
||||
Container& /*container*/, Index /*from*/,
|
||||
Index /*to*/, Index /*n*/)
|
||||
{
|
||||
}
|
||||
|
||||
template <class NoSlice>
|
||||
static void
|
||||
base_erase_index(
|
||||
Container& /*container*/, Index /*i*/, NoSlice /*no_slice*/)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
base_erase_indexes(Container& /*container*/, Index /*from*/, Index /*to*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
class Container
|
||||
, class DerivedPolicies
|
||||
, class ContainerElement
|
||||
, class Index
|
||||
>
|
||||
struct proxy_helper
|
||||
{
|
||||
static void
|
||||
register_container_element()
|
||||
{
|
||||
register_ptr_to_python<ContainerElement>();
|
||||
}
|
||||
|
||||
static object
|
||||
base_get_item_(back_reference<Container&> const& container, PyObject* i)
|
||||
{
|
||||
// Proxy
|
||||
Index idx = DerivedPolicies::convert_index(container.get(), i);
|
||||
|
||||
if (PyObject* shared =
|
||||
ContainerElement::get_links().find(container.get(), idx))
|
||||
{
|
||||
handle<> h(python::borrowed(shared));
|
||||
return object(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
object prox(ContainerElement(container.source(), idx));
|
||||
ContainerElement::
|
||||
get_links().add(prox.ptr(), container.get());
|
||||
return prox;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base_replace_indexes(
|
||||
Container& container, Index from,
|
||||
Index to, Index n)
|
||||
{
|
||||
ContainerElement::get_links().replace(container, from, to, n);
|
||||
}
|
||||
|
||||
template <class NoSlice>
|
||||
static void
|
||||
base_erase_index(
|
||||
Container& container, Index i, NoSlice no_slice)
|
||||
{
|
||||
ContainerElement::get_links().erase(container, i, no_slice);
|
||||
}
|
||||
|
||||
static void
|
||||
base_erase_indexes(
|
||||
Container& container, Index from, Index to)
|
||||
{
|
||||
ContainerElement::get_links().erase(container, from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
class Container
|
||||
, class DerivedPolicies
|
||||
, class ProxyHandler
|
||||
, class Data
|
||||
, class Index
|
||||
>
|
||||
struct slice_helper
|
||||
{
|
||||
static object
|
||||
base_get_slice(Container& container, PySliceObject* slice)
|
||||
{
|
||||
Index from, to;
|
||||
base_get_slice_data(container, slice, from, to);
|
||||
return DerivedPolicies::get_slice(container, from, to);
|
||||
}
|
||||
|
||||
static void
|
||||
base_get_slice_data(
|
||||
Container& container, PySliceObject* slice, Index& from_, Index& to_)
|
||||
{
|
||||
if (Py_None != slice->step) {
|
||||
PyErr_SetString( PyExc_IndexError, "slice step size not supported.");
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
Index min_index = DerivedPolicies::get_min_index(container);
|
||||
Index max_index = DerivedPolicies::get_max_index(container);
|
||||
|
||||
if (Py_None == slice->start) {
|
||||
from_ = min_index;
|
||||
}
|
||||
else {
|
||||
long from = extract<long>( slice->start);
|
||||
if (from < 0) // Negative slice index
|
||||
from += max_index;
|
||||
if (from < 0) // Clip lower bounds to zero
|
||||
from = 0;
|
||||
from_ = boost::numeric_cast<Index>(from);
|
||||
if (from_ > max_index) // Clip upper bounds to max_index.
|
||||
from_ = max_index;
|
||||
}
|
||||
|
||||
if (Py_None == slice->stop) {
|
||||
to_ = max_index;
|
||||
}
|
||||
else {
|
||||
long to = extract<long>( slice->stop);
|
||||
if (to < 0)
|
||||
to += max_index;
|
||||
if (to < 0)
|
||||
to = 0;
|
||||
to_ = boost::numeric_cast<Index>(to);
|
||||
if (to_ > max_index)
|
||||
to_ = max_index;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base_set_slice(Container& container, PySliceObject* slice, PyObject* v)
|
||||
{
|
||||
Index from, to;
|
||||
base_get_slice_data(container, slice, from, to);
|
||||
|
||||
extract<Data&> elem(v);
|
||||
// try if elem is an exact Data
|
||||
if (elem.check())
|
||||
{
|
||||
ProxyHandler::base_replace_indexes(container, from, to, 1);
|
||||
DerivedPolicies::set_slice(container, from, to, elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert elem to Data
|
||||
extract<Data> elem(v);
|
||||
if (elem.check())
|
||||
{
|
||||
ProxyHandler::base_replace_indexes(container, from, to, 1);
|
||||
DerivedPolicies::set_slice(container, from, to, elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, it must be a list or some container
|
||||
handle<> l_(python::borrowed(v));
|
||||
object l(l_);
|
||||
|
||||
std::vector<Data> temp;
|
||||
for (int i = 0; i < l.attr("__len__")(); i++)
|
||||
{
|
||||
object elem(l[i]);
|
||||
extract<Data const&> x(elem);
|
||||
// try if elem is an exact Data type
|
||||
if (x.check())
|
||||
{
|
||||
temp.push_back(x());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert elem to Data type
|
||||
extract<Data> x(elem);
|
||||
if (x.check())
|
||||
{
|
||||
temp.push_back(x());
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Invalid sequence element");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProxyHandler::base_replace_indexes(container, from, to,
|
||||
temp.end()-temp.begin());
|
||||
DerivedPolicies::set_slice(container, from, to,
|
||||
temp.begin(), temp.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base_delete_slice(Container& container, PySliceObject* slice)
|
||||
{
|
||||
Index from, to;
|
||||
base_get_slice_data(container, slice, from, to);
|
||||
ProxyHandler::base_erase_indexes(container, from, to);
|
||||
DerivedPolicies::delete_slice(container, from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
class Container
|
||||
, class DerivedPolicies
|
||||
, class ProxyHandler
|
||||
, class Data
|
||||
, class Index
|
||||
>
|
||||
struct no_slice_helper
|
||||
{
|
||||
static void
|
||||
slicing_not_suported()
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Slicing not supported");
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
static object
|
||||
base_get_slice(Container& /*container*/, PySliceObject* /*slice*/)
|
||||
{
|
||||
slicing_not_suported();
|
||||
return object();
|
||||
}
|
||||
|
||||
static void
|
||||
base_set_slice(Container& /*container*/, PySliceObject* /*slice*/, PyObject* /*v*/)
|
||||
{
|
||||
slicing_not_suported();
|
||||
}
|
||||
|
||||
static void
|
||||
base_delete_slice(Container& /*container*/, PySliceObject* /*slice*/)
|
||||
{
|
||||
slicing_not_suported();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
}} // namespace python::detail
|
||||
#endif
|
||||
|
||||
template <class Container, class Index, class Policies>
|
||||
inline typename Policies::data_type*
|
||||
get_pointer(
|
||||
python::detail::container_element<Container, Index, Policies> const& p)
|
||||
{
|
||||
// Get the pointer of a container_element smart pointer
|
||||
return p.get();
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
// Don't hide these other get_pointer overloads
|
||||
using boost::python::get_pointer;
|
||||
using boost::get_pointer;
|
||||
}} // namespace python::detail
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // INDEXING_SUITE_DETAIL_JDG20036_HPP
|
||||
299
test/external/boost/python/suite/indexing/indexing_suite.hpp
vendored
Normal file
299
test/external/boost/python/suite/indexing/indexing_suite.hpp
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
// (C) Copyright Joel de Guzman 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef INDEXING_SUITE_JDG20036_HPP
|
||||
# define INDEXING_SUITE_JDG20036_HPP
|
||||
|
||||
# include <boost/python/class.hpp>
|
||||
# include <boost/python/def_visitor.hpp>
|
||||
# include <boost/python/register_ptr_to_python.hpp>
|
||||
# include <boost/python/suite/indexing/detail/indexing_suite_detail.hpp>
|
||||
# include <boost/python/return_internal_reference.hpp>
|
||||
# include <boost/python/iterator.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// indexing_suite class. This class is the facade class for
|
||||
// the management of C++ containers intended to be integrated
|
||||
// to Python. The objective is make a C++ container look and
|
||||
// feel and behave exactly as we'd expect a Python container.
|
||||
// By default indexed elements are returned by proxy. This can be
|
||||
// disabled by supplying *true* in the NoProxy template parameter.
|
||||
//
|
||||
// Derived classes provide the hooks needed by the indexing_suite
|
||||
// to do its job:
|
||||
//
|
||||
// static data_type&
|
||||
// get_item(Container& container, index_type i);
|
||||
//
|
||||
// static object
|
||||
// get_slice(Container& container, index_type from, index_type to);
|
||||
//
|
||||
// static void
|
||||
// set_item(Container& container, index_type i, data_type const& v);
|
||||
//
|
||||
// static void
|
||||
// set_slice(
|
||||
// Container& container, index_type from,
|
||||
// index_type to, data_type const& v
|
||||
// );
|
||||
//
|
||||
// template <class Iter>
|
||||
// static void
|
||||
// set_slice(Container& container, index_type from,
|
||||
// index_type to, Iter first, Iter last
|
||||
// );
|
||||
//
|
||||
// static void
|
||||
// delete_item(Container& container, index_type i);
|
||||
//
|
||||
// static void
|
||||
// delete_slice(Container& container, index_type from, index_type to);
|
||||
//
|
||||
// static size_t
|
||||
// size(Container& container);
|
||||
//
|
||||
// template <class T>
|
||||
// static bool
|
||||
// contains(Container& container, T const& val);
|
||||
//
|
||||
// static index_type
|
||||
// convert_index(Container& container, PyObject* i);
|
||||
//
|
||||
// static index_type
|
||||
// adjust_index(index_type current, index_type from,
|
||||
// index_type to, size_type len
|
||||
// );
|
||||
//
|
||||
// Most of these policies are self explanatory. convert_index and
|
||||
// adjust_index, however, deserves some explanation.
|
||||
//
|
||||
// convert_index converts an Python index into a C++ index that the
|
||||
// container can handle. For instance, negative indexes in Python, by
|
||||
// convention, indexes from the right (e.g. C[-1] indexes the rightmost
|
||||
// element in C). convert_index should handle the necessary conversion
|
||||
// for the C++ container (e.g. convert -1 to C.size()-1). convert_index
|
||||
// should also be able to convert the type of the index (A dynamic Python
|
||||
// type) to the actual type that the C++ container expects.
|
||||
//
|
||||
// When a container expands or contracts, held indexes to its elements
|
||||
// must be adjusted to follow the movement of data. For instance, if
|
||||
// we erase 3 elements, starting from index 0 from a 5 element vector,
|
||||
// what used to be at index 4 will now be at index 1:
|
||||
//
|
||||
// [a][b][c][d][e] ---> [d][e]
|
||||
// ^ ^
|
||||
// 4 1
|
||||
//
|
||||
// adjust_index takes care of the adjustment. Given a current index,
|
||||
// the function should return the adjusted index when data in the
|
||||
// container at index from..to is replaced by *len* elements.
|
||||
//
|
||||
|
||||
template <
|
||||
class Container
|
||||
, class DerivedPolicies
|
||||
, bool NoProxy = false
|
||||
, bool NoSlice = false
|
||||
, class Data = typename Container::value_type
|
||||
, class Index = typename Container::size_type
|
||||
, class Key = typename Container::value_type
|
||||
>
|
||||
class indexing_suite
|
||||
: public def_visitor<
|
||||
indexing_suite<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, NoProxy
|
||||
, NoSlice
|
||||
, Data
|
||||
, Index
|
||||
, Key
|
||||
> >
|
||||
{
|
||||
private:
|
||||
|
||||
typedef mpl::or_<
|
||||
mpl::bool_<NoProxy>
|
||||
, mpl::not_<is_class<Data> >
|
||||
, typename mpl::or_<
|
||||
is_same<Data, std::string>
|
||||
, is_same<Data, std::complex<float> >
|
||||
, is_same<Data, std::complex<double> >
|
||||
, is_same<Data, std::complex<long double> > >::type>
|
||||
no_proxy;
|
||||
|
||||
typedef detail::container_element<Container, Index, DerivedPolicies>
|
||||
container_element_t;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
struct return_policy : return_internal_reference<> {};
|
||||
#else
|
||||
typedef return_internal_reference<> return_policy;
|
||||
#endif
|
||||
|
||||
typedef typename mpl::if_<
|
||||
no_proxy
|
||||
, iterator<Container>
|
||||
, iterator<Container, return_policy> >::type
|
||||
def_iterator;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
no_proxy
|
||||
, detail::no_proxy_helper<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, container_element_t
|
||||
, Index>
|
||||
, detail::proxy_helper<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, container_element_t
|
||||
, Index> >::type
|
||||
proxy_handler;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::bool_<NoSlice>
|
||||
, detail::no_slice_helper<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, proxy_handler
|
||||
, Data
|
||||
, Index>
|
||||
, detail::slice_helper<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, proxy_handler
|
||||
, Data
|
||||
, Index> >::type
|
||||
slice_handler;
|
||||
|
||||
public:
|
||||
|
||||
template <class Class>
|
||||
void visit(Class& cl) const
|
||||
{
|
||||
// Hook into the class_ generic visitation .def function
|
||||
proxy_handler::register_container_element();
|
||||
|
||||
cl
|
||||
.def("__len__", base_size)
|
||||
.def("__setitem__", &base_set_item)
|
||||
.def("__delitem__", &base_delete_item)
|
||||
.def("__getitem__", &base_get_item)
|
||||
.def("__contains__", &base_contains)
|
||||
.def("__iter__", def_iterator())
|
||||
;
|
||||
|
||||
DerivedPolicies::extension_def(cl);
|
||||
}
|
||||
|
||||
template <class Class>
|
||||
static void
|
||||
extension_def(Class& cl)
|
||||
{
|
||||
// default.
|
||||
// no more extensions
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static object
|
||||
base_get_item(back_reference<Container&> container, PyObject* i)
|
||||
{
|
||||
if (PySlice_Check(i))
|
||||
return slice_handler::base_get_slice(
|
||||
container.get(), static_cast<PySliceObject*>(static_cast<void*>(i)));
|
||||
|
||||
return proxy_handler::base_get_item_(container, i);
|
||||
}
|
||||
|
||||
static void
|
||||
base_set_item(Container& container, PyObject* i, PyObject* v)
|
||||
{
|
||||
if (PySlice_Check(i))
|
||||
{
|
||||
slice_handler::base_set_slice(container,
|
||||
static_cast<PySliceObject*>(static_cast<void*>(i)), v);
|
||||
}
|
||||
else
|
||||
{
|
||||
extract<Data&> elem(v);
|
||||
// try if elem is an exact Data
|
||||
if (elem.check())
|
||||
{
|
||||
DerivedPolicies::
|
||||
set_item(container,
|
||||
DerivedPolicies::
|
||||
convert_index(container, i), elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert elem to Data
|
||||
extract<Data> elem(v);
|
||||
if (elem.check())
|
||||
{
|
||||
DerivedPolicies::
|
||||
set_item(container,
|
||||
DerivedPolicies::
|
||||
convert_index(container, i), elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid assignment");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base_delete_item(Container& container, PyObject* i)
|
||||
{
|
||||
if (PySlice_Check(i))
|
||||
{
|
||||
slice_handler::base_delete_slice(
|
||||
container, static_cast<PySliceObject*>(static_cast<void*>(i)));
|
||||
return;
|
||||
}
|
||||
|
||||
Index index = DerivedPolicies::convert_index(container, i);
|
||||
proxy_handler::base_erase_index(container, index, mpl::bool_<NoSlice>());
|
||||
DerivedPolicies::delete_item(container, index);
|
||||
}
|
||||
|
||||
static size_t
|
||||
base_size(Container& container)
|
||||
{
|
||||
return DerivedPolicies::size(container);
|
||||
}
|
||||
|
||||
static bool
|
||||
base_contains(Container& container, PyObject* key)
|
||||
{
|
||||
extract<Key const&> x(key);
|
||||
// try if key is an exact Key type
|
||||
if (x.check())
|
||||
{
|
||||
return DerivedPolicies::contains(container, x());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert key to Key type
|
||||
extract<Key> x(key);
|
||||
if (x.check())
|
||||
return DerivedPolicies::contains(container, x());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // INDEXING_SUITE_JDG20036_HPP
|
||||
181
test/external/boost/python/suite/indexing/map_indexing_suite.hpp
vendored
Normal file
181
test/external/boost/python/suite/indexing/map_indexing_suite.hpp
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// (C) Copyright Joel de Guzman 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MAP_INDEXING_SUITE_JDG20038_HPP
|
||||
# define MAP_INDEXING_SUITE_JDG20038_HPP
|
||||
|
||||
# include <boost/python/suite/indexing/indexing_suite.hpp>
|
||||
# include <boost/python/iterator.hpp>
|
||||
# include <boost/python/call_method.hpp>
|
||||
# include <boost/python/tuple.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Forward declaration
|
||||
template <class Container, bool NoProxy, class DerivedPolicies>
|
||||
class map_indexing_suite;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Container, bool NoProxy>
|
||||
class final_map_derived_policies
|
||||
: public map_indexing_suite<Container,
|
||||
NoProxy, final_map_derived_policies<Container, NoProxy> > {};
|
||||
}
|
||||
|
||||
// The map_indexing_suite class is a predefined indexing_suite derived
|
||||
// class for wrapping std::map (and std::map like) classes. It provides
|
||||
// all the policies required by the indexing_suite (see indexing_suite).
|
||||
// Example usage:
|
||||
//
|
||||
// class X {...};
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// class_<std::map<std::string, X> >("XMap")
|
||||
// .def(map_indexing_suite<std::map<std::string, X> >())
|
||||
// ;
|
||||
//
|
||||
// By default indexed elements are returned by proxy. This can be
|
||||
// disabled by supplying *true* in the NoProxy template parameter.
|
||||
//
|
||||
template <
|
||||
class Container,
|
||||
bool NoProxy = false,
|
||||
class DerivedPolicies
|
||||
= detail::final_map_derived_policies<Container, NoProxy> >
|
||||
class map_indexing_suite
|
||||
: public indexing_suite<
|
||||
Container
|
||||
, DerivedPolicies
|
||||
, NoProxy
|
||||
, true
|
||||
, typename Container::value_type::second_type
|
||||
, typename Container::key_type
|
||||
, typename Container::key_type
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::value_type::second_type data_type;
|
||||
typedef typename Container::key_type key_type;
|
||||
typedef typename Container::key_type index_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
|
||||
template <class Class>
|
||||
static void
|
||||
extension_def(Class& cl)
|
||||
{
|
||||
// Wrap the map's element (value_type)
|
||||
std::string elem_name = "map_indexing_suite_";
|
||||
object class_name(cl.attr("__name__"));
|
||||
extract<std::string> class_name_extractor(class_name);
|
||||
elem_name += class_name_extractor();
|
||||
elem_name += "_entry";
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<is_class<data_type>, mpl::bool_<!NoProxy> >
|
||||
, return_internal_reference<>
|
||||
, default_call_policies
|
||||
>::type get_data_return_policy;
|
||||
|
||||
class_<value_type>(elem_name.c_str())
|
||||
.def("__repr__", &DerivedPolicies::print_elem)
|
||||
.def("data", &DerivedPolicies::get_data, get_data_return_policy())
|
||||
.def("key", &DerivedPolicies::get_key)
|
||||
;
|
||||
}
|
||||
|
||||
static object
|
||||
print_elem(typename Container::value_type const& e)
|
||||
{
|
||||
return "(%s, %s)" % python::make_tuple(e.first, e.second);
|
||||
}
|
||||
|
||||
static
|
||||
typename mpl::if_<
|
||||
mpl::and_<is_class<data_type>, mpl::bool_<!NoProxy> >
|
||||
, data_type&
|
||||
, data_type
|
||||
>::type
|
||||
get_data(typename Container::value_type& e)
|
||||
{
|
||||
return e.second;
|
||||
}
|
||||
|
||||
static typename Container::key_type
|
||||
get_key(typename Container::value_type& e)
|
||||
{
|
||||
return e.first;
|
||||
}
|
||||
|
||||
static data_type&
|
||||
get_item(Container& container, index_type i_)
|
||||
{
|
||||
typename Container::iterator i = container.find(i_);
|
||||
if (i == container.end())
|
||||
{
|
||||
PyErr_SetString(PyExc_KeyError, "Invalid key");
|
||||
throw_error_already_set();
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static void
|
||||
set_item(Container& container, index_type i, data_type const& v)
|
||||
{
|
||||
container[i] = v;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i)
|
||||
{
|
||||
container.erase(i);
|
||||
}
|
||||
|
||||
static size_t
|
||||
size(Container& container)
|
||||
{
|
||||
return container.size();
|
||||
}
|
||||
|
||||
static bool
|
||||
contains(Container& container, key_type const& key)
|
||||
{
|
||||
return container.find(key) != container.end();
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_index(Container& container, index_type a, index_type b)
|
||||
{
|
||||
return container.key_comp()(a, b);
|
||||
}
|
||||
|
||||
static index_type
|
||||
convert_index(Container& /*container*/, PyObject* i_)
|
||||
{
|
||||
extract<key_type const&> i(i_);
|
||||
if (i.check())
|
||||
{
|
||||
return i();
|
||||
}
|
||||
else
|
||||
{
|
||||
extract<key_type> i(i_);
|
||||
if (i.check())
|
||||
return i();
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid index type");
|
||||
throw_error_already_set();
|
||||
return index_type();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MAP_INDEXING_SUITE_JDG20038_HPP
|
||||
242
test/external/boost/python/suite/indexing/vector_indexing_suite.hpp
vendored
Normal file
242
test/external/boost/python/suite/indexing/vector_indexing_suite.hpp
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// (C) Copyright Joel de Guzman 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef VECTOR_INDEXING_SUITE_JDG20036_HPP
|
||||
# define VECTOR_INDEXING_SUITE_JDG20036_HPP
|
||||
|
||||
# include <boost/python/suite/indexing/indexing_suite.hpp>
|
||||
# include <boost/python/suite/indexing/container_utils.hpp>
|
||||
# include <boost/python/iterator.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Forward declaration
|
||||
template <class Container, bool NoProxy, class DerivedPolicies>
|
||||
class vector_indexing_suite;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Container, bool NoProxy>
|
||||
class final_vector_derived_policies
|
||||
: public vector_indexing_suite<Container,
|
||||
NoProxy, final_vector_derived_policies<Container, NoProxy> > {};
|
||||
}
|
||||
|
||||
// The vector_indexing_suite class is a predefined indexing_suite derived
|
||||
// class for wrapping std::vector (and std::vector like) classes. It provides
|
||||
// all the policies required by the indexing_suite (see indexing_suite).
|
||||
// Example usage:
|
||||
//
|
||||
// class X {...};
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// class_<std::vector<X> >("XVec")
|
||||
// .def(vector_indexing_suite<std::vector<X> >())
|
||||
// ;
|
||||
//
|
||||
// By default indexed elements are returned by proxy. This can be
|
||||
// disabled by supplying *true* in the NoProxy template parameter.
|
||||
//
|
||||
template <
|
||||
class Container,
|
||||
bool NoProxy = false,
|
||||
class DerivedPolicies
|
||||
= detail::final_vector_derived_policies<Container, NoProxy> >
|
||||
class vector_indexing_suite
|
||||
: public indexing_suite<Container, DerivedPolicies, NoProxy>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Container::value_type data_type;
|
||||
typedef typename Container::value_type key_type;
|
||||
typedef typename Container::size_type index_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
|
||||
template <class Class>
|
||||
static void
|
||||
extension_def(Class& cl)
|
||||
{
|
||||
cl
|
||||
.def("append", &base_append)
|
||||
.def("extend", &base_extend)
|
||||
;
|
||||
}
|
||||
|
||||
static
|
||||
typename mpl::if_<
|
||||
is_class<data_type>
|
||||
, data_type&
|
||||
, data_type
|
||||
>::type
|
||||
get_item(Container& container, index_type i)
|
||||
{
|
||||
return container[i];
|
||||
}
|
||||
|
||||
static object
|
||||
get_slice(Container& container, index_type from, index_type to)
|
||||
{
|
||||
if (from > to)
|
||||
return object(Container());
|
||||
return object(Container(container.begin()+from, container.begin()+to));
|
||||
}
|
||||
|
||||
static void
|
||||
set_item(Container& container, index_type i, data_type const& v)
|
||||
{
|
||||
container[i] = v;
|
||||
}
|
||||
|
||||
static void
|
||||
set_slice(Container& container, index_type from,
|
||||
index_type to, data_type const& v)
|
||||
{
|
||||
if (from > to) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
container.erase(container.begin()+from, container.begin()+to);
|
||||
container.insert(container.begin()+from, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Iter>
|
||||
static void
|
||||
set_slice(Container& container, index_type from,
|
||||
index_type to, Iter first, Iter last)
|
||||
{
|
||||
if (from > to) {
|
||||
container.insert(container.begin()+from, first, last);
|
||||
}
|
||||
else {
|
||||
container.erase(container.begin()+from, container.begin()+to);
|
||||
container.insert(container.begin()+from, first, last);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i)
|
||||
{
|
||||
container.erase(container.begin()+i);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_slice(Container& container, index_type from, index_type to)
|
||||
{
|
||||
if (from > to) {
|
||||
// A null-op.
|
||||
return;
|
||||
}
|
||||
container.erase(container.begin()+from, container.begin()+to);
|
||||
}
|
||||
|
||||
static size_t
|
||||
size(Container& container)
|
||||
{
|
||||
return container.size();
|
||||
}
|
||||
|
||||
static bool
|
||||
contains(Container& container, key_type const& key)
|
||||
{
|
||||
return std::find(container.begin(), container.end(), key)
|
||||
!= container.end();
|
||||
}
|
||||
|
||||
static index_type
|
||||
get_min_index(Container& /*container*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static index_type
|
||||
get_max_index(Container& container)
|
||||
{
|
||||
return container.size();
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_index(Container& /*container*/, index_type a, index_type b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static index_type
|
||||
convert_index(Container& container, PyObject* i_)
|
||||
{
|
||||
extract<long> i(i_);
|
||||
if (i.check())
|
||||
{
|
||||
long index = i();
|
||||
if (index < 0)
|
||||
index += DerivedPolicies::size(container);
|
||||
if (index >= long(container.size()) || index < 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "Index out of range");
|
||||
throw_error_already_set();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid index type");
|
||||
throw_error_already_set();
|
||||
return index_type();
|
||||
}
|
||||
|
||||
static void
|
||||
append(Container& container, data_type const& v)
|
||||
{
|
||||
container.push_back(v);
|
||||
}
|
||||
|
||||
template <class Iter>
|
||||
static void
|
||||
extend(Container& container, Iter first, Iter last)
|
||||
{
|
||||
container.insert(container.end(), first, last);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void
|
||||
base_append(Container& container, object v)
|
||||
{
|
||||
extract<data_type&> elem(v);
|
||||
// try if elem is an exact Data
|
||||
if (elem.check())
|
||||
{
|
||||
DerivedPolicies::append(container, elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to convert elem to data_type
|
||||
extract<data_type> elem(v);
|
||||
if (elem.check())
|
||||
{
|
||||
DerivedPolicies::append(container, elem());
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Attempting to append an invalid type");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base_extend(Container& container, object v)
|
||||
{
|
||||
std::vector<data_type> temp;
|
||||
container_utils::extend_container(temp, v);
|
||||
DerivedPolicies::extend(container, temp.begin(), temp.end());
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // VECTOR_INDEXING_SUITE_JDG20036_HPP
|
||||
Reference in New Issue
Block a user