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