GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
jsonencode.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2020-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 "builtin-defun-decls.h"
31#include "defun.h"
32#include "error.h"
33#include "errwarn.h"
34#include "oct-string.h"
35#include "ovl.h"
36
37#if defined (HAVE_RAPIDJSON)
38# include <rapidjson/stringbuffer.h>
39# include <rapidjson/writer.h>
40# if defined (HAVE_RAPIDJSON_PRETTYWRITER)
41# include <rapidjson/prettywriter.h>
42# endif
43#endif
44
45#if defined (HAVE_RAPIDJSON)
46
47//! Encodes a scalar Octave value into a numerical JSON value.
48//!
49//! @param writer RapidJSON's writer that is responsible for generating JSON.
50//! @param obj scalar Octave value.
51//! @param ConvertInfAndNaN @c bool that converts @c Inf and @c NaN to @c null.
52//!
53//! @b Example:
54//!
55//! @code{.cc}
56//! octave_value obj (7);
57//! encode_numeric (writer, obj, true);
58//! @endcode
59
60template <typename T> void
61encode_numeric (T& writer, const octave_value& obj,
62 const bool& ConvertInfAndNaN)
63{
64 if (obj.isfloat ())
65 {
66 double value = obj.scalar_value ();
67
68 // Detect floating point numbers which are actually integers by checking
69 // whether the number and the integer portion of the number are the same
70 // to within eps.
71 // FIXME: If value > 999999, MATLAB will encode it in scientific
72 // notation, but rapidJSON will output all digits.
73 if (fabs (trunc (value) - value) < std::numeric_limits<double>::epsilon ())
74
75 writer.Int64 (value);
76 // Possibly write NULL for non-finite values (-Inf, Inf, NaN, NA)
77 else if (ConvertInfAndNaN && ! octave::math::isfinite (value))
78 writer.Null ();
79 else
80 writer.Double (value);
81 }
82 else if (obj.isinteger ())
83 {
84 if (obj.is_uint64_type ())
85 {
86 uint64_t value = obj.uint64_value ();
87 writer.Uint64 (value);
88 }
89 else
90 {
91 // Write all other integers as 64-bit values and let RapidJSON
92 // determine number of digits to keep.
93 int64_t value = obj.int64_value ();
94 writer.Int64 (value);
95 }
96 }
97 else if (obj.is_bool_scalar ())
98 writer.Bool (obj.bool_value ());
99 else
100 error ("jsonencode: unsupported type");
101}
102
103//! Encodes character vectors and arrays into JSON strings.
104//!
105//! @param writer RapidJSON's writer that is responsible for generating JSON.
106//! @param obj character vectors or character arrays.
107//! @param original_dims The original dimensions of the array being encoded.
108//! @param level The level of recursion for the function.
109//!
110//! @b Example:
111//!
112//! @code{.cc}
113//! octave_value obj ("foo");
114//! encode_string (writer, obj, true);
115//! @endcode
116
117template <typename T> void
118encode_string (T& writer, const octave_value& obj,
119 const dim_vector& original_dims, int level = 0)
120{
121 charNDArray array = obj.char_array_value ();
122
123 if (array.isempty ())
124 writer.String ("");
125 else if (array.isvector ())
126 {
127 // Handle the special case where the input is a vector with more than
128 // 2 dimensions (e.g. cat (8, ['a'], ['c'])). In this case, we don't
129 // split the inner vectors of the input; we merge them into one.
130 if (level == 0)
131 {
132 std::string char_vector = "";
133 for (octave_idx_type i = 0; i < array.numel (); ++i)
134 char_vector += array(i);
135 writer.String (char_vector.c_str ());
136 }
137 else
138 for (octave_idx_type i = 0; i < array.numel () / original_dims(1); ++i)
139 {
140 std::string char_vector = "";
141 for (octave_idx_type k = 0; k < original_dims(1); ++k)
142 char_vector += array(i * original_dims(1) + k);
143 writer.String (char_vector.c_str ());
144 }
145 }
146 else
147 {
148 octave_idx_type idx;
149 octave_idx_type ndims = array.ndims ();
150 dim_vector dims = array.dims ();
151
152 // In this case, we already have a vector. So, we transform it to 2-D
153 // vector in order to be detected by "isvector" in the recursive call
154 if (dims.num_ones () == ndims - 1)
155 {
156 // Handle the special case when the input is a vector with more than
157 // 2 dimensions (e.g. cat (8, ['a'], ['c'])). In this case, we don't
158 // add dimension brackets and treat it as if it is a vector
159 if (level != 0)
160 // Place an opening and a closing bracket (represents a dimension)
161 // for every dimension that equals 1 until we reach the 2-D vector
162 for (int i = level; i < ndims - 1; ++i)
163 writer.StartArray ();
164
165 encode_string (writer, array.as_row (), original_dims, level);
166
167 if (level != 0)
168 for (int i = level; i < ndims - 1; ++i)
169 writer.EndArray ();
170 }
171 else
172 {
173 // We place an opening and a closing bracket for each dimension
174 // that equals 1 to preserve the number of dimensions when decoding
175 // the array after encoding it.
176 if (original_dims(level) == 1 && level != 1)
177 {
178 writer.StartArray ();
179 encode_string (writer, array, original_dims, level + 1);
180 writer.EndArray ();
181 }
182 else
183 {
184 // The second dimension contains the number of the chars in
185 // the char vector. We want to treat them as a one object,
186 // so we replace it with 1
187 dims(1) = 1;
188
189 for (idx = 0; idx < ndims; ++idx)
190 if (dims(idx) != 1)
191 break;
192 // Create the dimensions that will be used to call "num2cell"
193 // We called "num2cell" to divide the array to smaller sub-arrays
194 // in order to encode it recursively.
195 // The recursive encoding is necessary to support encoding of
196 // higher-dimensional arrays.
197 RowVector conversion_dims;
198 conversion_dims.resize (ndims - 1);
199 for (octave_idx_type i = 0; i < idx; ++i)
200 conversion_dims(i) = i + 1;
201 for (octave_idx_type i = idx ; i < ndims - 1; ++i)
202 conversion_dims(i) = i + 2;
203
204 octave_value_list args (obj);
205 args.append (conversion_dims);
206
207 Cell sub_arrays = octave::Fnum2cell (args)(0).cell_value ();
208
209 writer.StartArray ();
210
211 for (octave_idx_type i = 0; i < sub_arrays.numel (); ++i)
212 encode_string (writer, sub_arrays(i), original_dims,
213 level + 1);
214
215 writer.EndArray ();
216 }
217 }
218 }
219}
220
221//! Encodes a struct Octave value into a JSON object or a JSON array depending
222//! on the type of the struct (scalar struct or struct array.)
223//!
224//! @param writer RapidJSON's writer that is responsible for generating JSON.
225//! @param obj struct Octave value.
226//! @param ConvertInfAndNaN @c bool that converts @c Inf and @c NaN to @c null.
227//!
228//! @b Example:
229//!
230//! @code{.cc}
231//! octave_value obj (octave_map ());
232//! encode_struct (writer, obj,true);
233//! @endcode
234
235template <typename T> void
236encode_struct (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN)
237{
238 octave_map struct_array = obj.map_value ();
239 octave_idx_type numel = struct_array.numel ();
240 bool is_array = (numel != 1);
241 string_vector keys = struct_array.keys ();
242
243 if (is_array)
244 writer.StartArray ();
245
246 for (octave_idx_type i = 0; i < numel; ++i)
247 {
248 writer.StartObject ();
249 for (octave_idx_type k = 0; k < keys.numel (); ++k)
250 {
251 writer.Key (keys(k).c_str ());
252 encode (writer, struct_array(i).getfield (keys(k)), ConvertInfAndNaN);
253 }
254 writer.EndObject ();
255 }
256
257 if (is_array)
258 writer.EndArray ();
259}
260
261//! Encodes a Cell Octave value into a JSON array
262//!
263//! @param writer RapidJSON's writer that is responsible for generating JSON.
264//! @param obj Cell Octave value.
265//! @param ConvertInfAndNaN @c bool that converts @c Inf and @c NaN to @c null.
266//!
267//! @b Example:
268//!
269//! @code{.cc}
270//! octave_value obj (cell ());
271//! encode_cell (writer, obj,true);
272//! @endcode
273
274template <typename T> void
275encode_cell (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN)
276{
277 Cell cell = obj.cell_value ();
278
279 writer.StartArray ();
280
281 for (octave_idx_type i = 0; i < cell.numel (); ++i)
282 encode (writer, cell(i), ConvertInfAndNaN);
283
284 writer.EndArray ();
285}
286
287//! Encodes a numeric or logical Octave array into a JSON array
288//!
289//! @param writer RapidJSON's writer that is responsible for generating JSON.
290//! @param obj numeric or logical Octave array.
291//! @param ConvertInfAndNaN @c bool that converts @c Inf and @c NaN to @c null.
292//! @param original_dims The original dimensions of the array being encoded.
293//! @param level The level of recursion for the function.
294//! @param is_logical optional @c bool that indicates if the array is logical.
295//!
296//! @b Example:
297//!
298//! @code{.cc}
299//! octave_value obj (NDArray ());
300//! encode_array (writer, obj,true);
301//! @endcode
302
303template <typename T> void
304encode_array (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN,
305 const dim_vector& original_dims, int level = 0,
306 bool is_logical = false)
307{
308 NDArray array = obj.array_value ();
309 // is_logical is assigned at level 0. I think this is better than changing
310 // many places in the code, and it makes the function more modular.
311 if (level == 0)
312 is_logical = obj.islogical ();
313
314 if (array.isempty ())
315 {
316 writer.StartArray ();
317 writer.EndArray ();
318 }
319 else if (array.isvector ())
320 {
321 writer.StartArray ();
322 for (octave_idx_type i = 0; i < array.numel (); ++i)
323 {
324 if (is_logical)
325 encode_numeric (writer, bool (array(i)), ConvertInfAndNaN);
326 else
327 encode_numeric (writer, array(i), ConvertInfAndNaN);
328 }
329 writer.EndArray ();
330 }
331 else
332 {
333 octave_idx_type idx;
334 octave_idx_type ndims = array.ndims ();
335 const dim_vector& dims = array.dims ();
336
337 // In this case, we already have a vector. So, we transform it to 2-D
338 // vector in order to be detected by "isvector" in the recursive call
339 if (dims.num_ones () == ndims - 1)
340 {
341 // Handle the special case when the input is a vector with more than
342 // 2 dimensions (e.g. ones ([1 1 1 1 1 6])). In this case, we don't
343 // add dimension brackets and treat it as if it is a vector
344 if (level != 0)
345 // Place an opening and a closing bracket (represents a dimension)
346 // for every dimension that equals 1 till we reach the 2-D vector
347 for (int i = level; i < ndims - 1; ++i)
348 writer.StartArray ();
349
350 encode_array (writer, array.as_row (), ConvertInfAndNaN,
351 original_dims, level + 1, is_logical);
352
353 if (level != 0)
354 for (int i = level; i < ndims - 1; ++i)
355 writer.EndArray ();
356 }
357 else
358 {
359 // We place an opening and a closing bracket for each dimension
360 // that equals 1 to preserve the number of dimensions when decoding
361 // the array after encoding it.
362 if (original_dims (level) == 1)
363 {
364 writer.StartArray ();
365 encode_array (writer, array, ConvertInfAndNaN,
366 original_dims, level + 1, is_logical);
367 writer.EndArray ();
368 }
369 else
370 {
371 for (idx = 0; idx < ndims; ++idx)
372 if (dims(idx) != 1)
373 break;
374
375 // Create the dimensions that will be used to call "num2cell"
376 // We called "num2cell" to divide the array to smaller sub-arrays
377 // in order to encode it recursively.
378 // The recursive encoding is necessary to support encoding of
379 // higher-dimensional arrays.
380 RowVector conversion_dims;
381 conversion_dims.resize (ndims - 1);
382 for (octave_idx_type i = 0; i < idx; ++i)
383 conversion_dims(i) = i + 1;
384 for (octave_idx_type i = idx ; i < ndims - 1; ++i)
385 conversion_dims(i) = i + 2;
386
387 octave_value_list args (obj);
388 args.append (conversion_dims);
389
390 Cell sub_arrays = octave::Fnum2cell (args)(0).cell_value ();
391
392 writer.StartArray ();
393
394 for (octave_idx_type i = 0; i < sub_arrays.numel (); ++i)
395 encode_array (writer, sub_arrays(i), ConvertInfAndNaN,
396 original_dims, level + 1, is_logical);
397
398 writer.EndArray ();
399 }
400 }
401 }
402}
403
404//! Encodes any Octave object. This function only serves as an interface
405//! by choosing which function to call from the previous functions.
406//!
407//! @param writer RapidJSON's writer that is responsible for generating JSON.
408//! @param obj any @ref octave_value that is supported.
409//! @param ConvertInfAndNaN @c bool that converts @c Inf and @c NaN to @c null.
410//!
411//! @b Example:
412//!
413//! @code{.cc}
414//! octave_value obj (true);
415//! encode (writer, obj,true);
416//! @endcode
417
418template <typename T> void
419encode (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN)
420{
421 if (obj.is_real_scalar ())
422 // Numeric scalars.
423 encode_numeric (writer, obj, ConvertInfAndNaN);
424 else if (obj.isnumeric () || obj.islogical ())
425 // Numeric and logical arrays.
426 encode_array (writer, obj, ConvertInfAndNaN, obj.dims ());
427 else if (obj.is_string ())
428 encode_string (writer, obj, obj.dims ());
429 else if (obj.isstruct ())
430 encode_struct (writer, obj, ConvertInfAndNaN);
431 else if (obj.iscell ())
432 encode_cell (writer, obj, ConvertInfAndNaN);
433 else if (obj.class_name () == "containers.Map")
434 // To extract the data in containers.Map, convert it to a struct.
435 // The struct will have a "map" field whose value is a struct that
436 // contains the desired data.
437 // To avoid warnings due to that conversion, disable the
438 // "Octave:classdef-to-struct" warning and re-enable it.
439 {
440 octave::unwind_action restore_warning_state
441 ([] (const octave_value_list& old_warning_state)
442 {
443 octave::set_warning_state (old_warning_state);
444 }, octave::set_warning_state ("Octave:classdef-to-struct", "off"));
445
446 encode_struct (writer, obj.scalar_map_value ().getfield ("map"),
447 ConvertInfAndNaN);
448 }
449 else if (obj.isobject ())
450 {
451 octave::unwind_action restore_warning_state
452 ([] (const octave_value_list& old_warning_state)
453 {
454 octave::set_warning_state (old_warning_state);
455 }, octave::set_warning_state ("Octave:classdef-to-struct", "off"));
456
457 encode_struct (writer, obj.scalar_map_value (), ConvertInfAndNaN);
458 }
459 else
460 error ("jsonencode: unsupported type");
461}
462
463#endif
464
466
467DEFUN (jsonencode, args, ,
468 doc: /* -*- texinfo -*-
469@deftypefn {} {@var{JSON_txt} =} jsonencode (@var{object})
470@deftypefnx {} {@var{JSON_txt} =} jsonencode (@dots{}, "ConvertInfAndNaN", @var{TF})
471@deftypefnx {} {@var{JSON_txt} =} jsonencode (@dots{}, "PrettyPrint", @var{TF})
472
473Encode Octave data types into JSON text.
474
475The input @var{object} is an Octave variable to encode.
476
477The output @var{JSON_txt} is the JSON text that contains the result of encoding
478@var{object}.
479
480If the value of the option @qcode{"ConvertInfAndNaN"} is true then @code{NaN},
481@code{NA}, @code{-Inf}, and @code{Inf} values will be converted to
482@qcode{"null"} in the output. If it is false then they will remain as their
483original values. The default value for this option is true.
484
485If the value of the option @qcode{"PrettyPrint"} is true, the output text will
486have indentations and line feeds. If it is false, the output will be condensed
487and written without whitespace. The default value for this option is false.
488
489Programming Notes:
490
491@itemize @bullet
492@item
493Complex numbers are not supported.
494
495@item
496classdef objects are first converted to structs and then encoded.
497
498@item
499To preserve escape characters (e.g., @qcode{"@backslashchar{}n"}), use
500single-quoted strings.
501
502@item
503Every character after the null character (@qcode{"@backslashchar{}0"}) in a
504double-quoted string will be dropped during encoding.
505
506@item
507Encoding and decoding an array is not guaranteed to preserve the dimensions
508of the array. In particular, row vectors will be reshaped to column vectors.
509
510@item
511Encoding and decoding is not guaranteed to preserve the Octave data type
512because JSON supports fewer data types than Octave. For example, if you
513encode an @code{int8} and then decode it, you will get a @code{double}.
514@end itemize
515
516This table shows the conversions from Octave data types to JSON data types:
517
518@multitable @columnfractions 0.50 0.50
519@headitem Octave data type @tab JSON data type
520@item logical scalar @tab Boolean
521@item logical vector @tab Array of Boolean, reshaped to row vector
522@item logical array @tab nested Array of Boolean
523@item numeric scalar @tab Number
524@item numeric vector @tab Array of Number, reshaped to row vector
525@item numeric array @tab nested Array of Number
526@item @code{NaN}, @code{NA}, @code{Inf}, @code{-Inf}@*
527when @qcode{"ConvertInfAndNaN" = true} @tab @qcode{"null"}
528@item @code{NaN}, @code{NA}, @code{Inf}, @code{-Inf}@*
529when @qcode{"ConvertInfAndNaN" = false} @tab @qcode{"NaN"}, @qcode{"NaN"},
530@qcode{"Infinity"}, @qcode{"-Infinity"}
531@item empty array @tab @qcode{"[]"}
532@item character vector @tab String
533@item character array @tab Array of String
534@item empty character array @tab @qcode{""}
535@item cell scalar @tab Array
536@item cell vector @tab Array, reshaped to row vector
537@item cell array @tab Array, flattened to row vector
538@item struct scalar @tab Object
539@item struct vector @tab Array of Object, reshaped to row vector
540@item struct array @tab nested Array of Object
541@item classdef object @tab Object
542@end multitable
543
544Examples:
545
546@example
547@group
548jsonencode ([1, NaN; 3, 4])
549@result{} [[1,null],[3,4]]
550@end group
551
552@group
553jsonencode ([1, NaN; 3, 4], "ConvertInfAndNaN", false)
554@result{} [[1,NaN],[3,4]]
555@end group
556
557@group
558## Escape characters inside a single-quoted string
559jsonencode ('\0\a\b\t\n\v\f\r')
560@result{} "\\0\\a\\b\\t\\n\\v\\f\\r"
561@end group
562
563@group
564## Escape characters inside a double-quoted string
565jsonencode ("\a\b\t\n\v\f\r")
566@result{} "\u0007\b\t\n\u000B\f\r"
567@end group
568
569@group
570jsonencode ([true; false], "PrettyPrint", true)
571@result{} ans = [
572 true,
573 false
574 ]
575@end group
576
577@group
578jsonencode (['foo', 'bar'; 'foo', 'bar'])
579@result{} ["foobar","foobar"]
580@end group
581
582@group
583jsonencode (struct ('a', Inf, 'b', [], 'c', struct ()))
584@result{} @{"a":null,"b":[],"c":@{@}@}
585@end group
586
587@group
588jsonencode (struct ('structarray', struct ('a', @{1; 3@}, 'b', @{2; 4@})))
589@result{} @{"structarray":[@{"a":1,"b":2@},@{"a":3,"b":4@}]@}
590@end group
591
592@group
593jsonencode (@{'foo'; 'bar'; @{'foo'; 'bar'@}@})
594@result{} ["foo","bar",["foo","bar"]]
595@end group
596
597@group
598jsonencode (containers.Map(@{'foo'; 'bar'; 'baz'@}, [1, 2, 3]))
599@result{} @{"bar":2,"baz":3,"foo":1@}
600@end group
601@end example
602
603@seealso{jsondecode}
604@end deftypefn */)
605{
606#if defined (HAVE_RAPIDJSON)
607
608 int nargin = args.length ();
609 // jsonencode has two options 'ConvertInfAndNaN' and 'PrettyPrint'
610 if (nargin != 1 && nargin != 3 && nargin != 5)
611 print_usage ();
612
613 // Initialize options with their default values
614 bool ConvertInfAndNaN = true;
615 bool PrettyPrint = false;
616
617 for (octave_idx_type i = 1; i < nargin; ++i)
618 {
619 if (! args(i).is_string ())
620 error ("jsonencode: option must be a string");
621 if (! args(i+1).is_bool_scalar ())
622 error ("jsonencode: option value must be a logical scalar");
623
624 std::string option_name = args(i++).string_value ();
625 if (string::strcmpi (option_name, "ConvertInfAndNaN"))
626 ConvertInfAndNaN = args(i).bool_value ();
627 else if (string::strcmpi (option_name, "PrettyPrint"))
628 PrettyPrint = args(i).bool_value ();
629 else
630 error ("jsonencode: "
631 R"(Valid options are "ConvertInfAndNaN" and "PrettyPrint")");
632 }
633
634# if ! defined (HAVE_RAPIDJSON_PRETTYWRITER)
635 if (PrettyPrint)
636 {
637 warn_disabled_feature ("jsonencode",
638 R"(the "PrettyPrint" option of RapidJSON)");
639 PrettyPrint = false;
640 }
641# endif
642
643 rapidjson::StringBuffer json;
644 if (PrettyPrint)
645 {
646# if defined (HAVE_RAPIDJSON_PRETTYWRITER)
647 rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::UTF8<>,
648 rapidjson::UTF8<>, rapidjson::CrtAllocator,
649 rapidjson::kWriteNanAndInfFlag> writer (json);
650 writer.SetIndent (' ', 2);
651 encode (writer, args(0), ConvertInfAndNaN);
652# endif
653 }
654 else
655 {
656 rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<>,
657 rapidjson::UTF8<>, rapidjson::CrtAllocator,
658 rapidjson::kWriteNanAndInfFlag> writer (json);
659 encode (writer, args(0), ConvertInfAndNaN);
660 }
661
662 return octave_value (json.GetString ());
663
664#else
665
666 octave_unused_parameter (args);
667
668 err_disabled_feature ("jsonencode", "JSON encoding through RapidJSON");
669
670#endif
671}
672
673/*
674Functional BIST tests are located in test/json/jsonencode_BIST.tst
675
676## Input validation tests
677%!testif HAVE_RAPIDJSON
678%! fail ("jsonencode ()");
679%! fail ("jsonencode (1, 2)");
680%! fail ("jsonencode (1, 2, 3, 4)");
681%! fail ("jsonencode (1, 2, 3, 4, 5, 6)");
682%! fail ("jsonencode (1, 2, true)", "option must be a string");
683%! fail ("jsonencode (1, 'string', ones (2,2))", ...
684%! "option value must be a logical scalar");
685%! fail ("jsonencode (1, 'foobar', true)", ...
686%! 'Valid options are "ConvertInfAndNaN"');
687
688%!testif HAVE_RAPIDJSON; ! __have_feature__ ("RAPIDJSON_PRETTYWRITER")
689%! fail ("jsonencode (1, 'PrettyPrint', true)", ...
690%! "warning", 'the "PrettyPrint" option of RapidJSON was unavailable');
691
692*/
693
694OCTAVE_END_NAMESPACE(octave)
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition Array.h:507
bool isvector() const
Size of the specified dimension.
Definition Array.h:655
int ndims() const
Size of the specified dimension.
Definition Array.h:679
Array< T, Alloc > as_row() const
Return the array as a row vector.
Definition Array.h:435
bool isempty() const
Size of the specified dimension.
Definition Array.h:652
octave_idx_type numel() const
Number of elements in the array.
Definition Array.h:418
Definition Cell.h:41
void resize(octave_idx_type n, const double &rfv=0)
Definition dRowVector.h:100
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
int num_ones() const
Definition dim-vector.cc:86
string_vector keys() const
Definition oct-map.h:335
octave_idx_type numel() const
Definition oct-map.h:368
octave_value getfield(const std::string &key) const
Definition oct-map.cc:183
bool isfloat() const
Definition ov.h:701
uint64_t uint64_value(bool req_int=false, bool frc_str_conv=false) const
Definition ov.h:838
bool isinteger() const
Definition ov.h:730
std::string class_name() const
Definition ov.h:1362
bool bool_value(bool warn=false) const
Definition ov.h:891
bool is_real_scalar() const
Definition ov.h:610
Cell cell_value() const
int64_t int64_value(bool req_int=false, bool frc_str_conv=false) const
Definition ov.h:834
octave_scalar_map scalar_map_value() const
bool is_string() const
Definition ov.h:637
bool isnumeric() const
Definition ov.h:750
charNDArray char_array_value(bool frc_str_conv=false) const
Definition ov.h:906
bool is_uint64_type() const
Definition ov.h:727
double scalar_value(bool frc_str_conv=false) const
Definition ov.h:853
bool iscell() const
Definition ov.h:604
octave_map map_value() const
NDArray array_value(bool frc_str_conv=false) const
Definition ov.h:865
bool is_bool_scalar() const
Definition ov.h:622
bool isstruct() const
Definition ov.h:649
bool isobject() const
Definition ov.h:664
bool islogical() const
Definition ov.h:735
dim_vector dims() const
Definition ov.h:541
octave_idx_type numel() const
Definition str-vec.h:98
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage()
Definition defun-int.h:72
#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:1003
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition errwarn.cc:53
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition errwarn.cc:318
std::complex< T > trunc(const std::complex< T > &x)
Definition lo-mappers.h:111
T::size_type numel(const T &str)
Definition oct-string.cc:74