22 #include "pybind11/pybind11.h"
30 using namespace pybind11::literals;
37 uint64_t _uint64(py::handle
const & obj) {
39 return obj.cast<uint64_t>();
40 }
catch (py::cast_error
const &) {
41 throw py::value_error(
42 "RangeSet elements and range beginning and "
43 "end points must be non-negative integers "
50 RangeSet makeRangeSet(py::iterable iterable) {
52 for (py::handle item : iterable) {
53 PyObject *o = item.ptr();
54 if (PySequence_Check(o) && PySequence_Size(o) == 2) {
55 uint64_t
first = _uint64(py::reinterpret_steal<py::object>(
56 PySequence_GetItem(o, 0)));
57 uint64_t last = _uint64(py::reinterpret_steal<py::object>(
58 PySequence_GetItem(o, 1)));
59 rs.insert(
first, last);
61 rs.insert(_uint64(item));
68 py::list ranges(RangeSet
const &
self) {
71 list.append(py::make_tuple(py::int_(std::get<0>(t)),
72 py::int_(std::get<1>(t))));
84 py::class_<RangeSet, std::shared_ptr<RangeSet>>
cls(mod,
"RangeSet");
86 cls.def(py::init<>());
87 cls.def(py::init<uint64_t>(),
"integer"_a);
88 cls.def(py::init<uint64_t, uint64_t>(),
"first"_a,
"last"_a);
89 cls.def(py::init<RangeSet const &>(),
"rangeSet"_a);
91 [](py::iterable iterable) {
92 return new RangeSet(makeRangeSet(iterable));
96 cls.def(
"__eq__", &RangeSet::operator==, py::is_operator());
97 cls.def(
"__ne__", &RangeSet::operator!=, py::is_operator());
99 cls.def(
"insert", (
void (RangeSet::*)(uint64_t)) & RangeSet::insert,
102 (
void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::insert,
103 "first"_a,
"last"_a);
107 "first"_a,
"last"_a);
109 cls.def(
"complement", &RangeSet::complement);
110 cls.def(
"complemented", &RangeSet::complemented);
111 cls.def(
"intersection", &RangeSet::intersection,
"rangeSet"_a);
114 cls.def(
"union", &RangeSet::join,
"rangeSet"_a);
115 cls.def(
"difference", &RangeSet::difference,
"rangeSet"_a);
116 cls.def(
"symmetricDifference", &RangeSet::symmetricDifference,
118 cls.def(
"__invert__", &RangeSet::operator~, py::is_operator());
119 cls.def(
"__and__", &RangeSet::operator&, py::is_operator());
120 cls.def(
"__or__", &RangeSet::operator|, py::is_operator());
121 cls.def(
"__sub__", &RangeSet::operator-, py::is_operator());
122 cls.def(
"__xor__", &RangeSet::operator^, py::is_operator());
123 cls.def(
"__iand__", &RangeSet::operator&=);
124 cls.def(
"__ior__", &RangeSet::operator|=);
125 cls.def(
"__isub__", &RangeSet::operator-=);
126 cls.def(
"__ixor__", &RangeSet::operator^=);
128 cls.def(
"__len__", &RangeSet::size);
129 cls.def(
"__getitem__", [](RangeSet
const &
self, py::int_ i) {
130 auto j = python::convertIndex(
static_cast<ptrdiff_t
>(
self.size()), i);
131 return py::cast(
self.
begin()[j]);
134 cls.def(
"intersects",
135 (
bool (RangeSet::*)(uint64_t)
const) & RangeSet::intersects,
137 cls.def(
"intersects",
138 (
bool (RangeSet::*)(uint64_t, uint64_t)
const) &
139 RangeSet::intersects,
140 "first"_a,
"last"_a);
141 cls.def(
"intersects",
142 (
bool (RangeSet::*)(RangeSet
const &)
const) & RangeSet::intersects,
150 "first"_a,
"last"_a);
154 cls.def(
"__contains__",
156 "integer"_a, py::is_operator());
157 cls.def(
"__contains__",
159 "first"_a,
"last"_a, py::is_operator());
160 cls.def(
"__contains__",
162 "rangeSet"_a, py::is_operator());
165 (
bool (RangeSet::*)(uint64_t)
const) & RangeSet::isWithin,
168 (
bool (RangeSet::*)(uint64_t, uint64_t)
const) & RangeSet::isWithin,
169 "first"_a,
"last"_a);
171 (
bool (RangeSet::*)(RangeSet
const &)
const) & RangeSet::isWithin,
174 cls.def(
"isDisjointFrom",
175 (
bool (RangeSet::*)(uint64_t)
const) & RangeSet::isDisjointFrom,
177 cls.def(
"isDisjointFrom",
178 (
bool (RangeSet::*)(uint64_t, uint64_t)
const) &
179 RangeSet::isDisjointFrom,
180 "first"_a,
"last"_a);
181 cls.def(
"isDisjointFrom",
182 (
bool (RangeSet::*)(RangeSet
const &)
const) &
183 RangeSet::isDisjointFrom,
186 cls.def(
"simplify", &RangeSet::simplify,
"n"_a);
189 cls.def(
"scaled", &RangeSet::scaled,
"factor"_a);
190 cls.def(
"fill", &RangeSet::fill);
191 cls.def(
"clear", &RangeSet::clear);
192 cls.def(
"empty", &RangeSet::empty);
193 cls.def(
"full", &RangeSet::full);
194 cls.def(
"size", &RangeSet::size);
195 cls.def(
"cardinality", &RangeSet::cardinality);
198 cls.def(
"isValid", &RangeSet::cardinality);
199 cls.def(
"ranges", &ranges);
202 [](RangeSet
const &
self) {
return py::str(ranges(
self)); });
203 cls.def(
"__repr__", [](RangeSet
const &
self) {
204 return py::str(
"RangeSet({!s})").format(ranges(
self));
207 cls.def(
"__reduce__", [
cls](RangeSet
const &
self) {
208 return py::make_tuple(
cls, py::make_tuple(ranges(
self)));