GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-ch-mat.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 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 <cctype>
31 #include <ostream>
32 
33 #include "dNDArray.h"
34 #include "fNDArray.h"
35 #include "int8NDArray.h"
36 #include "int16NDArray.h"
37 #include "int32NDArray.h"
38 #include "int64NDArray.h"
39 #include "uint8NDArray.h"
40 #include "uint16NDArray.h"
41 #include "uint32NDArray.h"
42 #include "uint64NDArray.h"
43 
44 #include "lo-ieee.h"
45 #include "mx-base.h"
46 #include "unicase-wrappers.h"
47 #include "unictype-wrappers.h"
48 #include "unistr-wrappers.h"
49 
50 #include "mxarray.h"
51 #include "ov-base.h"
52 #include "ov-base-mat.h"
53 #include "ov-base-mat.cc"
54 #include "ov-ch-mat.h"
55 #include "errwarn.h"
56 #include "pr-output.h"
57 
58 template class octave_base_matrix<charNDArray>;
59 
61 octave_char_matrix::index_vector (bool /* require_integers */) const
62 {
63  const char *p = m_matrix.data ();
64  if (numel () == 1 && *p == ':')
65  return octave::idx_vector (':');
66  else
67  return octave::idx_vector (array_value (true));
68 }
69 
70 double
72 {
73  if (rows () == 0 || columns () == 0)
74  err_invalid_conversion ("character matrix", "real scalar");
75 
76  warn_implicit_conversion ("Octave:array-to-scalar",
77  "character matrix", "real scalar");
78 
79  return static_cast<unsigned char> (m_matrix(0, 0));
80 }
81 
82 float
84 {
85  if (rows () == 0 && columns () == 0)
86  err_invalid_conversion ("character matrix", "real scalar");
87 
88  warn_implicit_conversion ("Octave:array-to-scalar",
89  "character matrix", "real scalar");
90 
91  return static_cast<unsigned char> (m_matrix(0, 0));
92 }
93 
96 {
97  octave_int64 retval = 0;
98 
99  if (rows () == 0 || columns () == 0)
100  err_invalid_conversion ("character matrix", "int64 scalar");
101 
102  warn_implicit_conversion ("Octave:array-to-scalar",
103  "character matrix", "int64 scalar");
104 
105  retval = octave_int64 (m_matrix(0, 0));
106 
107  return retval;
108 }
109 
112 {
113  octave_uint64 retval = 0;
114 
115  if (rows () == 0 || columns () == 0)
116  err_invalid_conversion ("character matrix", "uint64 scalar");
117 
118  warn_implicit_conversion ("Octave:array-to-scalar",
119  "character matrix", "uint64 scalar");
120 
121  retval = octave_uint64 (m_matrix(0, 0));
122 
123  return retval;
124 }
125 
126 Complex
128 {
129  if (rows () == 0 && columns () == 0)
130  err_invalid_conversion ("character matrix", "complex scalar");
131 
132  warn_implicit_conversion ("Octave:array-to-scalar",
133  "character matrix", "complex scalar");
134 
135  return Complex (static_cast<unsigned char> (m_matrix(0, 0)), 0);
136 }
137 
140 {
141  float tmp = lo_ieee_float_nan_value ();
142 
143  FloatComplex retval (tmp, tmp);
144 
145  if (rows () == 0 || columns () == 0)
146  err_invalid_conversion ("character matrix", "complex scalar");
147 
148  warn_implicit_conversion ("Octave:array-to-scalar",
149  "character matrix", "complex scalar");
150 
151  retval = static_cast<unsigned char> (m_matrix(0, 0));
152 
153  return retval;
154 }
155 
158 {
159  return NDArray (m_matrix);
160 }
161 
164 {
165  return FloatNDArray (m_matrix);
166 }
167 
170 {
171  return int8NDArray (m_matrix);
172 }
173 
176 {
177  return int16NDArray (m_matrix);
178 }
179 
182 {
183  return int32NDArray (m_matrix);
184 }
185 
188 {
189  return int64NDArray (m_matrix);
190 }
191 
194 {
195  return uint8NDArray (m_matrix);
196 }
197 
200 {
201  return uint16NDArray (m_matrix);
202 }
203 
206 {
207  return uint32NDArray (m_matrix);
208 }
209 
212 {
213  return uint64NDArray (m_matrix);
214 }
215 
216 void
218  bool pr_as_read_syntax) const
219 {
220  octave_print_internal (os, m_matrix, pr_as_read_syntax,
222 }
223 
224 mxArray *
225 octave_char_matrix::as_mxArray (bool interleaved) const
226 {
227  mxArray *retval = new mxArray (interleaved, mxCHAR_CLASS, dims (), mxREAL);
228 
229  mxChar *pd = static_cast<mxChar *> (retval->get_data ());
230 
231  mwSize nel = numel ();
232 
233  const char *pdata = m_matrix.data ();
234 
235  for (mwIndex i = 0; i < nel; i++)
236  pd[i] = pdata[i];
237 
238  return retval;
239 }
240 
241 // The C++ standard guarantees cctype defines functions, not macros (and
242 // hence macros *CAN'T* be defined if only cctype is included) so
243 // there's no need to fuck around. The exceptions are isascii and
244 // toascii, which are not C++. Oddly enough, all those character
245 // functions are int (*) (int), even in C++. Wicked!
246 static inline int
247 xisascii (int c)
248 {
249 #if defined (HAVE_ISASCII)
250  return isascii (c);
251 #else
252  return (c >= 0x00 && c <= 0x7f);
253 #endif
254 }
255 
258 {
259  octave_value retval;
260 
261  switch (umap)
262  {
263 #define STRING_MAPPER(UMAP,FCN,TYPE) \
264  case umap_ ## UMAP: \
265  return octave_value (m_matrix.map<TYPE, int (&) (int)> (FCN))
266 
267  STRING_MAPPER (xisascii, xisascii, bool);
268 
269 #define STRING_U8_MAPPER(UMAP,FCN) \
270  case umap_ ## UMAP: \
271  { \
272  charNDArray in_m = m_matrix; \
273  Array<octave_idx_type> p (dim_vector (m_matrix.ndims (), 1)); \
274  if (m_matrix.ndims () > 1) \
275  { \
276  for (octave_idx_type i=0; i < m_matrix.ndims (); i++) \
277  p(i) = i; \
278  p(0) = 1; \
279  p(1) = 0; \
280  in_m = m_matrix.permute (p); \
281  } \
282  boolNDArray b_array = boolNDArray (in_m.dims ()); \
283  const uint8_t *in = reinterpret_cast<const uint8_t *> (in_m.data ()); \
284  uint32_t uc; \
285  for (octave_idx_type i = 0; i < in_m.numel (); ) \
286  { \
287  int mblen = octave_u8_strmbtouc_wrapper (&uc, in + i); \
288  if (mblen < 1) \
289  mblen = 1; \
290  bool is_upper = FCN (uc); \
291  for (int j = 0; j < mblen; j++) \
292  b_array(i+j) = is_upper; \
293  i += mblen; \
294  } \
295  return octave_value ((m_matrix.ndims () > 1) ? b_array.permute (p, true) \
296  : b_array); \
297  }
298 
310 
311 #define STRING_U8_FCN(UMAP,U8_FCN,STD_FCN) \
312  case umap_ ## UMAP: \
313  { \
314  charNDArray in_m = m_matrix; \
315  Array<octave_idx_type> p (dim_vector (m_matrix.ndims (), 1)); \
316  if (m_matrix.ndims () > 1) \
317  { \
318  for (octave_idx_type i=0; i < m_matrix.ndims (); i++) \
319  p(i) = i; \
320  p(0) = 1; \
321  p(1) = 0; \
322  in_m = m_matrix.permute (p); \
323  } \
324  std::size_t output_length = in_m.numel (); \
325  charNDArray ch_array = charNDArray (in_m.dims ()); \
326  const uint8_t *in = reinterpret_cast<const uint8_t *> (in_m.data ()); \
327  uint8_t *buf = reinterpret_cast<uint8_t *> (ch_array.fortran_vec ()); \
328  U8_FCN (in, m_matrix.numel (), nullptr, buf, &output_length); \
329  if (output_length != static_cast<std::size_t> (m_matrix.numel ())) \
330  { \
331  warning_with_id ("Octave:multi_byte_char_length", \
332  "UMAP: Possible multi-byte error."); \
333  return octave_value (m_matrix.map<char, int (&) (int)> (STD_FCN)); \
334  } \
335  return octave_value ((m_matrix.ndims () > 1) ? ch_array.permute (p, true)\
336  : ch_array); \
337  }
338 
339  STRING_U8_FCN (xtolower, octave_u8_tolower_wrapper, std::tolower);
340  STRING_U8_FCN (xtoupper, octave_u8_toupper_wrapper, std::toupper);
341 
342  // For Matlab compatibility, these should work on ASCII values
343  // without error or warning.
344  case umap_abs:
345  case umap_ceil:
346  case umap_fix:
347  case umap_floor:
348  case umap_imag:
349  case umap_isfinite:
350  case umap_isinf:
351  case umap_isnan:
352  case umap_real:
353  case umap_round:
354  {
355  octave_matrix m (array_value (true));
356  return m.map (umap);
357  }
358 
359  default:
360  error ("%s: argument must be numeric", get_umap_name (umap));
361  break;
362  }
363 
364  return retval;
365 }
const T * data() const
Size of the specified dimension.
Definition: Array.h:663
void * get_data() const
Definition: mxarray.h:473
octave_idx_type numel() const
Definition: ov-base-mat.h:122
octave_idx_type rows() const
Definition: ov-base.h:374
octave_idx_type columns() const
Definition: ov-base.h:381
int current_print_indent_level() const
Definition: ov-base.h:920
static const char * get_umap_name(unary_mapper_t)
Definition: ov-base.cc:1084
octave_value as_single() const
Definition: ov-ch-mat.cc:163
octave_value as_uint64() const
Definition: ov-ch-mat.cc:211
octave::idx_vector index_vector(bool require_integers=false) const
Definition: ov-ch-mat.cc:61
octave_value as_int8() const
Definition: ov-ch-mat.cc:169
octave_uint64 uint64_scalar_value() const
Definition: ov-ch-mat.cc:111
octave_value as_int16() const
Definition: ov-ch-mat.cc:175
float float_value(bool=false) const
Definition: ov-ch-mat.cc:83
Complex complex_value(bool=false) const
Definition: ov-ch-mat.cc:127
mxArray * as_mxArray(bool interleaved) const
Definition: ov-ch-mat.cc:225
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov-ch-mat.cc:217
octave_value map(unary_mapper_t umap) const
Definition: ov-ch-mat.cc:257
octave_value as_int32() const
Definition: ov-ch-mat.cc:181
octave_int64 int64_scalar_value() const
Definition: ov-ch-mat.cc:95
FloatComplex float_complex_value(bool=false) const
Definition: ov-ch-mat.cc:139
octave_value as_double() const
Definition: ov-ch-mat.cc:157
octave_value as_uint16() const
Definition: ov-ch-mat.cc:199
octave_value as_int64() const
Definition: ov-ch-mat.cc:187
octave_value as_uint8() const
Definition: ov-ch-mat.cc:193
octave_value as_uint32() const
Definition: ov-ch-mat.cc:205
NDArray array_value(bool=false) const
Definition: ov-ch-mat.h:120
double double_value(bool=false) const
Definition: ov-ch-mat.cc:71
void() error(const char *fmt,...)
Definition: error.cc:988
void err_invalid_conversion(const std::string &from, const std::string &to)
Definition: errwarn.cc:71
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:344
octave::idx_vector idx_vector
Definition: idx-vector.h:1022
intNDArray< octave_int16 > int16NDArray
Definition: int16NDArray.h:36
intNDArray< octave_int32 > int32NDArray
Definition: int32NDArray.h:36
intNDArray< octave_int64 > int64NDArray
Definition: int64NDArray.h:36
intNDArray< octave_int8 > int8NDArray
Definition: int8NDArray.h:36
float lo_ieee_float_nan_value()
Definition: lo-ieee.cc:116
void mxArray
Definition: mex.h:58
T octave_idx_type m
Definition: mx-inlines.cc:781
char mxChar
Definition: mxtypes.h:87
@ mxCHAR_CLASS
Definition: mxtypes.h:62
int64_t mwIndex
Definition: mxtypes.h:125
@ mxREAL
Definition: mxtypes.h:80
int64_t mwSize
Definition: mxtypes.h:124
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
octave_int< int64_t > octave_int64
octave_int< uint64_t > octave_uint64
#define STRING_U8_FCN(UMAP, U8_FCN, STD_FCN)
#define STRING_U8_MAPPER(UMAP, FCN)
#define STRING_MAPPER(UMAP, FCN, TYPE)
void octave_print_internal(std::ostream &os, const float_display_format &fmt, bool d, bool pr_as_read_syntax)
Definition: pr-output.cc:1761
intNDArray< octave_uint16 > uint16NDArray
Definition: uint16NDArray.h:36
intNDArray< octave_uint32 > uint32NDArray
Definition: uint32NDArray.h:36
intNDArray< octave_uint64 > uint64NDArray
Definition: uint64NDArray.h:36
intNDArray< octave_uint8 > uint8NDArray
Definition: uint8NDArray.h:36
uint8_t * octave_u8_toupper_wrapper(const uint8_t *s, size_t n, const char *iso639_language, uint8_t *resultbuf, size_t *lengthp)
uint8_t * octave_u8_tolower_wrapper(const uint8_t *s, size_t n, const char *iso639_language, uint8_t *resultbuf, size_t *lengthp)
bool octave_uc_is_upper_wrapper(ucs4_t uc)
bool octave_uc_is_digit_wrapper(ucs4_t uc)
bool octave_uc_is_lower_wrapper(ucs4_t uc)
bool octave_uc_is_print_wrapper(ucs4_t uc)
bool octave_uc_is_alnum_wrapper(ucs4_t uc)
bool octave_uc_is_space_wrapper(ucs4_t uc)
bool octave_uc_is_cntrl_wrapper(ucs4_t uc)
bool octave_uc_is_xdigit_wrapper(ucs4_t uc)
bool octave_uc_is_alpha_wrapper(ucs4_t uc)
bool octave_uc_is_graph_wrapper(ucs4_t uc)
bool octave_uc_is_punct_wrapper(ucs4_t uc)