@@ -361,37 +361,45 @@ class PyRegionIterator {
361
361
362
362
// / Regions of an op are fixed length and indexed numerically so are represented
363
363
// / with a sequence-like container.
364
- class PyRegionList {
364
+ class PyRegionList : public Sliceable <PyRegionList, PyRegion> {
365
365
public:
366
- PyRegionList (PyOperationRef operation) : operation(std::move(operation)) {}
366
+ static constexpr const char *pyClassName = " RegionSequence" ;
367
+
368
+ PyRegionList (PyOperationRef operation, intptr_t startIndex = 0 ,
369
+ intptr_t length = -1 , intptr_t step = 1 )
370
+ : Sliceable(startIndex,
371
+ length == -1 ? mlirOperationGetNumRegions(operation->get ())
372
+ : length,
373
+ step),
374
+ operation(std::move(operation)) {}
367
375
368
376
PyRegionIterator dunderIter () {
369
377
operation->checkValid ();
370
378
return PyRegionIterator (operation);
371
379
}
372
380
373
- intptr_t dunderLen () {
381
+ static void bindDerived (ClassTy &c) {
382
+ c.def (" __iter__" , &PyRegionList::dunderIter);
383
+ }
384
+
385
+ private:
386
+ // / Give the parent CRTP class access to hook implementations below.
387
+ friend class Sliceable <PyRegionList, PyRegion>;
388
+
389
+ intptr_t getRawNumElements () {
374
390
operation->checkValid ();
375
391
return mlirOperationGetNumRegions (operation->get ());
376
392
}
377
393
378
- PyRegion dunderGetItem (intptr_t index) {
379
- // dunderLen checks validity.
380
- if (index < 0 || index >= dunderLen ()) {
381
- throw nb::index_error (" attempt to access out of bounds region" );
382
- }
383
- MlirRegion region = mlirOperationGetRegion (operation->get (), index );
384
- return PyRegion (operation, region);
394
+ PyRegion getRawElement (intptr_t pos) {
395
+ operation->checkValid ();
396
+ return PyRegion (operation, mlirOperationGetRegion (operation->get (), pos));
385
397
}
386
398
387
- static void bind (nb::module_ &m) {
388
- nb::class_<PyRegionList>(m, " RegionSequence" )
389
- .def (" __len__" , &PyRegionList::dunderLen)
390
- .def (" __iter__" , &PyRegionList::dunderIter)
391
- .def (" __getitem__" , &PyRegionList::dunderGetItem);
399
+ PyRegionList slice (intptr_t startIndex, intptr_t length, intptr_t step) {
400
+ return PyRegionList (operation, startIndex, length, step);
392
401
}
393
402
394
- private:
395
403
PyOperationRef operation;
396
404
};
397
405
@@ -450,6 +458,9 @@ class PyBlockList {
450
458
451
459
PyBlock dunderGetItem (intptr_t index) {
452
460
operation->checkValid ();
461
+ if (index < 0 ) {
462
+ index += dunderLen ();
463
+ }
453
464
if (index < 0 ) {
454
465
throw nb::index_error (" attempt to access out of bounds block" );
455
466
}
@@ -546,6 +557,9 @@ class PyOperationList {
546
557
547
558
nb::object dunderGetItem (intptr_t index) {
548
559
parentOperation->checkValid ();
560
+ if (index < 0 ) {
561
+ index += dunderLen ();
562
+ }
549
563
if (index < 0 ) {
550
564
throw nb::index_error (" attempt to access out of bounds operation" );
551
565
}
@@ -2629,6 +2643,9 @@ class PyOpAttributeMap {
2629
2643
}
2630
2644
2631
2645
PyNamedAttribute dunderGetItemIndexed (intptr_t index) {
2646
+ if (index < 0 ) {
2647
+ index += dunderLen ();
2648
+ }
2632
2649
if (index < 0 || index >= dunderLen ()) {
2633
2650
throw nb::index_error (" attempt to access out of bounds attribute" );
2634
2651
}
0 commit comments