GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Cell.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1999-2022 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 "idx-vector.h"
31
32#include "Cell.h"
33#include "error.h"
34#include "errwarn.h"
35#include "ovl.h"
36
38 : Array<octave_value> (ovl.cell_value ())
39{ }
40
41Cell::Cell (const string_vector& sv, bool trim)
43{
44 octave_idx_type n = sv.numel ();
45
46 if (n > 0)
47 {
48 resize (dim_vector (n, 1));
49
50 for (octave_idx_type i = 0; i < n; i++)
51 {
52 std::string s = sv[i];
53
54 if (trim)
55 {
56 std::size_t pos = s.find_last_not_of (' ');
57
58 s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
59 }
60
61 elem (i, 0) = s;
62 }
63 }
64}
65
66Cell::Cell (const std::list<std::string>& sl)
68{
69 octave_idx_type n = sl.size ();
70
71 if (n > 0)
72 {
73 resize (dim_vector (n, 1));
74
75 octave_value *dst = fortran_vec ();
76 auto p = sl.begin ();
77
78 for (octave_idx_type i = 0; i < n; i++)
79 dst[i] = *p++;
80 }
81}
82
84 : Array<octave_value> (sa.dims ())
85{
86 octave_idx_type n = sa.numel ();
87
88 octave_value *dst = fortran_vec ();
89 const std::string *src = sa.data ();
90
91 for (octave_idx_type i = 0; i < n; i++)
92 dst[i] = src[i];
93}
94
95// Set size to DV, filling with []. Then fill with as many elements of
96// SV as possible.
97
98Cell::Cell (const dim_vector& dv, const string_vector& sv, bool trim)
99 : Array<octave_value> (dv, Matrix ())
100{
101 octave_idx_type n = sv.numel ();
102
103 if (n > 0)
104 {
105 octave_idx_type m = numel ();
106
107 octave_idx_type len = (n > m ? m : n);
108
109 for (octave_idx_type i = 0; i < len; i++)
110 {
111 std::string s = sv[i];
112
113 if (trim)
114 {
115 std::size_t pos = s.find_last_not_of (' ');
116
117 s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
118 }
119
120 elem(i) = s;
121 }
122 }
123}
124
125bool
126Cell::iscellstr (void) const
127{
128 bool retval = true;
129
130 octave_idx_type n = numel ();
131
132 for (octave_idx_type i = 0; i < n; i++)
133 {
134 if (! elem(i).is_string ())
135 {
136 retval = false;
137 break;
138 }
139 }
140
141 return retval;
142}
143
146{
147 Array<std::string> retval (dims ());
148
149 octave_idx_type n = numel ();
150
151 for (octave_idx_type i = 0; i < n; i++)
152 retval.xelem (i) = elem (i).string_value ();
153
154 return retval;
155}
156
159{
160 octave_idx_type n = numel ();
161
162 string_vector retval (n);
163
164 for (octave_idx_type i = 0; i < n; i++)
165 retval.xelem (i) = elem (i).string_value ();
166
167 return retval;
168}
169
170Cell
171Cell::index (const octave_value_list& idx_arg, bool resize_ok) const
172{
173 Cell retval;
174
175 octave_idx_type n = idx_arg.length ();
176
177 // If we catch an indexing error in index_vector, we flag an error
178 // in index k. Ensure it is the right value before each idx_vector
179 // call. Same variable as used in for loop in default case.
180
181 octave_idx_type k = 0;
182
183 try
184 {
185 switch (n)
186 {
187 case 0:
188 warn_empty_index ("cell array");
189 retval = *this;
190 break;
191
192 case 1:
193 {
194 octave::idx_vector i = idx_arg(0).index_vector ();
195
196 retval = Array<octave_value>::index (i, resize_ok, Matrix ());
197 }
198 break;
199
200 case 2:
201 {
202 octave::idx_vector i = idx_arg(0).index_vector ();
203
204 k = 1;
205 octave::idx_vector j = idx_arg(1).index_vector ();
206
207 retval = Array<octave_value>::index (i, j, resize_ok, Matrix ());
208 }
209 break;
210
211 default:
212 {
214
215 for (k = 0; k < n; k++)
216 iv(k) = idx_arg(k).index_vector ();
217
218 retval = Array<octave_value>::index (iv, resize_ok, Matrix ());
219 }
220 break;
221 }
222 }
223 catch (octave::index_exception& ie)
224 {
225 // Rethrow to allow more info to be reported later.
226 ie.set_pos_if_unset (n, k+1);
227 throw;
228 }
229
230 return retval;
231}
232
233/*
234%% This behavior is required for Matlab compatibility.
235%!shared a
236%! a = {"foo", "bar"};
237%!assert (a(), a)
238%!error <invalid empty index expression> a{}
239*/
240
241void
242Cell::assign (const octave_value_list& idx_arg, const Cell& rhs,
243 const octave_value& fill_val)
244
245{
246 octave_idx_type len = idx_arg.length ();
247
249
250 for (octave_idx_type i = 0; i < len; i++)
251 {
252 try
253 {
254 ra_idx(i) = idx_arg(i).index_vector ();
255 }
256 catch (octave::index_exception& ie)
257 {
258 // Rethrow to allow more info to be reported later.
259 ie.set_pos (len, i+1);
260 throw;
261 }
262 }
263
264 Array<octave_value>::assign (ra_idx, rhs, fill_val);
265}
266
267void
269
270{
271 octave_idx_type len = idx_arg.length ();
272
274
275 for (octave_idx_type i = 0; i < len; i++)
276 try
277 {
278 ra_idx.xelem (i) = idx_arg(i).index_vector ();
279 }
280 catch (octave::index_exception& ie)
281 {
282 // Rethrow to allow more info to be reported later.
283 ie.set_pos (len, i+1);
284 throw;
285 }
286
288}
289
291Cell::nnz (void) const
292{
293 err_wrong_type_arg ("nnz", "cell array");
294}
295
296/*
297%!error <wrong type argument 'cell array'> nnz ({0, 1, 2})
298%!error <wrong type argument 'cell array'> nnz (cell ())
299%!error <wrong type argument 'cell array'> nnz ({"foo", "bar"})
300*/
301
302Cell
304{
305 Cell retval;
306
307 if (ndims () > 2)
308 error ("Cell::column: requires 2-D cell array");
309
310 if (i < 0 || i >= cols ())
311 error ("invalid column selection");
312
313 octave_idx_type nr = rows ();
314
315 retval.resize (dim_vector (nr, 1));
316
317 for (octave_idx_type j = 0; j < nr; j++)
318 retval.xelem (j) = elem (j, i);
319
320 return retval;
321}
322
323Cell
325{
326 return insert (rb, ra_idx);
327}
328
329Cell&
331{
333 return *this;
334}
335
336Cell&
338{
340 return *this;
341}
342
343Cell
344Cell::map (ctype_mapper fcn) const
345{
346 Cell retval (dims ());
347 octave_value *r = retval.fortran_vec ();
348
349 const octave_value *p = data ();
350
351 for (octave_idx_type i = 0; i < numel (); i++)
352 r[i] = ((p++)->*fcn) ();
353
354 return retval;
355}
356
359{
360 static octave_value rfv = octave_value (Matrix ());
361 return rfv;
362}
363
364Cell
366{
367 return Array<octave_value>::diag (k);
368}
369
370Cell
372{
373 return Array<octave_value>::diag (m, n);
374}
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:129
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:504
OCTARRAY_API Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
Definition: Array.cc:697
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:411
OCTARRAY_API void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Definition: Array.cc:1115
octave_idx_type cols(void) const
Definition: Array.h:457
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:487
octave_value & elem(octave_idx_type n)
Definition: Array.h:534
octave_idx_type rows(void) const
Definition: Array.h:449
OCTARRAY_API void resize(const dim_vector &dv, const octave_value &rfv)
Definition: Array.cc:1010
OCTARRAY_API Array< T, Alloc > & insert(const Array< T, Alloc > &a, const Array< octave_idx_type > &idx)
Insert an array into another at a specified position.
Definition: Array.cc:1588
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:616
OCTARRAY_API octave_value * fortran_vec(void)
Definition: Array.cc:1744
OCTARRAY_API void delete_elements(const octave::idx_vector &i)
Deleting elements.
Definition: Array.cc:1394
int ndims(void) const
Definition: Array.h:627
OCTARRAY_API Array< T, Alloc > diag(octave_idx_type k=0) const
Get the kth super or subdiagonal.
Definition: Array.cc:2521
Definition: Cell.h:43
Cell & insert(const Cell &a, octave_idx_type r, octave_idx_type c)
Definition: Cell.cc:330
bool iscellstr(void) const
Definition: Cell.cc:126
void assign(const octave_value_list &idx, const Cell &rhs, const octave_value &fill_val=Matrix())
Definition: Cell.cc:242
Cell column(octave_idx_type i) const
Definition: Cell.cc:303
octave_idx_type nnz(void) const
Definition: Cell.cc:291
Cell(void)=default
Cell concat(const Cell &rb, const Array< octave_idx_type > &ra_idx)
Definition: Cell.cc:324
Array< std::string > cellstr_value(void) const
Definition: Cell.cc:145
Cell index(const octave_value_list &idx, bool resize_ok=false) const
Definition: Cell.cc:171
Cell diag(octave_idx_type k=0) const
Definition: Cell.cc:365
void delete_elements(const octave_value_list &idx)
Definition: Cell.cc:268
octave_value resize_fill_value(void) const
Size of the specified dimension.
Definition: Cell.cc:358
Cell map(ctype_mapper) const
Definition: Cell.cc:344
string_vector string_vector_value(void) const
Definition: Cell.cc:158
Definition: dMatrix.h:42
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
void set_pos_if_unset(octave_idx_type nd_arg, octave_idx_type dim_arg)
void set_pos(octave_idx_type nd_arg, octave_idx_type dim_arg)
octave_idx_type length(void) const
Definition: ovl.h:113
std::string string_value(bool force=false) const
Definition: ov.h:1019
std::string & xelem(octave_idx_type i)
Definition: str-vec.h:108
octave_idx_type numel(void) const
Definition: str-vec.h:100
void error(const char *fmt,...)
Definition: error.cc:980
void warn_empty_index(const std::string &type_name)
Definition: errwarn.cc:336
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
const octave_base_value const Array< octave_idx_type > & ra_idx
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
F77_RET_T len
Definition: xerbla.cc:61