Mercurial > octave
changeset 28628:83172e1c77f2
refactor octave_read_* and octave_write_* functions
* lo-utils.h, lo-utils.cc (read_value): Define inside octave namespace
and rename from octave_read_value.
(write_value): New template.
(octave_read_double, octave_read_float, octave_read_complex,
octave_read_float_complex, octave_write_double, octave_write_float,
octave_write_complex, octave_write_float_complex): Deprecate. Change
all uses to use octave::read_value<T> and octave::write_value<T>
functions instead.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 11 Aug 2020 15:20:01 -0400 |
parents | 0da2fbd3a642 |
children | af361aea02e0 |
files | libinterp/corefcn/dlmread.cc libinterp/corefcn/ls-mat-ascii.cc libinterp/corefcn/oct-stream.cc libinterp/octave-value/ov-bool.cc libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-float.cc libinterp/octave-value/ov-flt-complex.cc libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-scalar.cc liboctave/array/CMatrix.cc liboctave/array/CNDArray.cc liboctave/array/CSparse.cc liboctave/array/Range.cc liboctave/array/boolSparse.cc liboctave/array/dMatrix.cc liboctave/array/dNDArray.cc liboctave/array/dSparse.cc liboctave/array/fCMatrix.cc liboctave/array/fCNDArray.cc liboctave/array/fMatrix.cc liboctave/array/fNDArray.cc liboctave/util/lo-utils.cc liboctave/util/lo-utils.h |
diffstat | 23 files changed, 340 insertions(+), 294 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/dlmread.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/corefcn/dlmread.cc Tue Aug 11 15:20:01 2020 -0400 @@ -443,7 +443,7 @@ tmp_stream.str (str); tmp_stream.clear (); - double x = octave_read_double (tmp_stream); + double x = octave::read_value<double> (tmp_stream); if (tmp_stream) { if (tmp_stream.eof ()) @@ -485,7 +485,7 @@ } else { - double y = octave_read_double (tmp_stream); + double y = octave::read_value<double> (tmp_stream); if (! iscmplx && y != 0.0) { @@ -502,7 +502,7 @@ } else { - // octave_read_double() parsing failed + // octave::read_value<double>() parsing failed j++; // Leave data initialized to empty_value }
--- a/libinterp/corefcn/ls-mat-ascii.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/corefcn/ls-mat-ascii.cc Tue Aug 11 15:20:01 2020 -0400 @@ -154,7 +154,7 @@ { std::istringstream tmp_stream (buf.substr (beg, end-beg)); - octave_read_double (tmp_stream); + octave::read_value<double> (tmp_stream); if (tmp_stream.fail ()) { @@ -285,7 +285,7 @@ { octave_quit (); - d = octave_read_value<double> (tmp_stream); + d = octave::read_value<double> (tmp_stream); if (! tmp_stream && ! tmp_stream.eof ()) error ("load: failed to read matrix from file '%s'", @@ -381,7 +381,7 @@ { // Omit leading tabs. if (j != 0) os << '\t'; - octave_write_double (os, m(i, j)); + octave::write_value<double> (os, m(i, j)); } os << "\n"; }
--- a/libinterp/corefcn/oct-stream.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/corefcn/oct-stream.cc Tue Aug 11 15:20:01 2020 -0400 @@ -2960,7 +2960,7 @@ { char *pos = is.tellg (); std::ios::iostate state = is.rdstate (); - //re = octave_read_value<double> (is); + //re = octave::read_value<double> (is); re = read_double (is, fmt); // check for "treat as empty" string @@ -3025,7 +3025,7 @@ pos = is.tellg (); state = is.rdstate (); - //im = octave_read_value<double> (is); + //im = octave::read_value<double> (is); im = read_double (is, fmt); if (is.fail ()) im = 1; @@ -4370,7 +4370,7 @@ { is.putback (c1); - ref = octave_read_value<double> (is); + ref = octave::read_value<double> (is); } } break;
--- a/libinterp/octave-value/ov-bool.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-bool.cc Tue Aug 11 15:20:01 2020 -0400 @@ -188,7 +188,7 @@ { double d = double_value (); - octave_write_double (os, d); + octave::write_value<double> (os, d); os << "\n"; return true; @@ -197,7 +197,7 @@ bool octave_bool::load_ascii (std::istream& is) { - scalar = (octave_read_value<double> (is) != 0.0); + scalar = (octave::read_value<double> (is) != 0.0); if (! is) error ("load: failed to load scalar constant");
--- a/libinterp/octave-value/ov-complex.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-complex.cc Tue Aug 11 15:20:01 2020 -0400 @@ -313,7 +313,7 @@ { Complex c = complex_value (); - octave_write_complex (os, c); + octave::write_value<Complex> (os, c); os << "\n"; @@ -323,7 +323,7 @@ bool octave_complex::load_ascii (std::istream& is) { - scalar = octave_read_value<Complex> (is); + scalar = octave::read_value<Complex> (is); if (! is) error ("load: failed to load complex scalar constant");
--- a/libinterp/octave-value/ov-float.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-float.cc Tue Aug 11 15:20:01 2020 -0400 @@ -200,7 +200,7 @@ { float d = float_value (); - octave_write_float (os, d); + octave::write_value<float> (os, d); os << "\n"; @@ -210,7 +210,7 @@ bool octave_float_scalar::load_ascii (std::istream& is) { - scalar = octave_read_value<float> (is); + scalar = octave::read_value<float> (is); if (! is) error ("load: failed to load scalar constant");
--- a/libinterp/octave-value/ov-flt-complex.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-flt-complex.cc Tue Aug 11 15:20:01 2020 -0400 @@ -254,7 +254,7 @@ { FloatComplex c = float_complex_value (); - octave_write_float_complex (os, c); + octave::write_value<FloatComplex> (os, c); os << "\n"; @@ -264,7 +264,7 @@ bool octave_float_complex::load_ascii (std::istream& is) { - scalar = octave_read_value<FloatComplex> (is); + scalar = octave::read_value<FloatComplex> (is); if (! is) error ("load: failed to load complex scalar constant");
--- a/libinterp/octave-value/ov-range.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-range.cc Tue Aug 11 15:20:01 2020 -0400 @@ -535,14 +535,14 @@ else os << "# base, length, increment\n"; - octave_write_double (os, base); + octave::write_value<double> (os, base); os << ' '; if (inc != 0) - octave_write_double (os, limit); + octave::write_value<double> (os, limit); else os << len; os << ' '; - octave_write_double (os, inc); + octave::write_value<double> (os, inc); os << "\n"; return true;
--- a/libinterp/octave-value/ov-scalar.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/libinterp/octave-value/ov-scalar.cc Tue Aug 11 15:20:01 2020 -0400 @@ -219,7 +219,7 @@ { double d = double_value (); - octave_write_double (os, d); + octave::write_value<double> (os, d); os << "\n"; @@ -229,7 +229,7 @@ bool octave_scalar::load_ascii (std::istream& is) { - scalar = octave_read_value<double> (is); + scalar = octave::read_value<double> (is); if (! is) error ("load: failed to load scalar constant");
--- a/liboctave/array/CMatrix.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/CMatrix.cc Tue Aug 11 15:20:01 2020 -0400 @@ -3168,7 +3168,7 @@ for (octave_idx_type j = 0; j < a.cols (); j++) { os << ' '; - octave_write_complex (os, a.elem (i, j)); + octave::write_value<Complex> (os, a.elem (i, j)); } os << "\n"; } @@ -3187,7 +3187,7 @@ for (octave_idx_type i = 0; i < nr; i++) for (octave_idx_type j = 0; j < nc; j++) { - tmp = octave_read_value<Complex> (is); + tmp = octave::read_value<Complex> (is); if (is) a.elem (i, j) = tmp; else
--- a/liboctave/array/CNDArray.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/CNDArray.cc Tue Aug 11 15:20:01 2020 -0400 @@ -601,7 +601,7 @@ for (octave_idx_type i = 0; i < nel; i++) { os << ' '; - octave_write_complex (os, a.elem (i)); + octave::write_value<Complex> (os, a.elem (i)); os << "\n"; } return os; @@ -617,7 +617,7 @@ Complex tmp; for (octave_idx_type i = 0; i < nel; i++) { - tmp = octave_read_value<Complex> (is); + tmp = octave::read_value<Complex> (is); if (is) a.elem (i) = tmp; else
--- a/liboctave/array/CSparse.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/CSparse.cc Tue Aug 11 15:20:01 2020 -0400 @@ -7487,7 +7487,7 @@ for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++) { os << a.ridx (i) + 1 << ' ' << j + 1 << ' '; - octave_write_complex (os, a.data (i)); + octave::write_value<Complex> (os, a.data (i)); os << "\n"; } } @@ -7500,7 +7500,7 @@ { typedef SparseComplexMatrix::element_type elt_type; - return read_sparse_matrix<elt_type> (is, a, octave_read_value<Complex>); + return read_sparse_matrix<elt_type> (is, a, octave::read_value<Complex>); } SparseComplexMatrix
--- a/liboctave/array/Range.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/Range.cc Tue Aug 11 15:20:01 2020 -0400 @@ -91,16 +91,19 @@ { Matrix retval (1, m_numel); - // The first element must always be *exactly* the base. - // E.g, -0 would otherwise become +0 in the loop (-0 + 0*increment). - retval(0) = m_base; + if (m_numel > 0) + { + // The first element must always be *exactly* the base. + // E.g, -0 would otherwise become +0 in the loop (-0 + 0*increment). + retval(0) = m_base; - double b = m_base; - double increment = m_inc; - for (octave_idx_type i = 1; i < m_numel - 1; i++) - retval.xelem (i) = b + i * increment; + double b = m_base; + double increment = m_inc; + for (octave_idx_type i = 1; i < m_numel - 1; i++) + retval.xelem (i) = b + i * increment; - retval.xelem (m_numel - 1) = m_limit; + retval.xelem (m_numel - 1) = m_limit; + } return retval; }
--- a/liboctave/array/boolSparse.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/boolSparse.cc Tue Aug 11 15:20:01 2020 -0400 @@ -282,7 +282,7 @@ { typedef SparseBoolMatrix::element_type elt_type; - return read_sparse_matrix<elt_type> (is, a, octave_read_value<bool>); + return read_sparse_matrix<elt_type> (is, a, octave::read_value<bool>); } SparseBoolMatrix
--- a/liboctave/array/dMatrix.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/dMatrix.cc Tue Aug 11 15:20:01 2020 -0400 @@ -2637,7 +2637,7 @@ for (octave_idx_type j = 0; j < a.cols (); j++) { os << ' '; - octave_write_double (os, a.elem (i, j)); + octave::write_value<double> (os, a.elem (i, j)); } os << "\n"; } @@ -2656,7 +2656,7 @@ for (octave_idx_type i = 0; i < nr; i++) for (octave_idx_type j = 0; j < nc; j++) { - tmp = octave_read_value<double> (is); + tmp = octave::read_value<double> (is); if (is) a.elem (i, j) = tmp; else
--- a/liboctave/array/dNDArray.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/dNDArray.cc Tue Aug 11 15:20:01 2020 -0400 @@ -626,7 +626,7 @@ for (octave_idx_type i = 0; i < nel; i++) { os << ' '; - octave_write_double (os, a.elem (i)); + octave::write_value<double> (os, a.elem (i)); os << "\n"; } return os; @@ -642,7 +642,7 @@ double tmp; for (octave_idx_type i = 0; i < nel; i++) { - tmp = octave_read_value<double> (is); + tmp = octave::read_value<double> (is); if (is) a.elem (i) = tmp; else
--- a/liboctave/array/dSparse.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/dSparse.cc Tue Aug 11 15:20:01 2020 -0400 @@ -7493,7 +7493,7 @@ for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++) { os << a.ridx (i) + 1 << ' ' << j + 1 << ' '; - octave_write_double (os, a.data (i)); + octave::write_value<double> (os, a.data (i)); os << "\n"; } } @@ -7506,7 +7506,7 @@ { typedef SparseMatrix::element_type elt_type; - return read_sparse_matrix<elt_type> (is, a, octave_read_value<double>); + return read_sparse_matrix<elt_type> (is, a, octave::read_value<double>); } SparseMatrix
--- a/liboctave/array/fCMatrix.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/fCMatrix.cc Tue Aug 11 15:20:01 2020 -0400 @@ -3200,7 +3200,7 @@ for (octave_idx_type j = 0; j < a.cols (); j++) { os << ' '; - octave_write_complex (os, a.elem (i, j)); + octave::write_value<Complex> (os, a.elem (i, j)); } os << "\n"; } @@ -3219,7 +3219,7 @@ for (octave_idx_type i = 0; i < nr; i++) for (octave_idx_type j = 0; j < nc; j++) { - tmp = octave_read_value<FloatComplex> (is); + tmp = octave::read_value<FloatComplex> (is); if (is) a.elem (i, j) = tmp; else
--- a/liboctave/array/fCNDArray.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/fCNDArray.cc Tue Aug 11 15:20:01 2020 -0400 @@ -616,7 +616,7 @@ for (octave_idx_type i = 0; i < nel; i++) { os << ' '; - octave_write_complex (os, a.elem (i)); + octave::write_value<Complex> (os, a.elem (i)); os << "\n"; } return os; @@ -632,7 +632,7 @@ FloatComplex tmp; for (octave_idx_type i = 0; i < nel; i++) { - tmp = octave_read_value<FloatComplex> (is); + tmp = octave::read_value<FloatComplex> (is); if (is) a.elem (i) = tmp; else
--- a/liboctave/array/fMatrix.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/fMatrix.cc Tue Aug 11 15:20:01 2020 -0400 @@ -2647,7 +2647,7 @@ for (octave_idx_type j = 0; j < a.cols (); j++) { os << ' '; - octave_write_float (os, a.elem (i, j)); + octave::write_value<float> (os, a.elem (i, j)); } os << "\n"; } @@ -2666,7 +2666,7 @@ for (octave_idx_type i = 0; i < nr; i++) for (octave_idx_type j = 0; j < nc; j++) { - tmp = octave_read_value<float> (is); + tmp = octave::read_value<float> (is); if (is) a.elem (i, j) = tmp; else
--- a/liboctave/array/fNDArray.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/array/fNDArray.cc Tue Aug 11 15:20:01 2020 -0400 @@ -594,7 +594,7 @@ for (octave_idx_type i = 0; i < nel; i++) { os << ' '; - octave_write_float (os, a.elem (i)); + octave::write_value<float> (os, a.elem (i)); os << "\n"; } return os; @@ -610,7 +610,7 @@ float tmp; for (octave_idx_type i = 0; i < nel; i++) { - tmp = octave_read_value<float> (is); + tmp = octave::read_value<float> (is); if (is) a.elem (i) = tmp; else
--- a/liboctave/util/lo-utils.cc Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/util/lo-utils.cc Tue Aug 11 15:20:01 2020 -0400 @@ -187,244 +187,253 @@ return retval; } -// Note that the caller is responsible for repositioning the stream on failure. +namespace octave +{ + // Note that the caller is responsible for repositioning the stream on + // failure. + + template <typename T> + T + read_inf_nan_na (std::istream& is, char c0) + { + T val = 0.0; + + switch (c0) + { + case 'i': case 'I': + { + char c1 = is.get (); + if (c1 == 'n' || c1 == 'N') + { + char c2 = is.get (); + if (c2 == 'f' || c2 == 'F') + val = std::numeric_limits<T>::infinity (); + else + is.setstate (std::ios::failbit); + } + else + is.setstate (std::ios::failbit); + } + break; -template <typename T> -T -read_inf_nan_na (std::istream& is, char c0) -{ - T val = 0.0; + case 'n': case 'N': + { + char c1 = is.get (); + if (c1 == 'a' || c1 == 'A') + { + char c2 = is.get (); + if (c2 == 'n' || c2 == 'N') + val = std::numeric_limits<T>::quiet_NaN (); + else + { + val = octave::numeric_limits<T>::NA (); + if (c2 != std::istream::traits_type::eof ()) + is.putback (c2); + else + is.clear (is.rdstate () & ~std::ios::failbit); + } + } + else + is.setstate (std::ios::failbit); + } + break; + + default: + (*current_liboctave_error_handler) + ("read_inf_nan_na: invalid character '%c'", c0); + } + + return val; + } + + // Read a double value. Discard any sign on NaN and NA. + + template <typename T> + double + read_fp_value (std::istream& is) + { + T val = 0.0; + + // FIXME: resetting stream position is likely to fail unless we are + // reading from a file. + std::streampos pos = is.tellg (); + + char c1 = ' '; + + while (isspace (c1)) + c1 = is.get (); + + bool neg = false; - switch (c0) - { - case 'i': case 'I': + switch (c1) + { + case '-': + neg = true; + OCTAVE_FALLTHROUGH; + + case '+': + { + char c2 = 0; + c2 = is.get (); + if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') + val = read_inf_nan_na<T> (is, c2); + else + { + is.putback (c2); + is >> val; + } + + if (neg && ! is.fail ()) + val = -val; + } + break; + + case 'i': case 'I': + case 'n': case 'N': + val = read_inf_nan_na<T> (is, c1); + break; + + default: + is.putback (c1); + is >> val; + break; + } + + std::ios::iostate status = is.rdstate (); + if (status & std::ios::failbit) { - char c1 = is.get (); - if (c1 == 'n' || c1 == 'N') + // Convert MAX_VAL returned by C++ streams for very large numbers to Inf + if (val == std::numeric_limits<T>::max ()) + { + if (neg) + val = -std::numeric_limits<T>::infinity (); + else + val = std::numeric_limits<T>::infinity (); + is.clear (status & ~std::ios::failbit); + } + else { - char c2 = is.get (); - if (c2 == 'f' || c2 == 'F') - val = std::numeric_limits<T>::infinity (); + // True error. Reset stream to original position and pass status on. + is.clear (); + is.seekg (pos); + is.setstate (status); + } + } + + return val; + } + + template <typename T> + std::complex<T> + read_cx_fp_value (std::istream& is) + { + T re = 0.0; + T im = 0.0; + + std::complex<T> cx = 0.0; + + char ch = ' '; + + while (isspace (ch)) + ch = is.get (); + + if (ch == '(') + { + re = read_value<T> (is); + ch = is.get (); + + if (ch == ',') + { + im = read_value<T> (is); + ch = is.get (); + + if (ch == ')') + cx = std::complex<T> (re, im); else is.setstate (std::ios::failbit); } - else - is.setstate (std::ios::failbit); - } - break; - - case 'n': case 'N': - { - char c1 = is.get (); - if (c1 == 'a' || c1 == 'A') - { - char c2 = is.get (); - if (c2 == 'n' || c2 == 'N') - val = std::numeric_limits<T>::quiet_NaN (); - else - { - val = octave::numeric_limits<T>::NA (); - if (c2 != std::istream::traits_type::eof ()) - is.putback (c2); - else - is.clear (is.rdstate () & ~std::ios::failbit); - } - } + else if (ch == ')') + cx = re; else is.setstate (std::ios::failbit); } - break; - - default: - (*current_liboctave_error_handler) - ("read_inf_nan_na: invalid character '%c'", c0); - } - - return val; -} - -// Read a double value. Discard any sign on NaN and NA. - -template <typename T> -double -octave_read_fp_value (std::istream& is) -{ - T val = 0.0; - - // FIXME: resetting stream position is likely to fail unless we are - // reading from a file. - std::streampos pos = is.tellg (); + else + { + is.putback (ch); + cx = read_value<T> (is); + } - char c1 = ' '; - - while (isspace (c1)) - c1 = is.get (); - - bool neg = false; + return cx; + } - switch (c1) - { - case '-': - neg = true; - OCTAVE_FALLTHROUGH; + // FIXME: Could we use traits and enable_if to avoid duplication in the + // following specializations? - case '+': - { - char c2 = 0; - c2 = is.get (); - if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') - val = read_inf_nan_na<T> (is, c2); - else - { - is.putback (c2); - is >> val; - } + template <> double read_value (std::istream& is) + { + return read_fp_value<double> (is); + } - if (neg && ! is.fail ()) - val = -val; - } - break; - - case 'i': case 'I': - case 'n': case 'N': - val = read_inf_nan_na<T> (is, c1); - break; - - default: - is.putback (c1); - is >> val; - break; - } + template <> Complex read_value (std::istream& is) + { + return read_cx_fp_value<double> (is); + } - std::ios::iostate status = is.rdstate (); - if (status & std::ios::failbit) - { - // Convert MAX_VAL returned by C++ streams for very large numbers to Inf - if (val == std::numeric_limits<T>::max ()) - { - if (neg) - val = -std::numeric_limits<T>::infinity (); - else - val = std::numeric_limits<T>::infinity (); - is.clear (status & ~std::ios::failbit); - } - else - { - // True error. Reset stream to original position and pass status on. - is.clear (); - is.seekg (pos); - is.setstate (status); - } - } + template <> float read_value (std::istream& is) + { + return read_fp_value<float> (is); + } - return val; -} + template <> FloatComplex read_value (std::istream& is) + { + return read_cx_fp_value<float> (is); + } -template <typename T> -std::complex<T> -octave_read_cx_fp_value (std::istream& is) -{ - T re = 0.0; - T im = 0.0; - - std::complex<T> cx = 0.0; - - char ch = ' '; + // Note: precision is supposed to be managed outside of this function by + // setting stream parameters. - while (isspace (ch)) - ch = is.get (); - - if (ch == '(') - { - re = octave_read_value<T> (is); - ch = is.get (); - - if (ch == ',') - { - im = octave_read_value<T> (is); - ch = is.get (); + template <> void write_value (std::ostream& os, const double& value) + { + if (lo_ieee_is_NA (value)) + os << "NA"; + else if (lo_ieee_isnan (value)) + os << "NaN"; + else if (lo_ieee_isinf (value)) + os << (value < 0 ? "-Inf" : "Inf"); + else + os << value; + } - if (ch == ')') - cx = std::complex<T> (re, im); - else - is.setstate (std::ios::failbit); - } - else if (ch == ')') - cx = re; - else - is.setstate (std::ios::failbit); - } - else - { - is.putback (ch); - cx = octave_read_value<double> (is); - } - - return cx; -} - -template <> OCTAVE_API double octave_read_value (std::istream& is) -{ - return octave_read_fp_value<double> (is); -} - -template <> OCTAVE_API Complex octave_read_value (std::istream& is) -{ - return octave_read_cx_fp_value<double> (is); -} - -template <> OCTAVE_API float octave_read_value (std::istream& is) -{ - return octave_read_fp_value<float> (is); -} + template <> void write_value (std::ostream& os, const Complex& value) + { + os << '('; + write_value<double> (os, real (value)); + os << ','; + write_value<double> (os, imag (value)); + os << ')'; + } -template <> OCTAVE_API FloatComplex octave_read_value (std::istream& is) -{ - return octave_read_cx_fp_value<float> (is); -} - -void -octave_write_double (std::ostream& os, double d) -{ - if (lo_ieee_is_NA (d)) - os << "NA"; - else if (lo_ieee_isnan (d)) - os << "NaN"; - else if (lo_ieee_isinf (d)) - os << (d < 0 ? "-Inf" : "Inf"); - else - os << d; -} + // Note: precision is supposed to be managed outside of this function by + // setting stream parameters. -void -octave_write_complex (std::ostream& os, const Complex& c) -{ - os << '('; - octave_write_double (os, real (c)); - os << ','; - octave_write_double (os, imag (c)); - os << ')'; -} + template <> void write_value (std::ostream& os, const float& value) + { + if (lo_ieee_is_NA (value)) + os << "NA"; + else if (lo_ieee_isnan (value)) + os << "NaN"; + else if (lo_ieee_isinf (value)) + os << (value < 0 ? "-Inf" : "Inf"); + else + os << value; + } -void -octave_write_float (std::ostream& os, float d) -{ - if (lo_ieee_is_NA (d)) - os << "NA"; - else if (lo_ieee_isnan (d)) - os << "NaN"; - else if (lo_ieee_isinf (d)) - os << (d < 0 ? "-Inf" : "Inf"); - else - os << d; + template <> void write_value (std::ostream& os, const FloatComplex& value) + { + os << '('; + write_value<float> (os, real (value)); + os << ','; + write_value<float> (os, imag (value)); + os << ')'; + } } - -void -octave_write_float_complex (std::ostream& os, const FloatComplex& c) -{ - os << '('; - octave_write_float (os, real (c)); - os << ','; - octave_write_float (os, imag (c)); - os << ')'; -}
--- a/liboctave/util/lo-utils.h Thu Aug 20 23:12:47 2020 +0900 +++ b/liboctave/util/lo-utils.h Tue Aug 11 15:20:01 2020 -0400 @@ -85,55 +85,89 @@ extern OCTAVE_API std::string octave_fgets (std::FILE *, bool& eof); extern OCTAVE_API std::string octave_fgetl (std::FILE *, bool& eof); -template <typename T> -T -octave_read_value (std::istream& is) +namespace octave { - T retval; - is >> retval; - return retval; + template <typename T> + T + read_value (std::istream& is) + { + T retval; + is >> retval; + return retval; + } + + template <> double read_value (std::istream& is); + template <> Complex read_value (std::istream& is); + template <> float read_value (std::istream& is); + template <> FloatComplex read_value (std::istream& is); + + template <typename T> + void + write_value (std::ostream& os, const T& value) + { + os << value; + } + + template <> void write_value (std::ostream& os, const double& value); + template <> void write_value (std::ostream& os, const Complex& value); + template <> void write_value (std::ostream& os, const float& value); + template <> void write_value (std::ostream& os, const FloatComplex& value); } -template <> OCTAVE_API double octave_read_value (std::istream& is); -template <> OCTAVE_API Complex octave_read_value (std::istream& is); -template <> OCTAVE_API float octave_read_value (std::istream& is); -template <> OCTAVE_API FloatComplex octave_read_value (std::istream& is); - -// The next four functions are provided for backward compatibility. +OCTAVE_DEPRECATED (7, "use 'octave::read_value<T>' instead") inline double octave_read_double (std::istream& is) { - return octave_read_value<double> (is); + return octave::read_value<double> (is); } +OCTAVE_DEPRECATED (7, "use 'octave::read_value<T>' instead") inline Complex octave_read_complex (std::istream& is) { - return octave_read_value<Complex> (is); + return octave::read_value<Complex> (is); } +OCTAVE_DEPRECATED (7, "use 'octave::read_value<T>' instead") inline float octave_read_float (std::istream& is) { - return octave_read_value<float> (is); + return octave::read_value<float> (is); } +OCTAVE_DEPRECATED (7, "use 'octave::read_value<T>' instead") inline FloatComplex octave_read_float_complex (std::istream& is) { - return octave_read_value<FloatComplex> (is); + return octave::read_value<FloatComplex> (is); +} + +OCTAVE_DEPRECATED (7, "use 'octave::write_value<T>' instead") +inline void +octave_write_double (std::ostream& os, double value) +{ + octave::write_value<double> (os, value); } -extern OCTAVE_API void -octave_write_double (std::ostream& os, double dval); - -extern OCTAVE_API void -octave_write_complex (std::ostream& os, const Complex& cval); +OCTAVE_DEPRECATED (7, "use 'octave::write_value<T>' instead") +inline void +octave_write_complex (std::ostream& os, const Complex& value) +{ + octave::write_value<Complex> (os, value); +} -extern OCTAVE_API void -octave_write_float (std::ostream& os, float dval); +OCTAVE_DEPRECATED (7, "use 'octave::write_value<T>' instead") +inline void +octave_write_float (std::ostream& os, float value) +{ + octave::write_value<float> (os, value); +} -extern OCTAVE_API void -octave_write_float_complex (std::ostream& os, const FloatComplex& cval); +OCTAVE_DEPRECATED (7, "use 'octave::write_value<T>' instead") +inline void +octave_write_float_complex (std::ostream& os, const FloatComplex& value) +{ + octave::write_value<FloatComplex> (os, value); +} #endif