mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
179 lines
5.6 KiB
C++
179 lines
5.6 KiB
C++
// (C) Copyright Greg Landrum 2003-2006.
|
|
// Derived from vector_indexing_suite.hpp,
|
|
// which is (C) Copyright Joel de Guzman 2003.
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
// is granted provided this copyright notice appears in all copies. This
|
|
// software is provided "as is" without express or implied warranty, and
|
|
// with no claim as to its suitability for any purpose.
|
|
|
|
#ifndef LIST_INDEXING_SUITE_GL20042_HPP
|
|
#define LIST_INDEXING_SUITE_GL20042_HPP
|
|
|
|
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
|
#include <boost/python/suite/indexing/indexing_suite.hpp>
|
|
#include <boost/python/suite/indexing/container_utils.hpp>
|
|
#include <boost/python/iterator.hpp>
|
|
|
|
#include "pyint_api.h"
|
|
|
|
namespace boost {
|
|
namespace python {
|
|
|
|
// Forward declaration
|
|
template <class Container, bool NoProxy, class DerivedPolicies>
|
|
class list_indexing_suite;
|
|
|
|
namespace detail {
|
|
template <class Container, bool NoProxy>
|
|
class final_list_derived_policies
|
|
: public list_indexing_suite<
|
|
Container, NoProxy, final_list_derived_policies<Container, NoProxy>> {
|
|
};
|
|
} // namespace detail
|
|
|
|
// 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_list_derived_policies<Container, NoProxy>>
|
|
class list_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::iterator iterator_type;
|
|
|
|
static typename mpl::if_<is_class<data_type>, data_type&, data_type>::type
|
|
get_item(Container& container, index_type i) {
|
|
iterator_type pos = moveToPos(container, i);
|
|
return *pos;
|
|
}
|
|
static object get_slice(Container& container, index_type from,
|
|
index_type to) {
|
|
Container res;
|
|
iterator_type beg = moveToPos(container, from);
|
|
iterator_type end = moveToPos(container, to);
|
|
std::copy(beg, end, res.begin());
|
|
return object(res);
|
|
}
|
|
static void set_item(Container& container, index_type i, data_type const& v) {
|
|
iterator_type pos = moveToPos(container, i);
|
|
*pos = v;
|
|
}
|
|
|
|
static void set_slice(Container& container, index_type from, index_type to,
|
|
data_type const& v) {
|
|
iterator_type beg = moveToPos(container, from);
|
|
iterator_type end = moveToPos(container, to);
|
|
container.erase(beg, end);
|
|
// FIX: didn't we just invalidate this iterator?
|
|
container.insert(beg, v);
|
|
}
|
|
template <class Iter>
|
|
static void set_slice(Container& container, index_type from, index_type to,
|
|
Iter first, Iter last) {
|
|
iterator_type beg = moveToPos(container, from);
|
|
iterator_type end = moveToPos(container, to);
|
|
container.erase(beg, end);
|
|
// FIX: didn't we just invalidate this iterator?
|
|
container.insert(beg, first, last);
|
|
}
|
|
|
|
static void delete_item(Container& container, index_type i) {
|
|
iterator_type pos = moveToPos(container, i);
|
|
container.erase(pos);
|
|
}
|
|
|
|
static void delete_slice(Container& container, index_type from,
|
|
index_type to) {
|
|
iterator_type beg = moveToPos(container, from);
|
|
iterator_type end = moveToPos(container, to);
|
|
container.erase(beg, end);
|
|
}
|
|
|
|
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) {
|
|
(void)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) {
|
|
(void)container;
|
|
return a < b;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
private:
|
|
static iterator_type moveToPos(Container& container, index_type i) {
|
|
iterator_type pos;
|
|
index_type idx = 0;
|
|
pos = container.begin();
|
|
while (idx < i && pos != container.end()) {
|
|
pos++;
|
|
idx++;
|
|
}
|
|
if (pos == container.end()) {
|
|
PyErr_SetObject(PyExc_IndexError, PyInt_FromLong(i));
|
|
python::throw_error_already_set();
|
|
}
|
|
return pos;
|
|
}
|
|
};
|
|
|
|
} // namespace python
|
|
} // namespace boost
|
|
|
|
#endif
|