get_ptr.c (10985B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include "stdlib/ndarray/ctor/get_ptr.h" 20 #include "stdlib/ndarray/ctor/ndarray.h" 21 #include "stdlib/ndarray/dtypes.h" 22 #include "stdlib/ndarray/index_modes.h" 23 #include "stdlib/ndarray/base/ind.h" 24 #include <stdlib.h> 25 #include <stdint.h> 26 #include <stdbool.h> 27 #include <complex.h> 28 29 /** 30 * Returns a pointer to an ndarray data element in the underlying byte array. 31 * 32 * @param arr input ndarray 33 * @param sub ndarray subscripts 34 * @return underlying byte array pointer 35 */ 36 uint8_t * stdlib_ndarray_get_ptr( const struct ndarray *arr, const int64_t *sub ) { 37 int8_t *submodes; 38 int64_t *strides; 39 int64_t *shape; 40 int64_t ndims; 41 uint8_t *idx; 42 int64_t ind; 43 int64_t M; 44 int64_t i; 45 46 ndims = arr->ndims; 47 shape = arr->shape; 48 strides = arr->strides; 49 submodes = arr->submodes; 50 M = arr->nsubmodes; 51 52 idx = (arr->data) + (arr->offset); // pointer arithmetic 53 for ( i = 0; i < ndims; i++ ) { 54 ind = stdlib_ndarray_ind( sub[ i ], shape[ i ]-1, submodes[ i%M ] ); 55 if ( ind < 0 ) { 56 return NULL; 57 } 58 idx += strides[ i ] * ind; // pointer arithmetic 59 } 60 return idx; 61 } 62 63 /** 64 * Returns an ndarray data element specified by a byte array pointer. 65 * 66 * ## Notes 67 * 68 * - The function does **not** perform bounds checking and **assumes** you know what you are doing. 69 * - The function returns `-1` if unable to get an element and `0` otherwise. 70 * - The function requires a `void` pointer for the output address `out` in order to provide a generic API supporting ndarrays having different data types. 71 * 72 * @param arr input ndarray 73 * @param idx byte array pointer to an ndarray data element 74 * @param out output address 75 * @return status code 76 */ 77 int8_t stdlib_ndarray_get_ptr_value( const struct ndarray *arr, const uint8_t *idx, void *out ) { 78 switch ( arr->dtype ) { 79 case STDLIB_NDARRAY_FLOAT64: 80 *(double *)out = *(double *)idx; 81 return 0; 82 case STDLIB_NDARRAY_FLOAT32: 83 *(float *)out = *(float *)idx; 84 return 0; 85 case STDLIB_NDARRAY_UINT64: 86 *(uint64_t *)out = *(uint64_t *)idx; 87 return 0; 88 case STDLIB_NDARRAY_INT64: 89 *(int64_t *)out = *(int64_t *)idx; 90 return 0; 91 case STDLIB_NDARRAY_UINT32: 92 *(uint32_t *)out = *(uint32_t *)idx; 93 return 0; 94 case STDLIB_NDARRAY_INT32: 95 *(int32_t *)out = *(int32_t *)idx; 96 return 0; 97 case STDLIB_NDARRAY_UINT16: 98 *(uint16_t *)out = *(uint16_t *)idx; 99 return 0; 100 case STDLIB_NDARRAY_INT16: 101 *(int16_t *)out = *(int16_t *)idx; 102 return 0; 103 case STDLIB_NDARRAY_UINT8: 104 *(uint8_t *)out = *(uint8_t *)idx; 105 return 0; 106 case STDLIB_NDARRAY_UINT8C: 107 *(uint8_t *)out = *(uint8_t *)idx; 108 return 0; 109 case STDLIB_NDARRAY_INT8: 110 *(int8_t *)out = *(int8_t *)idx; 111 return 0; 112 case STDLIB_NDARRAY_COMPLEX128: 113 *(double complex *)out = *(double complex *)idx; 114 return 0; 115 case STDLIB_NDARRAY_COMPLEX64: 116 *(float complex *)out = *(float complex *)idx; 117 return 0; 118 case STDLIB_NDARRAY_BOOL: 119 *(bool *)out = *(bool *)idx; 120 return 0; 121 default: 122 return -1; 123 } 124 } 125 126 /** 127 * Returns a double-precision floating-point ndarray data element specified by a byte array pointer. 128 * 129 * ## Notes 130 * 131 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 132 * - The function always returns `0`. 133 * 134 * @param idx byte array pointer to an ndarray data element 135 * @param out output address 136 * @return status code 137 */ 138 int8_t stdlib_ndarray_get_ptr_float64( const uint8_t *idx, double *out ) { 139 *out = *(double *)idx; 140 return 0; 141 } 142 143 /** 144 * Returns a single-precision floating-point ndarray data element specified by a byte array pointer. 145 * 146 * ## Notes 147 * 148 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 149 * - The function always returns `0`. 150 * 151 * @param idx byte array pointer to an ndarray data element 152 * @param out output address 153 * @return status code 154 */ 155 int8_t stdlib_ndarray_get_ptr_float32( const uint8_t *idx, float *out ) { 156 *out = *(float *)idx; 157 return 0; 158 } 159 160 /** 161 * Returns an unsigned 64-bit integer ndarray data element specified by a byte array pointer. 162 * 163 * ## Notes 164 * 165 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 166 * - The function always returns `0`. 167 * 168 * @param idx byte array pointer to an ndarray data element 169 * @param out output address 170 * @return status code 171 */ 172 int8_t stdlib_ndarray_get_ptr_uint64( const uint8_t *idx, uint64_t *out ) { 173 *out = *(uint64_t *)idx; 174 return 0; 175 } 176 177 /** 178 * Returns a signed 64-bit integer ndarray data element specified by a byte array pointer. 179 * 180 * ## Notes 181 * 182 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 183 * - The function always returns `0`. 184 * 185 * @param idx byte array pointer to an ndarray data element 186 * @param out output address 187 * @return status code 188 */ 189 int8_t stdlib_ndarray_get_ptr_int64( const uint8_t *idx, int64_t *out ) { 190 *out = *(int64_t *)idx; 191 return 0; 192 } 193 194 /** 195 * Returns an unsigned 32-bit integer ndarray data element specified by a byte array pointer. 196 * 197 * ## Notes 198 * 199 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 200 * - The function always returns `0`. 201 * 202 * @param idx byte array pointer to an ndarray data element 203 * @param out output address 204 * @return status code 205 */ 206 int8_t stdlib_ndarray_get_ptr_uint32( const uint8_t *idx, uint32_t *out ) { 207 *out = *(uint32_t *)idx; 208 return 0; 209 } 210 211 /** 212 * Returns a signed 32-bit integer ndarray data element specified by a byte array pointer. 213 * 214 * ## Notes 215 * 216 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 217 * - The function always returns `0`. 218 * 219 * @param idx byte array pointer to an ndarray data element 220 * @param out output address 221 * @return status code 222 */ 223 int8_t stdlib_ndarray_get_ptr_int32( const uint8_t *idx, int32_t *out ) { 224 *out = *(int32_t *)idx; 225 return 0; 226 } 227 228 /** 229 * Returns an unsigned 16-bit integer ndarray data element specified by a byte array pointer. 230 * 231 * ## Notes 232 * 233 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 234 * - The function always returns `0`. 235 * 236 * @param idx byte array pointer to an ndarray data element 237 * @param out output address 238 * @return status code 239 */ 240 int8_t stdlib_ndarray_get_ptr_uint16( const uint8_t *idx, uint16_t *out ) { 241 *out = *(uint16_t *)idx; 242 return 0; 243 } 244 245 /** 246 * Returns a signed 16-bit integer ndarray data element specified by a byte array pointer. 247 * 248 * ## Notes 249 * 250 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 251 * - The function always returns `0`. 252 * 253 * @param idx byte array pointer to an ndarray data element 254 * @param out output address 255 * @return status code 256 */ 257 int8_t stdlib_ndarray_get_ptr_int16( const uint8_t *idx, int16_t *out ) { 258 *out = *(int16_t *)idx; 259 return 0; 260 } 261 262 /** 263 * Returns an unsigned 8-bit integer ndarray data element specified by a byte array pointer. 264 * 265 * ## Notes 266 * 267 * - The function always returns `0`. 268 * 269 * @param idx byte array pointer to an ndarray data element 270 * @param out output address 271 * @return status code 272 */ 273 int8_t stdlib_ndarray_get_ptr_uint8( const uint8_t *idx, uint8_t *out ) { 274 *out = *(uint8_t *)idx; 275 return 0; 276 } 277 278 /** 279 * Returns a signed 8-bit integer ndarray data element specified by a byte array pointer. 280 * 281 * ## Notes 282 * 283 * - The function always returns `0`. 284 * 285 * @param idx byte array pointer to an ndarray data element 286 * @param out output address 287 * @return status code 288 */ 289 int8_t stdlib_ndarray_get_ptr_int8( const uint8_t *idx, int8_t *out ) { 290 *out = *(int8_t *)idx; 291 return 0; 292 } 293 294 /** 295 * Returns a double-precision complex floating-point ndarray data element specified by a byte array pointer. 296 * 297 * ## Notes 298 * 299 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 300 * - The function always returns `0`. 301 * 302 * @param idx byte array pointer to an ndarray data element 303 * @param out output address 304 * @return status code 305 */ 306 int8_t stdlib_ndarray_get_ptr_complex128( const uint8_t *idx, double complex *out ) { 307 *out = *(double complex *)idx; 308 return 0; 309 } 310 311 /** 312 * Returns a single-precision complex floating-point ndarray data element specified by a byte array pointer. 313 * 314 * ## Notes 315 * 316 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 317 * - The function always returns `0`. 318 * 319 * @param idx byte array pointer to an ndarray data element 320 * @param out output address 321 * @return status code 322 */ 323 int8_t stdlib_ndarray_get_ptr_complex64( const uint8_t *idx, float complex *out ) { 324 *out = *(float complex *)idx; 325 return 0; 326 } 327 328 /** 329 * Returns a boolean ndarray data element specified by a byte array pointer. 330 * 331 * ## Notes 332 * 333 * - The function has no way of determining whether `idx` actually points to a compatible memory address. Accordingly, accessing **unowned** memory is possible, and this function **assumes** you know what you are doing. 334 * - The function always returns `0`. 335 * 336 * @param idx byte array pointer to an ndarray data element 337 * @param out output address 338 * @return status code 339 */ 340 int8_t stdlib_ndarray_get_ptr_bool( const uint8_t *idx, bool *out ) { 341 *out = *(bool *)idx; 342 return 0; 343 }