GNU Octave  6.2.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-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 <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 = matrix.data ();
64  if (numel () == 1 && *p == ':')
65  return idx_vector (':');
66  else
67  return 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> (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> (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 (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 (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> (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> (matrix(0, 0));
152 
153  return retval;
154 }
155 
158 {
159  return NDArray (matrix);
160 }
161 
164 {
165  return FloatNDArray (matrix);
166 }
167 
170 {
171  return int8NDArray (matrix);
172 }
173 
176 {
177  return int16NDArray (matrix);
178 }
179 
182 {
183  return int32NDArray (matrix);
184 }
185 
188 {
189  return int64NDArray (matrix);
190 }
191 
194 {
195  return uint8NDArray (matrix);
196 }
197 
200 {
201  return uint16NDArray (matrix);
202 }
203 
206 {
207  return uint32NDArray (matrix);
208 }
209 
212 {
213  return uint64NDArray (matrix);
214 }
215 
216 void
218  bool pr_as_read_syntax) const
219 {
220  octave_print_internal (os, matrix, pr_as_read_syntax,
222 }
223 
224 mxArray *
226 {
228 
229  mxChar *pr = static_cast<mxChar *> (retval->get_data ());
230 
231  mwSize nel = numel ();
232 
233  const char *p = matrix.data ();
234 
235  for (mwIndex i = 0; i < nel; i++)
236  pr[i] = p[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 xisascii (int c)
247 {
248 #if defined (HAVE_ISASCII)
249  return isascii (c);
250 #else
251  return (c >= 0x00 && c <= 0x7f);
252 #endif
253 }
254 
257 {
259 
260  switch (umap)
261  {
262 #define STRING_MAPPER(UMAP,FCN,TYPE) \
263  case umap_ ## UMAP: \
264  return octave_value (matrix.map<TYPE, int (&) (int)> (FCN))
265 
267 
268 #define STRING_U8_MAPPER(UMAP,FCN) \
269  case umap_ ## UMAP: \
270  { \
271  charNDArray in_m = matrix; \
272  Array<octave_idx_type> p (dim_vector (matrix.ndims (), 1)); \
273  if (matrix.ndims () > 1) \
274  { \
275  for (octave_idx_type i=0; i < matrix.ndims (); i++) \
276  p(i) = i; \
277  p(0) = 1; \
278  p(1) = 0; \
279  in_m = matrix.permute (p); \
280  } \
281  boolNDArray b_array = boolNDArray (in_m.dims ()); \
282  const uint8_t *in = reinterpret_cast<const uint8_t *> (in_m.data ()); \
283  uint32_t uc; \
284  for (octave_idx_type i = 0; i < in_m.numel (); ) \
285  { \
286  int mblen = octave_u8_strmbtouc_wrapper (&uc, in + i); \
287  if (mblen < 1) \
288  mblen = 1; \
289  bool is_upper = FCN (uc); \
290  for (int j = 0; j < mblen; j++) \
291  b_array(i+j) = is_upper; \
292  i += mblen; \
293  } \
294  return octave_value ((matrix.ndims () > 1) ? b_array.permute (p, true) \
295  : b_array); \
296  }
297 
309 
310 #define STRING_U8_FCN(UMAP,U8_FCN,STD_FCN) \
311  case umap_ ## UMAP: \
312  { \
313  charNDArray in_m = matrix; \
314  Array<octave_idx_type> p (dim_vector (matrix.ndims (), 1)); \
315  if (matrix.ndims () > 1) \
316  { \
317  for (octave_idx_type i=0; i < matrix.ndims (); i++) \
318  p(i) = i; \
319  p(0) = 1; \
320  p(1) = 0; \
321  in_m = matrix.permute (p); \
322  } \
323  size_t output_length = in_m.numel (); \
324  charNDArray ch_array = charNDArray (in_m.dims ()); \
325  const uint8_t *in = reinterpret_cast<const uint8_t *> (in_m.data ()); \
326  uint8_t *buf = reinterpret_cast<uint8_t *> (ch_array.fortran_vec ()); \
327  U8_FCN (in, matrix.numel (), nullptr, buf, &output_length); \
328  if (output_length != static_cast<size_t> (matrix.numel ())) \
329  { \
330  warning_with_id ("Octave:multi_byte_char_length", \
331  "UMAP: Possible multi-byte error."); \
332  return octave_value (matrix.map<char, int (&) (int)> (STD_FCN)); \
333  } \
334  return octave_value ((matrix.ndims () > 1) ? ch_array.permute (p, true)\
335  : ch_array); \
336  }
337 
338  STRING_U8_FCN (xtolower, octave_u8_tolower_wrapper, std::tolower);
339  STRING_U8_FCN (xtoupper, octave_u8_toupper_wrapper, std::toupper);
340 
341  // For Matlab compatibility, these should work on ASCII values
342  // without error or warning.
343  case umap_abs:
344  case umap_ceil:
345  case umap_fix:
346  case umap_floor:
347  case umap_imag:
348  case umap_isinf:
349  case umap_isnan:
350  case umap_real:
351  case umap_round:
352  {
353  octave_matrix m (array_value (true));
354  return m.map (umap);
355  }
356 
357  default:
358  error ("%s: argument must be numeric", get_umap_name (umap));
359  break;
360  }
361 
362  return retval;
363 }
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:581
octave_idx_type numel(void) const
Definition: ov-base-mat.h:114
dim_vector dims(void) const
Definition: ov-base-mat.h:112
octave_idx_type columns(void) const
Definition: ov-base.h:325
int current_print_indent_level(void) const
Definition: ov-base.h:847
static const char * get_umap_name(unary_mapper_t)
Definition: ov-base.cc:1017
octave_idx_type rows(void) const
Definition: ov-base.h:318
octave_value as_double(void) const
Definition: ov-ch-mat.cc:157
mxArray * as_mxArray(void) const
Definition: ov-ch-mat.cc:225
octave_uint64 uint64_scalar_value() const
Definition: ov-ch-mat.cc:111
float float_value(bool=false) const
Definition: ov-ch-mat.cc:83
idx_vector index_vector(bool require_integers=false) const
Definition: ov-ch-mat.cc:61
Complex complex_value(bool=false) const
Definition: ov-ch-mat.cc:127
octave_value as_uint64(void) const
Definition: ov-ch-mat.cc:211
octave_value as_uint16(void) const
Definition: ov-ch-mat.cc:199
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:256
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_uint8(void) const
Definition: ov-ch-mat.cc:193
octave_value as_single(void) const
Definition: ov-ch-mat.cc:163
octave_value as_int16(void) const
Definition: ov-ch-mat.cc:175
octave_value as_int8(void) const
Definition: ov-ch-mat.cc:169
octave_value as_uint32(void) const
Definition: ov-ch-mat.cc:205
octave_value as_int32(void) const
Definition: ov-ch-mat.cc:181
NDArray array_value(bool=false) const
Definition: ov-ch-mat.h:120
double double_value(bool=false) const
Definition: ov-ch-mat.cc:71
octave_value as_int64(void) const
Definition: ov-ch-mat.cc:187
void error(const char *fmt,...)
Definition: error.cc:968
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
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(void)
Definition: lo-ieee.cc:126
void mxArray
Definition: mex.h:58
T octave_idx_type m
Definition: mx-inlines.cc:773
char mxChar
Definition: mxarray.in.h:87
OCTAVE_IDX_TYPE mwSize
Definition: mxarray.in.h:97
@ mxCHAR_CLASS
Definition: mxarray.in.h:62
OCTAVE_IDX_TYPE mwIndex
Definition: mxarray.in.h:98
@ mxREAL
Definition: mxarray.in.h:80
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
static int xisascii(int c)
Definition: ov-ch-mat.cc:246
#define STRING_U8_FCN(UMAP, U8_FCN, STD_FCN)
#define STRING_U8_MAPPER(UMAP, FCN)
#define STRING_MAPPER(UMAP, FCN, TYPE)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
void octave_print_internal(std::ostream &os, const float_display_format &fmt, bool d, bool pr_as_read_syntax)
Definition: pr-output.cc:1762
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)