See array_assign.h for parameter documentation */
| 86 | |
| 87 | /* See array_assign.h for parameter documentation */ |
| 88 | NPY_NO_EXPORT int |
| 89 | raw_array_is_aligned(int ndim, npy_intp const *shape, |
| 90 | char *data, npy_intp const *strides, int alignment) |
| 91 | { |
| 92 | |
| 93 | /* |
| 94 | * The code below expects the following: |
| 95 | * * that alignment is a power of two, as required by the C standard. |
| 96 | * * that casting from pointer to uintp gives a sensible representation |
| 97 | * we can use bitwise operations on (perhaps *not* req. by C std, |
| 98 | * but assumed by glibc so it should be fine) |
| 99 | * * that casting stride from intp to uintp (to avoid dependence on the |
| 100 | * signed int representation) preserves remainder wrt alignment, so |
| 101 | * stride%a is the same as ((unsigned intp)stride)%a. Req. by C std. |
| 102 | * |
| 103 | * The code checks whether the lowest log2(alignment) bits of `data` |
| 104 | * and all `strides` are 0, as this implies that |
| 105 | * (data + n*stride)%alignment == 0 for all integers n. |
| 106 | */ |
| 107 | |
| 108 | if (alignment > 1) { |
| 109 | npy_uintp align_check = (npy_uintp)data; |
| 110 | int i; |
| 111 | |
| 112 | for (i = 0; i < ndim; i++) { |
| 113 | /* skip dim == 1 as it is not required to have stride 0 */ |
| 114 | if (shape[i] > 1) { |
| 115 | /* if shape[i] == 1, the stride is never used */ |
| 116 | align_check |= (npy_uintp)strides[i]; |
| 117 | } |
| 118 | else if (shape[i] == 0) { |
| 119 | /* an array with zero elements is always aligned */ |
| 120 | return 1; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | return npy_is_aligned((void *)align_check, alignment); |
| 125 | } |
| 126 | else if (alignment == 1) { |
| 127 | return 1; |
| 128 | } |
| 129 | else { |
| 130 | /* always return false for alignment == 0, which means cannot-be-aligned */ |
| 131 | return 0; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | NPY_NO_EXPORT int |
| 136 | IsAligned(PyArrayObject *ap) |
no test coverage detected