📄 indexing_suite_detail.hpp
字号:
}
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -