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