27 template<
typename A,
typename B>
29 return !(*it).first || !(*it).second;
32 template <
typename PythonType>
35 throw py::value_error(
"Please provide at least 5 elements for testing.");
39 auto result = PyObject_RichCompareBool(a.
ptr(), b.ptr(), Py_EQ);
41 checks.append(result != 0);
66 checks.append(static_cast<std::size_t>(x.end() - x.begin()) == x.size());
67 checks.append((x.begin() +
static_cast<std::ptrdiff_t
>(x.size())) == x.end());
68 checks.append(x.begin() < x.end());
77 Sliceable(
int n):
size(n) {}
83 .def(
"__getitem__",[](
const Sliceable &s,
py::slice slice) {
84 ssize_t start, stop, step, slicelength;
85 if (!slice.compute(s.size, &start, &stop, &step, &slicelength))
87 int istart =
static_cast<int>(start);
88 int istop =
static_cast<int>(stop);
89 int istep =
static_cast<int>(step);
97 Sequence(
size_t size) : m_size(size) {
99 m_data =
new float[
size];
100 memset(m_data, 0,
sizeof(
float) * size);
102 Sequence(
const std::vector<float> &
value) : m_size(value.size()) {
104 m_data =
new float[m_size];
105 memcpy(m_data, &value[0],
sizeof(
float) * m_size);
107 Sequence(
const Sequence &s) : m_size(s.m_size) {
109 m_data =
new float[m_size];
110 memcpy(m_data, s.m_data,
sizeof(
float)*m_size);
112 Sequence(Sequence &&s) : m_size(s.m_size), m_data(s.m_data) {
120 Sequence &operator=(
const Sequence &s) {
124 m_data =
new float[m_size];
125 memcpy(m_data, s.m_data,
sizeof(
float)*m_size);
131 Sequence &operator=(Sequence &&s) {
144 if (m_size != s.size())
return false;
145 for (
size_t i = 0;
i < m_size; ++
i)
146 if (m_data[
i] != s[
i])
152 float operator[](
size_t index)
const {
return m_data[index]; }
153 float &operator[](
size_t index) {
return m_data[index]; }
155 bool contains(
float v)
const {
156 for (
size_t i = 0;
i < m_size; ++
i)
162 Sequence reversed()
const {
163 Sequence result(m_size);
164 for (
size_t i = 0;
i < m_size; ++
i)
165 result[m_size -
i - 1] = m_data[
i];
169 size_t size()
const {
return m_size; }
171 const float *begin()
const {
return m_data; }
172 const float *
end()
const {
return m_data+m_size; }
179 .def(py::init<size_t>())
180 .def(
py::init<
const std::vector<float>&>())
182 .def(
"__getitem__", [](
const Sequence &s,
size_t i) {
186 .def(
"__setitem__", [](Sequence &s,
size_t i,
float v) {
194 .
def(
"__contains__", [](
const Sequence &s,
float v) {
return s.contains(v); })
195 .def(
"__reversed__", [](
const Sequence &s) -> Sequence {
return s.reversed(); })
197 .def(
"__getitem__", [](
const Sequence &s,
py::slice slice) -> Sequence* {
198 size_t start, stop, step, slicelength;
199 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength))
201 Sequence *seq =
new Sequence(slicelength);
202 for (
size_t i = 0; i < slicelength; ++
i) {
203 (*seq)[
i] = s[start]; start += step;
207 .def(
"__setitem__", [](Sequence &s,
py::slice slice,
const Sequence &
value) {
208 size_t start, stop, step, slicelength;
209 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength))
211 if (slicelength != value.size())
212 throw std::runtime_error(
"Left and right hand size of slice assignment have different sizes!");
213 for (
size_t i = 0; i < slicelength; ++
i) {
214 s[start] = value[
i]; start += step;
228 StringMap() =
default;
229 StringMap(std::unordered_map<std::string, std::string>
init)
232 void set(std::string key, std::string val) { map[key] = val; }
233 std::string
get(std::string key)
const {
return map.at(key); }
234 size_t size()
const {
return map.size(); }
236 std::unordered_map<std::string, std::string> map;
238 decltype(map.cbegin()) begin()
const {
return map.cbegin(); }
239 decltype(map.cend())
end()
const {
return map.cend(); }
243 .def(
py::init<std::unordered_map<std::string, std::string>>())
244 .def(
"__getitem__", [](
const StringMap &map, std::string key) {
245 try {
return map.get(key); }
246 catch (
const std::out_of_range&) {
250 .def(
"__setitem__", &StringMap::set)
262 const std::pair<int, int>* begin()
const {
return data_.data(); }
264 std::vector<std::pair<int, int>> data_;
267 .def(
py::init<std::vector<std::pair<int, int>>>())
268 .def(
"nonzero", [](
const IntPairs& s) {
271 .
def(
"nonzero_keys", [](
const IntPairs& s) {
282 struct PySequenceIterator {
283 PySequenceIterator(
const Sequence &seq,
py::object ref) : seq(seq),
ref(ref) { }
286 if (index == seq.size())
297 .def(
"__iter__", [](PySequenceIterator &it) -> PySequenceIterator& {
return it; })
298 .def(
"__next__", &PySequenceIterator::next);
300 On the actual Sequence object, the iterator would be constructed as follows:
301 .def(
"__iter__", [](
py::object s) {
return PySequenceIterator(s.
cast<
const Sequence &>(), s); })
307 for (auto item : o) {
315 while (it != py::iterator::sentinel()) {
333 return std::count_if(d.
begin(), d.
end(), [](std::pair<py::handle, py::handle> p) {
334 return p.second.cast<
int>() != 0;
338 m.def(
"tuple_iterator", &test_random_access_iterator<py::tuple>);
339 m.def(
"list_iterator", &test_random_access_iterator<py::list>);
340 m.def(
"sequence_iterator", &test_random_access_iterator<py::sequence>);
350 static std::vector<int> list = { 1, 2, 3 };
351 m.def(
"make_iterator_1", []() {
return py::make_iterator<py::return_value_policy::copy>(list); });
352 m.def(
"make_iterator_2", []() {
return py::make_iterator<py::return_value_policy::automatic>(list); });
iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra)
iterator end() const
Return a sentinel which ends iteration.
constexpr bool operator!=(const day &x, const day &y) noexcept
PyObject * ptr() const
Return the underlying PyObject * pointer.
void print_destroyed(T *inst, Values &&...values)
void print_copy_assigned(T *inst, Values &&...values)
void print_copy_created(T *inst, Values &&...values)
arr data(const arr &a, Ix... index)
bool is_none() const
Equivalent to obj is None in Python.
detail::initimpl::constructor< Args... > init()
Binds an existing constructor taking arguments Args...
void print_move_assigned(T *inst, Values &&...values)
test_initializer sequences_and_iterators("sequences_and_iterators", test_submodule_sequences_and_iterators)
detail::dict_iterator end() const
const T & operator*() const
py::list test_random_access_iterator(PythonType x)
NonZeroIterator & operator++()
Keep patient alive while nurse lives.
Reference counting helper.
NonZeroIterator(const T *ptr)
def assert_equal(actual, expected_data, expected_dtype)
bool operator==(const NonZeroIterator< std::pair< A, B >> &it, const NonZeroSentinel &)
void print_created(T *inst, Values &&...values)
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
void print_move_created(T *inst, Values &&...values)
iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra)
Makes a python iterator from a first and past-the-end C++ InputIterator.
#define TEST_SUBMODULE(name, variable)
detail::dict_iterator begin() const
bool typename Extra class_ & def(const char *name_, Func &&f, const Extra &... extra)