# HG changeset patch # User John W. Eaton # Date 1647921969 14400 # Node ID eba0a86471b917d910dda9958e820c1cd99baf72 # Parent a0e13472457dd04bfa3be8cc37c2c39850c5345b# Parent fc3bd70cd1bec23982300b1211f0b093b93b11e2 maint: Merge stable to default. diff -r a0e13472457d -r eba0a86471b9 libinterp/corefcn/data.cc --- a/libinterp/corefcn/data.cc Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/corefcn/data.cc Tue Mar 22 00:06:09 2022 -0400 @@ -4227,14 +4227,6 @@ case oct_data_conv::dt_double: if (iscomplex) retval = ComplexNDArray (dims, Complex (val, 0)); - else if (dims.ndims () == 2 && dims(0) == 1) - { - // FIXME: If this optimization provides a significant - // benefit, then maybe there should be a special storage - // type for constant value arrays. - double dval = static_cast (val); - retval = range::make_constant (dval, dims(1)); - } else retval = NDArray (dims, val); break; @@ -4338,11 +4330,6 @@ case oct_data_conv::dt_double: if (iscomplex) retval = ComplexNDArray (dims, Complex (val, 0)); - else if (dims.ndims () == 2 && dims(0) == 1 && math::isfinite (val)) - // FIXME: If this optimization provides a significant benefit, - // then maybe there should be a special storage type for - // constant value arrays. - retval = range::make_constant (val, dims(1)); else retval = NDArray (dims, val); break; @@ -4407,13 +4394,7 @@ break; case oct_data_conv::dt_double: - if (dims.ndims () == 2 && dims(0) == 1 && math::isfinite (val)) - // FIXME: If this optimization provides a significant benefit, - // then maybe there should be a special storage type for - // constant value arrays. - retval = range::make_constant (val, dims(1)); - else - retval = NDArray (dims, val); + retval = NDArray (dims, val); break; default: diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/module.mk --- a/libinterp/octave-value/module.mk Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/module.mk Tue Mar 22 00:06:09 2022 -0400 @@ -53,6 +53,7 @@ %reldir%/ov-flt-re-mat.h \ %reldir%/ov-java.h \ %reldir%/ov-lazy-idx.h \ + %reldir%/ov-legacy-range.h \ %reldir%/ov-magic-int.h \ %reldir%/ov-mex-fcn.h \ %reldir%/ov-null-mat.h \ @@ -119,6 +120,7 @@ %reldir%/ov-flt-re-mat.cc \ %reldir%/ov-java.cc \ %reldir%/ov-lazy-idx.cc \ + %reldir%/ov-legacy-range.cc \ %reldir%/ov-magic-int.cc \ %reldir%/ov-mex-fcn.cc \ %reldir%/ov-null-mat.cc \ diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov-base.h --- a/libinterp/octave-value/ov-base.h Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/ov-base.h Tue Mar 22 00:06:09 2022 -0400 @@ -387,6 +387,8 @@ virtual bool is_storable (void) const { return true; } + virtual bool is_legacy_object (void) const { return false; } + bool isempty (void) const { return (dims ().any_zero ()); } bool is_zero_by_zero (void) const { return dims().zero_by_zero (); } diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov-legacy-range.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-legacy-range.cc Tue Mar 22 00:06:09 2022 -0400 @@ -0,0 +1,275 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1996-2022 The Octave Project Developers +// +// See the file COPYRIGHT.md in the top-level directory of this +// distribution or . +// +// 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 +// . +// +//////////////////////////////////////////////////////////////////////// + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include +#include +#include + +#include "lo-ieee.h" +#include "lo-utils.h" + +#include "variables.h" +#include "error.h" +#include "ovl.h" +#include "oct-hdf5.h" +#include "ov-legacy-range.h" +#include "ov-range.h" +#include "ov-re-mat.h" +#include "ov-scalar.h" +#include "pr-output.h" + +#include "byte-swap.h" +#include "ls-ascii-helper.h" +#include "ls-hdf5.h" +#include "ls-utils.h" + +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_legacy_range, "range", "double"); + +octave_legacy_range::octave_legacy_range (void) + : octave_base_value (), range () { } + +octave_legacy_range::octave_legacy_range (const Range& r) + : octave_base_value (), range (r) +{ + if (range.numel () < 0 && range.numel () != -2) + error ("invalid range"); +} + +static octave_base_value * +default_numeric_conversion_function (const octave_base_value& a) +{ + const octave_legacy_range& v = dynamic_cast (a); + + return new octave_matrix (v.matrix_value ()); +} + +octave_base_value::type_conv_info +octave_legacy_range::numeric_conversion_function (void) const +{ + return octave_base_value::type_conv_info (default_numeric_conversion_function, + octave_matrix::static_type_id ()); +} + +octave_base_value * +octave_legacy_range::try_narrowing_conversion (void) +{ + octave_base_value *retval = nullptr; + + switch (range.numel ()) + { + case 1: + retval = new octave_scalar (range.base ()); + break; + + case 0: + retval = new octave_matrix (Matrix (1, 0)); + break; + + case -2: + retval = new octave_matrix (range.matrix_value ()); + break; + + default: + { + if (range.increment () == 0) + retval = new octave_matrix (range.matrix_value ()); + else + retval = new octave_range + (octave::range (range.base (), range.increment (), + range.limit (), range.numel ())); + } + break; + } + + return retval; +} + +// Skip white space and comments on stream IS. + +static void +skip_comments (std::istream& is) +{ + char c = '\0'; + while (is.get (c)) + { + if (c == ' ' || c == '\t' || c == '\n') + ; // Skip whitespace on way to beginning of next line. + else + break; + } + + octave::skip_until_newline (is, false); +} + +bool +octave_legacy_range::load_ascii (std::istream& is) +{ + // # base, limit, range comment added by save (). + skip_comments (is); + + double base, limit, inc; + is >> base >> limit >> inc; + + if (! is) + error ("load: failed to load range constant"); + + if (inc != 0) + range = Range (base, limit, inc); + else + range = Range (base, inc, static_cast (limit)); + + return true; +} + +bool +octave_legacy_range::load_binary (std::istream& is, bool swap, + octave::mach_info::float_format /* fmt */) +{ + char tmp; + if (! is.read (reinterpret_cast (&tmp), 1)) + return false; + double bas, lim, inc; + if (! is.read (reinterpret_cast (&bas), 8)) + return false; + if (swap) + swap_bytes<8> (&bas); + if (! is.read (reinterpret_cast (&lim), 8)) + return false; + if (swap) + swap_bytes<8> (&lim); + if (! is.read (reinterpret_cast (&inc), 8)) + return false; + if (swap) + swap_bytes<8> (&inc); + if (inc != 0) + range = Range (bas, lim, inc); + else + range = Range (bas, inc, static_cast (lim)); + + return true; +} + +#if defined (HAVE_HDF5) + +// The following subroutines creates an HDF5 representation of the way +// we will store Octave range types (triplets of floating-point numbers). +// NUM_TYPE is the HDF5 numeric type to use for storage (e.g. +// H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary +// conversions are handled automatically by HDF5. + +static hid_t +hdf5_make_range_type (hid_t num_type) +{ + hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3); + + H5Tinsert (type_id, "base", 0 * sizeof (double), num_type); + H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type); + H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type); + + return type_id; +} + +#endif + +bool +octave_legacy_range::load_hdf5 (octave_hdf5_id loc_id, const char *name) +{ + bool retval = false; + +#if defined (HAVE_HDF5) + +#if defined (HAVE_HDF5_18) + hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT); +#else + hid_t data_hid = H5Dopen (loc_id, name); +#endif + hid_t type_hid = H5Dget_type (data_hid); + + hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE); + + if (! hdf5_types_compatible (type_hid, range_type)) + { + H5Tclose (range_type); + H5Dclose (data_hid); + return false; + } + + hid_t space_hid = H5Dget_space (data_hid); + hsize_t rank = H5Sget_simple_extent_ndims (space_hid); + + if (rank != 0) + { + H5Tclose (range_type); + H5Sclose (space_hid); + H5Dclose (data_hid); + return false; + } + + double rangevals[3]; + if (H5Dread (data_hid, range_type, octave_H5S_ALL, octave_H5S_ALL, + octave_H5P_DEFAULT, rangevals) + >= 0) + { + retval = true; + octave_idx_type nel; + if (hdf5_get_scalar_attr (data_hid, H5T_NATIVE_IDX, + "OCTAVE_RANGE_NELEM", &nel)) + range = Range (rangevals[0], rangevals[2], nel); + else + { + if (rangevals[2] != 0) + range = Range (rangevals[0], rangevals[1], rangevals[2]); + else + range = Range (rangevals[0], rangevals[2], + static_cast (rangevals[1])); + } + } + + H5Tclose (range_type); + H5Sclose (space_hid); + H5Dclose (data_hid); + +#else + octave_unused_parameter (loc_id); + octave_unused_parameter (name); + + warn_load ("hdf5"); +#endif + + return retval; +} + +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) +# pragma GCC diagnostic pop +#endif diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov-legacy-range.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-legacy-range.h Tue Mar 22 00:06:09 2022 -0400 @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1996-2022 The Octave Project Developers +// +// See the file COPYRIGHT.md in the top-level directory of this +// distribution or . +// +// 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 +// . +// +//////////////////////////////////////////////////////////////////////// + +#if ! defined (octave_ov_legacy_range_h) +#define octave_ov_legacy_range_h 1 + +#include "octave-config.h" + +#include + +#include +#include + +#include "Range.h" + +#include "lo-mappers.h" +#include "lo-utils.h" +#include "mx-base.h" + +#include "error.h" +#include "oct-stream.h" +#include "ov-base.h" +#include "ov-re-mat.h" +#include "ov-typeinfo.h" + +class octave_value_list; + +// Legacy Range values. + +// Provide enough of the old octave_range class to allow Range objects +// to be loaded from files. After loading, they are converted to some +// other type by a call to octave_value::maybe_mutate in +// load_save_system::load_vars so there should no longer be any values +// of this type used by the interpreter. The action of maybe_mutate is +// performed by octave_legacy_range::try_narrowing_conversion. + +class +octave_legacy_range : public octave_base_value +{ +public: + + octave_legacy_range (void); + + octave_legacy_range (const Range& r); + + octave_legacy_range (const octave_legacy_range& r) = default; + + // No assignment. + + octave_legacy_range& operator = (const octave_legacy_range&) = delete; + + ~octave_legacy_range (void) { } + + octave_base_value * clone (void) const + { + return new octave_legacy_range (*this); + } + + // A range is really just a special kind of real matrix object. In + // the places where we need to call empty_clone, it makes more sense + // to create an empty matrix (0x0) instead of an empty range (1x0). + octave_base_value * empty_clone (void) const { return new octave_matrix (); } + + type_conv_info numeric_conversion_function (void) const; + + octave_base_value * try_narrowing_conversion (void); + + bool is_defined (void) const { return true; } + + bool is_legacy_object (void) const { return true; } + + bool is_constant (void) const { return true; } + + bool load_ascii (std::istream& is); + + bool load_binary (std::istream& is, bool swap, + octave::mach_info::float_format fmt); + + bool load_hdf5 (octave_hdf5_id loc_id, const char *name); + +private: + + Range range; + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +#endif diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov-range.cc --- a/libinterp/octave-value/ov-range.cc Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/ov-range.cc Tue Mar 22 00:06:09 2022 -0400 @@ -143,7 +143,7 @@ #endif DEFINE_TEMPLATE_OV_TYPEID_FUNCTIONS_AND_DATA (ov_range, - "range", "double"); + "double_range", "double"); // For now, disable all but ov_range. @@ -766,13 +766,7 @@ if (! is) error ("load: failed to load range constant"); - if (inc != T (0)) - r = octave::range (base, inc, limit, rev); - else - { - octave_idx_type numel = static_cast (limit); - r = octave::range::make_constant (base, numel, rev); - } + r = octave::range (base, inc, limit, rev); return true; } @@ -946,13 +940,8 @@ if (swap) swap_bytes (&rev); } - if (inc != T (0)) - r = octave::range (bas, inc, lim, rev); - else - { - octave_idx_type numel = static_cast (lim); - r = octave::range::make_constant (bas, numel, rev); - } + + r = octave::range (bas, inc, lim, rev); return true; } @@ -1281,13 +1270,7 @@ bool rev = with_reverse ? static_cast (rangevals[3]) : false; - if (rangevals[2] != T (0)) - r = octave::range (rangevals[0], rangevals[2], rangevals[1], rev); - else - { - octave_idx_type numel = static_cast (rangevals[1]); - r = octave::range::make_constant (rangevals[0], numel, rev); - } + r = octave::range (rangevals[0], rangevals[2], rangevals[1], rev); } H5Tclose (range_type); diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov-typeinfo.cc --- a/libinterp/octave-value/ov-typeinfo.cc Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/ov-typeinfo.cc Tue Mar 22 00:06:09 2022 -0400 @@ -951,7 +951,7 @@ %!test %! if (optimize_range ()) -%! assert (typeinfo (1:2), "range") +%! assert (typeinfo (1:2), "double_range") %! else %! assert (typeinfo (1:2), "matrix") %! endif diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov.cc --- a/libinterp/octave-value/ov.cc Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/ov.cc Tue Mar 22 00:06:09 2022 -0400 @@ -48,6 +48,7 @@ #include "ov-flt-re-mat.h" #include "ov-re-diag.h" #include "ov-flt-re-diag.h" +#include "ov-legacy-range.h" #include "ov-perm.h" #include "ov-bool-sparse.h" #include "ov-cx-sparse.h" @@ -1076,8 +1077,17 @@ octave_base_value * octave_value::make_range_rep_deprecated (double base, double inc, double limit) { +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + return dynamic_cast - (new ov_range (octave::range (base, inc, limit))); + (new octave_legacy_range (Range (base, inc, limit))); + +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) +# pragma GCC diagnostic pop +#endif } // Remove when public constructor that uses this function is removed. @@ -1087,8 +1097,8 @@ if (! force_range && ! r.ok ()) error ("invalid range"); - if (force_range || Voptimize_range) - return make_range_rep_deprecated (r.base (), r.increment (), r.limit ()); + if ((force_range || Voptimize_range)) + return dynamic_cast (new octave_legacy_range (r)); else return dynamic_cast (new octave_matrix (r.matrix_value ())); } @@ -2350,6 +2360,39 @@ m_rep->print_info (os, prefix + ' '); } +bool octave_value::load_ascii (std::istream& is) +{ + bool status = m_rep->load_ascii (is); + + // Force conversion of legacy objects. + if (is_legacy_object ()) + maybe_mutate (); + + return status; +} +bool octave_value::load_binary (std::istream& is, bool swap, + octave::mach_info::float_format fmt) +{ + bool status = m_rep->load_binary (is, swap, fmt); + + // Force conversion of legacy objects. + if (is_legacy_object ()) + maybe_mutate (); + + return status; +} + +bool octave_value::load_hdf5 (octave_hdf5_id loc_id, const char *name) +{ + bool status = m_rep->load_hdf5 (loc_id, name); + + // Force conversion of legacy objects. + if (is_legacy_object ()) + maybe_mutate (); + + return status; +} + const void * octave_value::mex_get_data (mxClassID class_id, mxComplexity complexity) const { @@ -3595,6 +3638,11 @@ octave_diag_matrix::register_type (ti); octave_complex_matrix::register_type (ti); octave_complex_diag_matrix::register_type (ti); + + // Legacy range type, preserved to allow loading "constant" ranges + // from data files. + octave_legacy_range::register_type (ti); + ov_range::register_type (ti); // For now, disable all but ov_range. @@ -4078,7 +4126,7 @@ %! r = base:limit; %!endfunction -%!assert (typeinfo (__test_dr__ (true)), "range") +%!assert (typeinfo (__test_dr__ (true)), "double_range") %!assert (typeinfo (__test_dr__ (false)), "matrix") */ diff -r a0e13472457d -r eba0a86471b9 libinterp/octave-value/ov.h --- a/libinterp/octave-value/ov.h Sat Mar 19 11:00:13 2022 -0300 +++ b/libinterp/octave-value/ov.h Tue Mar 22 00:06:09 2022 -0400 @@ -640,6 +640,9 @@ bool is_undefined (void) const { return ! is_defined (); } + bool is_legacy_object (void) const + { return m_rep->is_legacy_object (); } + bool isempty (void) const { return m_rep->isempty (); } @@ -1483,21 +1486,19 @@ bool save_ascii (std::ostream& os) { return m_rep->save_ascii (os); } - bool load_ascii (std::istream& is) { return m_rep->load_ascii (is); } + OCTINTERP_API bool load_ascii (std::istream& is); bool save_binary (std::ostream& os, bool save_as_floats) { return m_rep->save_binary (os, save_as_floats); } - bool load_binary (std::istream& is, bool swap, - octave::mach_info::float_format fmt) - { return m_rep->load_binary (is, swap, fmt); } + OCTINTERP_API bool load_binary (std::istream& is, bool swap, + octave::mach_info::float_format fmt); bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats) { return m_rep->save_hdf5 (loc_id, name, save_as_floats); } - bool load_hdf5 (octave_hdf5_id loc_id, const char *name) - { return m_rep->load_hdf5 (loc_id, name); } + OCTINTERP_API bool load_hdf5 (octave_hdf5_id loc_id, const char *name); OCTINTERP_API int write (octave::stream& os, int block_size, diff -r a0e13472457d -r eba0a86471b9 liboctave/array/Range.h --- a/liboctave/array/Range.h Sat Mar 19 11:00:13 2022 -0300 +++ b/liboctave/array/Range.h Tue Mar 22 00:06:09 2022 -0400 @@ -76,14 +76,11 @@ } // Allow conversion from (presumably) properly constructed Range - // objects and to create constant ranges (see the static - // make_constant method). The values of base, limit, increment, - // and numel must be consistent. + // objects. The values of base, limit, increment, and numel must be + // consistent. // FIXME: Actually check that base, limit, increment, and numel are - // consistent. - - // FIXME: Is there a way to limit this to T == double? + // consistent? range (const T& base, const T& increment, const T& limit, octave_idx_type numel, bool reverse = false) @@ -91,26 +88,6 @@ m_final (limit), m_numel (numel), m_reverse (reverse) { } - range (const T& base, const T& increment, const T& limit, - const T& final, octave_idx_type numel, bool reverse = false) - : m_base (base), m_increment (increment), m_limit (limit), - m_final (final), m_numel (numel), m_reverse (reverse) - { } - - // We don't use a constructor for this because it will conflict with - // range (base, limit) when T is octave_idx_type. - - static range make_constant (const T& base, octave_idx_type numel, - bool reverse = false) - { - // We could just make this constructor public, but it allows - // inconsistent ranges to be constructed. And it is probably much - // clearer to see "make_constant" instead of puzzling over the - // purpose of this strange constructor form. - - return range (base, T (), base, numel, reverse); - } - // We don't use a constructor for this because it will conflict with // range (base, limit, increment) when T is octave_idx_type. @@ -120,7 +97,7 @@ { // We could just make this constructor public, but it allows // inconsistent ranges to be constructed. And it is probably much - // clearer to see "make_constant" instead of puzzling over the + // clearer to see "make_n_element_range" instead of puzzling over the // purpose of this strange constructor form. T final_val = (reverse ? base - (numel - 1) * increment @@ -423,7 +400,6 @@ { public: -#if defined (OCTAVE_PROVIDE_DEPRECATED_SYMBOLS) OCTAVE_DEPRECATED (7, "use the 'octave::range' class instead") Range (void) : m_base (0), m_limit (0), m_inc (0), m_numel (0) @@ -439,7 +415,6 @@ : m_base (r.base ()), m_limit (r.final_value ()), m_inc (r.increment ()), m_numel (r.numel ()) { } -#endif Range (const Range& r) = default; @@ -447,7 +422,6 @@ ~Range (void) = default; -#if defined (OCTAVE_PROVIDE_DEPRECATED_SYMBOLS) OCTAVE_DEPRECATED (7, "use the 'octave::range' class instead") Range (double b, double l) : m_base (b), m_limit (l), m_inc (1), m_numel (numel_internal ()) @@ -477,7 +451,6 @@ if (! octave::math::isinf (m_limit)) m_limit = limit_internal (); } -#endif // The range has a finite number of elements. bool ok (void) const diff -r a0e13472457d -r eba0a86471b9 test/mk-conv-tst.sh --- a/test/mk-conv-tst.sh Sat Mar 19 11:00:13 2022 -0300 +++ b/test/mk-conv-tst.sh Tue Mar 22 00:06:09 2022 -0400 @@ -73,7 +73,7 @@ %! %!test %! if (optimize_range ()) -%! assert (typeinfo (r), "range") +%! assert (typeinfo (r), "double_range") %! else %! assert (typeinfo (r), "matrix") %! endif diff -r a0e13472457d -r eba0a86471b9 test/range.tst --- a/test/range.tst Sat Mar 19 11:00:13 2022 -0300 +++ b/test/range.tst Tue Mar 22 00:06:09 2022 -0400 @@ -611,17 +611,30 @@ %!test # ascending ranges %! types = {"int8", "int16", "int32", "int64"}; %! for i_type = 1:numel (types) -%! assert (intmin (types{i_type}) : double (intmax (types{i_type})) + 1 : intmax (types{i_type}), ... +%! assert (intmin (types{i_type}) : -double (intmin (types{i_type})) : intmax (types{i_type}), ... %! [intmin(types{i_type}), 0]); +%! ## FIXME: This test leads to a deadlock for "int64". +%! ## assert (intmin (types{i_type}) : -2*double (intmin (types{i_type})) : intmax (types{i_type}), ... +%! ## intmin (types{i_type})); +%! if (! strcmp (types, "int64")) +%! ## The increment cannot be represented in double precision for "int64" +%! assert (intmin (types{i_type}) : 2*double (intmax (types{i_type})) : intmin (types{i_type}), ... +%! [intmin(types{i_type}), intmax(types{i_type})-1]); +%! endif %! endfor %!test # descending ranges %! types = {"int8", "int16", "int32", "int64"}; %! for i_type = 1:numel (types) %! assert (intmax (types{i_type}) : double (intmin (types{i_type})) : intmin (types{i_type}), ... %! [intmax(types{i_type}), -1]); -%! ## FIXME: This leads to a deadlock for "int64". -%! ## assert (intmax (types{i_type}) : -2*double (intmax (types{i_type})) : intmin (types{i_type}), ... -%! ## [intmax(types{i_type}), -intmax(types{i_type})]); +%! ## FIXME: This test leads to a deadlock for "int64". +%! ## assert (intmax (types{i_type}) : 2*double (intmin (types{i_type})) : intmin (types{i_type}), ... +%! ## intmax (types{i_type})); +%! if (! strcmp (types, "int64")) +%! ## The increment cannot be represented in double precision for "int64" +%! assert (intmax (types{i_type}) : -2*double (intmax (types{i_type})) : intmin (types{i_type}), ... +%! [intmax(types{i_type}), -intmax(types{i_type})]); +%! endif %! endfor ## integer range near intmax