forked from M-Labs/nac3
lyken
fdfc80ca5f
Based on01c96396
: core/irrt: add Slice and Range and part of8f9d2d82
: core/ndstrides: implement ndarray indexing. Needed for implementing general ndarray indexing. Currently IRRT slice and range have nothing to do with NAC3's slice and range. The IRRT slice and range are currently there to implement ndarray specific features. However, in the future their definitions may be used to replace that of NAC3's. (NAC3's range is a [i32 x 3], IRRT's range is a proper struct. NAC3 does not have a slice struct).
47 lines
1016 B
C++
47 lines
1016 B
C++
#pragma once
|
|
|
|
#include "irrt/debug.hpp"
|
|
#include "irrt/int_types.hpp"
|
|
|
|
namespace {
|
|
namespace range {
|
|
template<typename T>
|
|
T len(T start, T stop, T step) {
|
|
// Reference:
|
|
// https://github.com/python/cpython/blob/9dbd12375561a393eaec4b21ee4ac568a407cdb0/Objects/rangeobject.c#L933
|
|
if (step > 0 && start < stop)
|
|
return 1 + (stop - 1 - start) / step;
|
|
else if (step < 0 && start > stop)
|
|
return 1 + (start - 1 - stop) / (-step);
|
|
else
|
|
return 0;
|
|
}
|
|
} // namespace range
|
|
|
|
/**
|
|
* @brief A Python range.
|
|
*/
|
|
template<typename T>
|
|
struct Range {
|
|
T start;
|
|
T stop;
|
|
T step;
|
|
|
|
/**
|
|
* @brief Calculate the `len()` of this range.
|
|
*/
|
|
template<typename SizeT>
|
|
T len() {
|
|
debug_assert(SizeT, step != 0);
|
|
return range::len(start, stop, step);
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
extern "C" {
|
|
using namespace range;
|
|
|
|
SliceIndex __nac3_range_slice_len(const SliceIndex start, const SliceIndex end, const SliceIndex step) {
|
|
return len(start, end, step);
|
|
}
|
|
} |