1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2008-2021 The Octave Project Developers
//
// See the file COPYRIGHT.md in the top-level directory of this
// distribution or <https://octave.org/copyright/>.
//
// This file is part of Octave.
//
// Octave is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Octave is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Octave; see the file COPYING. If not, see
// <https://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include "ov-null-mat.h"
#include "ops.h"
#include "defun.h"
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_matrix, "null_matrix",
"double");
const octave_value octave_null_matrix::instance (new octave_null_matrix ());
static octave_base_value *
default_null_matrix_numeric_conversion_function (const octave_base_value& a)
{
// The cast is not necessary?
// const octave_null_matrix& v = dynamic_cast<const octave_null_matrix&> (a);
return a.empty_clone ();
}
octave_base_value::type_conv_info
octave_null_matrix::numeric_conversion_function (void) const
{
return octave_base_value::type_conv_info
(default_null_matrix_numeric_conversion_function,
octave_matrix::static_type_id ());
}
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_str, "null_string", "char");
const octave_value octave_null_str::instance (new octave_null_str ());
static octave_base_value *
default_null_str_numeric_conversion_function (const octave_base_value& a)
{
// The cast is not necessary?
// const octave_null_str& v = dynamic_cast<const octave_null_str&> (a);
return a.empty_clone ();
}
octave_base_value::type_conv_info
octave_null_str::numeric_conversion_function (void) const
{
return octave_base_value::type_conv_info
(default_null_str_numeric_conversion_function,
octave_char_matrix_str::static_type_id ());
}
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_null_sq_str, "null_sq_string",
"char");
const octave_value octave_null_sq_str::instance (new octave_null_sq_str ());
static octave_base_value *
default_null_sq_str_numeric_conversion_function (const octave_base_value& a)
{
// The cast is not necessary?
// const octave_null_sq_str& v = dynamic_cast<const octave_null_sq_str&> (a);
return a.empty_clone ();
}
octave_base_value::type_conv_info
octave_null_sq_str::numeric_conversion_function (void) const
{
return octave_base_value::type_conv_info
(default_null_sq_str_numeric_conversion_function,
octave_char_matrix_sq_str::static_type_id ());
}
DEFUN (isnull, args, ,
doc: /* -*- texinfo -*-
@deftypefn {} {} isnull (@var{x})
Return true if @var{x} is a special null matrix, string, or single quoted
string.
Indexed assignment with such a null value on the right-hand side should delete
array elements. This function is used in place of @code{isempty} when
overloading the indexed assignment method (@code{subsasgn}) for user-defined
classes. @code{isnull} is used to distinguish between these two cases:
@code{@var{A}(@var{I}) = []}
and
@code{@var{X} = []; @var{A}(@var{I}) = @var{X}}
In the first assignment, the right-hand side is @code{[]} which is a special
null value. As long as the index @var{I} is not empty, this code should
delete elements from @var{A} rather than perform assignment.
In the second assignment, the right-hand side is empty (because @var{X} is
@code{[]}), but it is @strong{not} null. This code should assign the empty
value to elements in @var{A}.
An example from Octave's built-in char class demonstrates the interpreter
behavior when @code{isnull} is used correctly.
@example
@group
str = "Hello World";
nm = "Wally";
str(7:end) = nm # indexed assignment
@result{} str = Hello Wally
str(7:end) = "" # indexed deletion
@result{} str = Hello
@end group
@end example
@seealso{isempty, isindex}
@end deftypefn */)
{
if (args.length () != 1)
print_usage ();
return ovl (args(0).isnull ());
}
/*
%!assert (isnull ([]), true)
%!assert (isnull ([1]), false)
%!assert (isnull (zeros (0,3)), false)
%!assert (isnull (""), true)
%!assert (isnull ("A"), false)
%!assert (isnull (''), true)
%!assert (isnull ('A'), false)
%!test
%! x = [];
%! assert (isnull (x), false);
*/
|