GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
typecast.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2007-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <algorithm>
31 #include <limits>
32 
33 #include "mx-base.h"
34 
35 #include "defun.h"
36 #include "error.h"
37 #include "errwarn.h"
38 #include "ovl.h"
39 #include "unwind-prot.h"
40 
41 static dim_vector
43 {
44  if (old_dims.ndims () == 2 && old_dims(0) == 1)
45  return dim_vector (1, n);
46  else if (old_dims.ndims () == 2 && old_dims(0) == 0 && old_dims(1) == 0)
47  return dim_vector ();
48  else
49  return dim_vector (n, 1);
50 }
51 
52 template <typename ArrayType>
53 static void
54 get_data_and_bytesize (const ArrayType& array,
55  const void *& data,
56  octave_idx_type& byte_size,
57  dim_vector& old_dims,
59 {
60  // The array given may be a temporary, constructed from a scalar or sparse
61  // array. This will ensure the data will be deallocated after we exit.
62  frame.add_delete (new ArrayType (array));
63 
64  data = reinterpret_cast<const void *> (array.data ());
65  byte_size = array.byte_size ();
66 
67  old_dims = array.dims ();
68 }
69 
70 template <typename ArrayType>
71 static ArrayType
72 reinterpret_copy (const void *data, octave_idx_type byte_size,
73  const dim_vector& old_dims)
74 {
75  typedef typename ArrayType::element_type T;
76  octave_idx_type n = byte_size / sizeof (T);
77 
78  if (n * static_cast<int> (sizeof (T)) != byte_size)
79  error ("typecast: incorrect number of input values to make output value");
80 
81  ArrayType retval (get_vec_dims (old_dims, n));
82  T *dest = retval.fortran_vec ();
83  std::memcpy (dest, data, n * sizeof (T));
84 
85  return retval;
86 }
87 
88 template <typename ArrayType>
89 static ArrayType
90 reinterpret_int_copy (const void *data, octave_idx_type byte_size,
91  const dim_vector& old_dims)
92 {
93  typedef typename ArrayType::element_type T;
94  typedef typename T::val_type VT;
95  octave_idx_type n = byte_size / sizeof (T);
96 
97  if (n * static_cast<int> (sizeof (T)) != byte_size)
98  error ("typecast: incorrect number of input values to make output value");
99 
100  ArrayType retval (get_vec_dims (old_dims, n));
101  VT *dest = reinterpret_cast<VT *> (retval.fortran_vec ());
102  std::memcpy (dest, data, n * sizeof (VT));
103 
104  return retval;
105 }
106 
107 DEFUN (typecast, args, ,
108  doc: /* -*- texinfo -*-
109 @deftypefn {} {@var{y} =} typecast (@var{x}, "@var{class}")
110 Return a new array @var{y} resulting from interpreting the data of @var{x}
111 in memory as data of the numeric class @var{class}.
112 
113 Both the class of @var{x} and @var{class} must be one of the built-in
114 numeric classes:
115 
116 @example
117 @group
118 "logical"
119 "char"
120 "int8"
121 "int16"
122 "int32"
123 "int64"
124 "uint8"
125 "uint16"
126 "uint32"
127 "uint64"
128 "double"
129 "single"
130 "double complex"
131 "single complex"
132 @end group
133 @end example
134 
135 @noindent
136 the last two are only used with @var{class}; they indicate that a
137 complex-valued result is requested. Complex arrays are stored in memory as
138 consecutive pairs of real numbers. The sizes of integer types are given by
139 their bit counts. Both logical and char are typically one byte wide;
140 however, this is not guaranteed by C++. If your system is IEEE conformant,
141 single and double will be 4 bytes and 8 bytes wide, respectively.
142 @qcode{"logical"} is not allowed for @var{class}.
143 
144 If the input is a row vector, the return value is a row vector, otherwise it
145 is a column vector.
146 
147 If the bit length of @var{x} is not divisible by that of @var{class}, an
148 error occurs.
149 
150 An example of the use of typecast on a little-endian machine is
151 
152 @example
153 @group
154 @var{x} = uint16 ([1, 65535]);
155 typecast (@var{x}, "uint8")
156 @result{} [ 1, 0, 255, 255]
157 @end group
158 @end example
159 @seealso{cast, bitpack, bitunpack, swapbytes}
160 @end deftypefn */)
161 {
162  if (args.length () != 2)
163  print_usage ();
164 
166 
168 
169  const void *data = nullptr;
170  octave_idx_type byte_size = 0;
171  dim_vector old_dims;
172 
173  octave_value array = args(0);
174 
175  if (array.islogical ())
176  get_data_and_bytesize (array.bool_array_value (), data, byte_size,
177  old_dims, frame);
178  else if (array.is_string ())
179  get_data_and_bytesize (array.char_array_value (), data, byte_size,
180  old_dims, frame);
181  else if (array.isinteger ())
182  {
183  if (array.is_int8_type ())
184  get_data_and_bytesize (array.int8_array_value (), data, byte_size,
185  old_dims, frame);
186  else if (array.is_int16_type ())
187  get_data_and_bytesize (array.int16_array_value (), data, byte_size,
188  old_dims, frame);
189  else if (array.is_int32_type ())
190  get_data_and_bytesize (array.int32_array_value (), data, byte_size,
191  old_dims, frame);
192  else if (array.is_int64_type ())
193  get_data_and_bytesize (array.int64_array_value (), data, byte_size,
194  old_dims, frame);
195  else if (array.is_uint8_type ())
196  get_data_and_bytesize (array.uint8_array_value (), data, byte_size,
197  old_dims, frame);
198  else if (array.is_uint16_type ())
199  get_data_and_bytesize (array.uint16_array_value (), data, byte_size,
200  old_dims, frame);
201  else if (array.is_uint32_type ())
202  get_data_and_bytesize (array.uint32_array_value (), data, byte_size,
203  old_dims, frame);
204  else if (array.is_uint64_type ())
205  get_data_and_bytesize (array.uint64_array_value (), data, byte_size,
206  old_dims, frame);
207  else
208  assert (0);
209  }
210  else if (array.iscomplex ())
211  {
212  if (array.is_single_type ())
214  byte_size, old_dims, frame);
215  else
217  byte_size, old_dims, frame);
218  }
219  else if (array.isreal ())
220  {
221  if (array.is_single_type ())
222  get_data_and_bytesize (array.float_array_value (), data, byte_size,
223  old_dims, frame);
224  else
225  get_data_and_bytesize (array.array_value (), data, byte_size,
226  old_dims, frame);
227  }
228  else
229  error ("typecast: invalid input CLASS: %s",
230  array.class_name ().c_str ());
231 
232  std::string numclass = args(1).string_value ();
233  std::transform (numclass.begin (), numclass.end (), numclass.begin (),
234  tolower);
235 
236  if (numclass.size () == 0)
237  ;
238  else if (numclass == "char")
239  retval = octave_value (reinterpret_copy<charNDArray>
240  (data, byte_size, old_dims), array.is_dq_string () ? '"'
241  : '\'');
242  else if (numclass[0] == 'i')
243  {
244  if (numclass == "int8")
245  retval = reinterpret_int_copy<int8NDArray> (data, byte_size, old_dims);
246  else if (numclass == "int16")
247  retval = reinterpret_int_copy<int16NDArray> (data, byte_size, old_dims);
248  else if (numclass == "int32")
249  retval = reinterpret_int_copy<int32NDArray> (data, byte_size, old_dims);
250  else if (numclass == "int64")
251  retval = reinterpret_int_copy<int64NDArray> (data, byte_size, old_dims);
252  }
253  else if (numclass[0] == 'u')
254  {
255  if (numclass == "uint8")
256  retval = reinterpret_int_copy<uint8NDArray> (data, byte_size, old_dims);
257  else if (numclass == "uint16")
258  retval = reinterpret_int_copy<uint16NDArray> (data, byte_size,
259  old_dims);
260  else if (numclass == "uint32")
261  retval = reinterpret_int_copy<uint32NDArray> (data, byte_size,
262  old_dims);
263  else if (numclass == "uint64")
264  retval = reinterpret_int_copy<uint64NDArray> (data, byte_size,
265  old_dims);
266  }
267  else if (numclass == "single")
268  retval = reinterpret_copy<FloatNDArray> (data, byte_size, old_dims);
269  else if (numclass == "double")
270  retval = reinterpret_copy<NDArray> (data, byte_size, old_dims);
271  else if (numclass == "single complex")
272  retval = reinterpret_copy<FloatComplexNDArray> (data, byte_size,
273  old_dims);
274  else if (numclass == "double complex")
275  retval = reinterpret_copy<ComplexNDArray> (data, byte_size, old_dims);
276 
277  if (retval.is_undefined ())
278  error ("typecast: cannot convert to %s class", numclass.c_str ());
279 
280  return retval;
281 }
282 
283 /*
284 %!assert (typecast (int64 (0), "char"), char (zeros (1, 8)))
285 %!assert (typecast (int64 (0), "int8"), zeros (1, 8, "int8"))
286 %!assert (typecast (int64 (0), "uint8"), zeros (1, 8, "uint8"))
287 %!assert (typecast (int64 (0), "int16"), zeros (1, 4, "int16"))
288 %!assert (typecast (int64 (0), "uint16"), zeros (1, 4, "uint16"))
289 %!assert (typecast (int64 (0), "int32"), zeros (1, 2, "int32"))
290 %!assert (typecast (int64 (0), "uint32"), zeros (1, 2, "uint32"))
291 %!assert (typecast (int64 (0), "int64"), zeros (1, 1, "int64"))
292 %!assert (typecast (int64 (0), "uint64"), zeros (1, 1, "uint64"))
293 %!assert (typecast (int64 (0), "single"), zeros (1, 2, "single"))
294 %!assert (typecast (int64 (0), "double"), 0)
295 %!assert (typecast (int64 (0), "single complex"), single (0))
296 %!assert (typecast (int64 ([0 0]), "double complex"), 0)
297 
298 %!assert (typecast ([], "double"), [])
299 %!assert (typecast (0, "double"), 0)
300 %!assert (typecast (inf, "double"), inf)
301 %!assert (typecast (-inf, "double"), -inf)
302 %!assert (typecast (nan, "double"), nan)
303 
304 %!error typecast ()
305 %!error typecast (1)
306 %!error typecast (1, 2, 3)
307 %!error typecast (1, "invalid")
308 %!error typecast (int8 (0), "double")
309 */
310 
311 template <typename ArrayType>
312 ArrayType
313 do_bitpack (const boolNDArray& bitp)
314 {
315  typedef typename ArrayType::element_type T;
317  = bitp.numel () / (sizeof (T) * std::numeric_limits<unsigned char>::digits);
318 
319  if (n * static_cast<int> (sizeof (T)) *
320  std::numeric_limits<unsigned char>::digits != bitp.numel ())
321  error ("bitpack: incorrect number of bits to make up output value");
322 
323  ArrayType retval (get_vec_dims (bitp.dims (), n));
324 
325  const bool *bits = bitp.fortran_vec ();
326  char *packed = reinterpret_cast<char *> (retval.fortran_vec ());
327 
328  octave_idx_type m = n * sizeof (T);
329 
330  for (octave_idx_type i = 0; i < m; i++)
331  {
332  char c = bits[0];
333  for (int j = 1; j < std::numeric_limits<unsigned char>::digits; j++)
334  c |= bits[j] << j;
335 
336  packed[i] = c;
337  bits += std::numeric_limits<unsigned char>::digits;
338  }
339 
340  return retval;
341 }
342 
343 DEFUN (bitpack, args, ,
344  doc: /* -*- texinfo -*-
345 @deftypefn {} {@var{y} =} bitpack (@var{x}, @var{class})
346 Return a new array @var{y} resulting from interpreting the logical array
347 @var{x} as raw bit patterns for data of the numeric class @var{class}.
348 
349 @var{class} must be one of the built-in numeric classes:
350 
351 @example
352 @group
353 "double"
354 "single"
355 "double complex"
356 "single complex"
357 "char"
358 "int8"
359 "int16"
360 "int32"
361 "int64"
362 "uint8"
363 "uint16"
364 "uint32"
365 "uint64"
366 @end group
367 @end example
368 
369 The number of elements of @var{x} should be divisible by the bit length of
370 @var{class}. If it is not, excess bits are discarded. Bits come in
371 increasing order of significance, i.e., @code{x(1)} is bit 0, @code{x(2)} is
372 bit 1, etc.
373 
374 The result is a row vector if @var{x} is a row vector, otherwise it is a
375 column vector.
376 @seealso{bitunpack, typecast}
377 @end deftypefn */)
378 {
379  if (args.length () != 2)
380  print_usage ();
381 
382  if (! args(0).islogical ())
383  error ("bitpack: X must be a logical array");
384 
386 
387  boolNDArray bitp = args(0).bool_array_value ();
388 
389  std::string numclass = args(1).string_value ();
390 
391  if (numclass.size () == 0)
392  ;
393  else if (numclass == "char")
394  retval = octave_value (do_bitpack<charNDArray> (bitp), '\'');
395  else if (numclass[0] == 'i')
396  {
397  if (numclass == "int8")
398  retval = do_bitpack<int8NDArray> (bitp);
399  else if (numclass == "int16")
400  retval = do_bitpack<int16NDArray> (bitp);
401  else if (numclass == "int32")
402  retval = do_bitpack<int32NDArray> (bitp);
403  else if (numclass == "int64")
404  retval = do_bitpack<int64NDArray> (bitp);
405  }
406  else if (numclass[0] == 'u')
407  {
408  if (numclass == "uint8")
409  retval = do_bitpack<uint8NDArray> (bitp);
410  else if (numclass == "uint16")
411  retval = do_bitpack<uint16NDArray> (bitp);
412  else if (numclass == "uint32")
413  retval = do_bitpack<uint32NDArray> (bitp);
414  else if (numclass == "uint64")
415  retval = do_bitpack<uint64NDArray> (bitp);
416  }
417  else if (numclass == "single")
418  retval = do_bitpack<FloatNDArray> (bitp);
419  else if (numclass == "double")
420  retval = do_bitpack<NDArray> (bitp);
421  else if (numclass == "single complex")
422  retval = do_bitpack<FloatComplexNDArray> (bitp);
423  else if (numclass == "double complex")
424  retval = do_bitpack<ComplexNDArray> (bitp);
425 
426  if (retval.is_undefined ())
427  error ("bitpack: cannot pack to %s class", numclass.c_str ());
428 
429  return retval;
430 }
431 
432 /*
433 %!assert (bitpack (zeros (1, 8, "logical"), "char"), "\0")
434 %!assert (bitpack (zeros (1, 8, "logical"), "int8"), int8 (0))
435 %!assert (bitpack (zeros (1, 8, "logical"), "uint8"), uint8 (0))
436 %!assert (bitpack (zeros (1, 16, "logical"), "int16"), int16 (0))
437 %!assert (bitpack (zeros (1, 16, "logical"), "uint16"), uint16 (0))
438 %!assert (bitpack (zeros (1, 32, "logical"), "int32"), int32 (0))
439 %!assert (bitpack (zeros (1, 32, "logical"), "uint32"), uint32 (0))
440 %!assert (bitpack (zeros (1, 64, "logical"), "int64"), int64 (0))
441 %!assert (bitpack (zeros (1, 64, "logical"), "uint64"), uint64 (0))
442 %!assert (bitpack (zeros (1, 32, "logical"), "single"), single (0))
443 %!assert (bitpack (zeros (1, 64, "logical"), "double"), double (0))
444 %!assert (bitpack (zeros (1, 64, "logical"), "single complex"), single (0))
445 %!assert (bitpack (zeros (1, 128, "logical"), "double complex"), double (0))
446 
447 %!test <54931>
448 %! x = false (1, 32);
449 %! x(1) = true;
450 %! assert (bitpack (x, "uint32"), uint32 (1));
451 %! x([1, 9]) = true;
452 %! assert (bitpack (x, "uint32"), uint32 (257));
453 
454 %!error bitpack ()
455 %!error bitpack (1)
456 %!error bitpack (1, 2, 3)
457 %!error bitpack (1, "invalid")
458 %!error bitpack (1, "double")
459 %!error bitpack (false, "invalid")
460 %!error bitpack (false, "double")
461 */
462 
463 template <typename ArrayType>
465 do_bitunpack (const ArrayType& array)
466 {
467  typedef typename ArrayType::element_type T;
468  octave_idx_type n = array.numel () * sizeof (T)
469  * std::numeric_limits<unsigned char>::digits;
470 
471  boolNDArray retval (get_vec_dims (array.dims (), n));
472 
473  const char *packed = reinterpret_cast<const char *> (array.fortran_vec ());
474  bool *bits = retval.fortran_vec ();
475 
476  octave_idx_type m = n / std::numeric_limits<unsigned char>::digits;
477 
478  for (octave_idx_type i = 0; i < m; i++)
479  {
480  char c = packed[i];
481  bits[0] = c & 1;
482  for (int j = 1; j < std::numeric_limits<unsigned char>::digits; j++)
483  bits[j] = (c >>= 1) & 1;
484  bits += std::numeric_limits<unsigned char>::digits;
485  }
486 
487  return retval;
488 }
489 
490 DEFUN (bitunpack, args, ,
491  doc: /* -*- texinfo -*-
492 @deftypefn {} {@var{y} =} bitunpack (@var{x})
493 Return a logical array @var{y} corresponding to the raw bit patterns of
494 @var{x}.
495 
496 @var{x} must belong to one of the built-in numeric classes:
497 
498 @example
499 @group
500 "double"
501 "single"
502 "char"
503 "int8"
504 "int16"
505 "int32"
506 "int64"
507 "uint8"
508 "uint16"
509 "uint32"
510 "uint64"
511 @end group
512 @end example
513 
514 The result is a row vector if @var{x} is a row vector; otherwise, it is a
515 column vector.
516 @seealso{bitpack, typecast}
517 @end deftypefn */)
518 {
519  if (args.length () != 1)
520  print_usage ();
521 
522  if (! (args(0).isnumeric () || args(0).is_string ()))
523  error ("bitunpack: argument must be a number or a string");
524 
526 
527  octave_value array = args(0);
528 
529  if (array.is_string ())
530  retval = do_bitunpack (array.char_array_value ());
531  else if (array.isinteger ())
532  {
533  if (array.is_int8_type ())
534  retval = do_bitunpack (array.int8_array_value ());
535  else if (array.is_int16_type ())
537  else if (array.is_int32_type ())
539  else if (array.is_int64_type ())
541  else if (array.is_uint8_type ())
543  else if (array.is_uint16_type ())
545  else if (array.is_uint32_type ())
547  else if (array.is_uint64_type ())
549  else
550  assert (0);
551  }
552  else if (array.iscomplex ())
553  {
554  if (array.is_single_type ())
556  else
558  }
559  else if (array.isreal ())
560  {
561  if (array.is_single_type ())
563  else
564  retval = do_bitunpack (array.array_value ());
565  }
566  else
567  error ("bitunpack: invalid input class: %s",
568  array.class_name ().c_str ());
569 
570  return retval;
571 }
572 
573 /*
574 %!assert (bitunpack ("\0"), zeros (1, 8, "logical"))
575 %!assert (bitunpack (int8 (0)), zeros (1, 8, "logical"))
576 %!assert (bitunpack (uint8 (0)), zeros (1, 8, "logical"))
577 %!assert (bitunpack (int16 (0)), zeros (1, 16, "logical"))
578 %!assert (bitunpack (uint16 (0)), zeros (1, 16, "logical"))
579 %!assert (bitunpack (int32 (0)), zeros (1, 32, "logical"))
580 %!assert (bitunpack (uint32 (0)), zeros (1, 32, "logical"))
581 %!assert (bitunpack (int64 (0)), zeros (1, 64, "logical"))
582 %!assert (bitunpack (uint64 (0)), zeros (1, 64, "logical"))
583 %!assert (bitunpack (single (0)), zeros (1, 32, "logical"))
584 %!assert (bitunpack (double (0)), zeros (1, 64, "logical"))
585 %!assert (bitunpack (complex (single (0))), zeros (1, 64, "logical"))
586 %!assert (bitunpack (complex (double (0))), zeros (1, 128, "logical"))
587 
588 %!error bitunpack ()
589 %!error bitunpack (1, 2)
590 %!error bitunpack ({})
591 */
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:453
const T * fortran_vec(void) const
Size of the specified dimension.
Definition: Array.h:583
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:334
int32NDArray int32_array_value(void) const
Definition: ov.h:909
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:844
uint16NDArray uint16_array_value(void) const
Definition: ov.h:918
bool isreal(void) const
Definition: ov.h:691
bool is_uint16_type(void) const
Definition: ov.h:674
bool is_int8_type(void) const
Definition: ov.h:659
bool is_dq_string(void) const
Definition: ov.h:599
bool is_string(void) const
Definition: ov.h:593
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:831
charNDArray char_array_value(bool frc_str_conv=false) const
Definition: ov.h:850
bool isinteger(void) const
Definition: ov.h:683
std::string class_name(void) const
Definition: ov.h:1256
bool is_uint32_type(void) const
Definition: ov.h:677
int8NDArray int8_array_value(void) const
Definition: ov.h:903
bool is_int64_type(void) const
Definition: ov.h:668
int64NDArray int64_array_value(void) const
Definition: ov.h:912
uint8NDArray uint8_array_value(void) const
Definition: ov.h:915
bool is_int32_type(void) const
Definition: ov.h:665
bool is_uint64_type(void) const
Definition: ov.h:680
bool is_int16_type(void) const
Definition: ov.h:662
uint64NDArray uint64_array_value(void) const
Definition: ov.h:924
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:812
bool is_single_type(void) const
Definition: ov.h:651
uint32NDArray uint32_array_value(void) const
Definition: ov.h:921
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:835
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:815
bool is_uint8_type(void) const
Definition: ov.h:671
int16NDArray int16_array_value(void) const
Definition: ov.h:906
bool iscomplex(void) const
Definition: ov.h:694
bool islogical(void) const
Definition: ov.h:688
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void error(const char *fmt,...)
Definition: error.cc:968
ColumnVector transform(const Matrix &m, double x, double y, double z)
Definition: graphics.cc:5814
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
static void get_data_and_bytesize(const ArrayType &array, const void *&data, octave_idx_type &byte_size, dim_vector &old_dims, octave::unwind_protect &frame)
Definition: typecast.cc:54
ArrayType do_bitpack(const boolNDArray &bitp)
Definition: typecast.cc:313
static dim_vector get_vec_dims(const dim_vector &old_dims, octave_idx_type n)
Definition: typecast.cc:42
static ArrayType reinterpret_int_copy(const void *data, octave_idx_type byte_size, const dim_vector &old_dims)
Definition: typecast.cc:90
static ArrayType reinterpret_copy(const void *data, octave_idx_type byte_size, const dim_vector &old_dims)
Definition: typecast.cc:72
boolNDArray do_bitunpack(const ArrayType &array)
Definition: typecast.cc:465