# HG changeset patch # User John W. Eaton # Date 1518985956 21600 # Node ID 0eb41237424e29128a70421a1217d5ec2dbf2d43 # Parent e6f380f9b2a4b45f7557a0858d337cb288a3a972 more templates for pr-output.cc functions * pr-output.h, pr-output.cc (pr_max_internal, pr_min_internal, make_complex_format, make_format, make_format_internal, make_real_format): Define with templates where possible. (pr_plus_format): New template function. Use to eliminate some duplicate code. (octave_print_internal): Define versions for float and FloatComplex. diff -r e6f380f9b2a4 -r 0eb41237424e libinterp/corefcn/pr-output.cc --- a/libinterp/corefcn/pr-output.cc Wed Feb 21 09:17:05 2018 -0500 +++ b/libinterp/corefcn/pr-output.cc Sun Feb 18 14:32:36 2018 -0600 @@ -135,7 +135,7 @@ } template -static int +static inline int engineering_exponent (T x) { int ex = 0; @@ -158,7 +158,7 @@ } template -static int +static inline int num_digits (T x) { return 1 + (print_eng @@ -369,20 +369,24 @@ return os; } -static double -pr_max_internal (const Matrix& m) +template +static inline T +pr_max_internal (const MArray& m) { + // We expect a 2-d array. + assert (m.ndims () == 2); + octave_idx_type nr = m.rows (); octave_idx_type nc = m.columns (); - double result = -std::numeric_limits::max (); + T result = std::numeric_limits::lowest (); bool all_inf_or_nan = true; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { - double val = m(i,j); + T val = m(i,j); if (! octave::math::isfinite (val)) continue; @@ -398,20 +402,21 @@ return result; } -static double -pr_min_internal (const Matrix& m) +template +static inline T +pr_min_internal (const MArray& m) { octave_idx_type nr = m.rows (); octave_idx_type nc = m.columns (); - double result = std::numeric_limits::max (); + T result = std::numeric_limits::max (); bool all_inf_or_nan = true; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { - double val = m(i,j); + T val = m(i,j); if (! octave::math::isfinite (val)) continue; @@ -429,8 +434,10 @@ // FIXME: it would be nice to share more code among these functions,.. -static float_display_format -make_real_format (int digits, bool inf_or_nan, bool int_only, int& fw) +template +static inline float_display_format +make_real_format (int digits, bool inf_or_nan, + bool int_only, int& fw) { float_format fmt; @@ -452,12 +459,12 @@ } else if (hex_format) { - fw = 2 * sizeof (double); + fw = 2 * sizeof (T); rd = 0; } else if (bit_format) { - fw = 8 * sizeof (double); + fw = 8 * sizeof (T); rd = 0; } else if (inf_or_nan || int_only) @@ -524,24 +531,26 @@ return float_display_format (fmt); } +template float_display_format -make_format (double d, int& fw) +make_format (T val, int& fw) { if (free_format) return float_display_format (); - bool inf_or_nan = (octave::math::isinf (d) || octave::math::isnan (d)); - - bool int_only = (! inf_or_nan && octave::math::x_nint (d) == d); - - double d_abs = (d < 0 ? -d : d); - - int digits = (inf_or_nan || d_abs == 0) ? 0 : num_digits (d_abs); - - return make_real_format (digits, inf_or_nan, int_only, fw); + bool inf_or_nan = (octave::math::isinf (val) || octave::math::isnan (val)); + + bool int_only = (! inf_or_nan && octave::math::x_nint (val) == val); + + T val_abs = (val < 0 ? -val : val); + + int digits = (inf_or_nan || val_abs == 0) ? 0 : num_digits (val_abs); + + return make_real_format (digits, inf_or_nan, int_only, fw); } -static float_display_format +template +static inline float_display_format make_real_matrix_format (int x_max, int x_min, bool inf_or_nan, int int_or_inf_or_nan, int& fw) { @@ -566,12 +575,12 @@ } else if (hex_format) { - fw = 2 * sizeof (double); + fw = 2 * sizeof (T); rd = 0; } else if (bit_format) { - fw = 8 * sizeof (double); + fw = 8 * sizeof (T); rd = 0; } else if (Vfixed_point_format && ! print_g) @@ -667,9 +676,12 @@ return float_display_format (fmt); } -float_display_format -make_format (const Matrix& m, int& fw, double& scale) +template +static inline float_display_format +make_format_internal (const MT& m, int& fw, ELT_T& scale) { + assert (m.ndims () == 2); + if (free_format) return float_display_format (); @@ -677,9 +689,9 @@ bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan (); - Matrix m_abs = m.abs (); - double max_abs = pr_max_internal (m_abs); - double min_abs = pr_min_internal (m_abs); + MT m_abs = m.abs (); + ELT_T max_abs = pr_max_internal (m_abs); + ELT_T min_abs = pr_min_internal (m_abs); int x_max = (max_abs == 0 ? 0 : num_digits (max_abs)); @@ -688,13 +700,26 @@ scale = ((x_max == 0 || int_or_inf_or_nan) ? 1 : std::pow (10.0, calc_scale_exp (x_max - 1))); - return make_real_matrix_format (x_max, x_min, inf_or_nan, - int_or_inf_or_nan, fw); + return make_real_matrix_format (x_max, x_min, inf_or_nan, + int_or_inf_or_nan, fw); +} + +float_display_format +make_format (const Matrix& m, int& fw, double& scale) +{ + return make_format_internal (m, fw, scale); } -static float_display_format -make_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan, - int int_only, int& r_fw, int& i_fw) +float_display_format +make_format (const FloatMatrix& m, int& fw, float& scale) +{ + return make_format_internal (m, fw, scale); +} + +template +static inline float_display_format +make_complex_format (int x_max, int x_min, int r_x, + bool inf_or_nan, int int_only, int& r_fw, int& i_fw) { float_format r_fmt; float_format i_fmt; @@ -720,14 +745,14 @@ } else if (hex_format) { - r_fw = 2 * sizeof (double); - i_fw = 2 * sizeof (double); + r_fw = 2 * sizeof (T); + i_fw = 2 * sizeof (T); rd = 0; } else if (bit_format) { - r_fw = 8 * sizeof (double); - i_fw = 8 * sizeof (double); + r_fw = 8 * sizeof (T); + i_fw = 8 * sizeof (T); rd = 0; } else if (inf_or_nan || int_only) @@ -844,22 +869,23 @@ return float_display_format (r_fmt, i_fmt); } +template float_display_format -make_format (const Complex& c, int& r_fw, int& i_fw) +make_format (const std::complex& c, int& r_fw, int& i_fw) { if (free_format) return float_display_format (); - double rp = c.real (); - double ip = c.imag (); + T rp = c.real (); + T ip = c.imag (); bool inf_or_nan = (octave::math::isinf (c) || octave::math::isnan (c)); bool int_only = (octave::math::x_nint (rp) == rp && octave::math::x_nint (ip) == ip); - double r_abs = (rp < 0 ? -rp : rp); - double i_abs = (ip < 0 ? -ip : ip); + T r_abs = (rp < 0 ? -rp : rp); + T i_abs = (ip < 0 ? -ip : ip); int r_x = (! octave::math::isfinite (rp) || r_abs == 0) ? 0 : num_digits (r_abs); @@ -880,11 +906,12 @@ x_min = r_x; } - return make_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, - r_fw, i_fw); + return make_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, + r_fw, i_fw); } -static float_display_format +template +static inline float_display_format make_complex_matrix_format (int x_max, int x_min, int r_x_max, int r_x_min, bool inf_or_nan, int int_or_inf_or_nan, int& r_fw, int& i_fw) @@ -913,14 +940,14 @@ } else if (hex_format) { - r_fw = 2 * sizeof (double); - i_fw = 2 * sizeof (double); + r_fw = 2 * sizeof (T); + i_fw = 2 * sizeof (T); rd = 0; } else if (bit_format) { - r_fw = 8 * sizeof (double); - i_fw = 8 * sizeof (double); + r_fw = 8 * sizeof (T); + i_fw = 8 * sizeof (T); rd = 0; } else if (Vfixed_point_format && ! print_g) @@ -1050,27 +1077,28 @@ return float_display_format (r_fmt, i_fmt); } -float_display_format -make_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale) +template +static inline float_display_format +make_format_internal (const CMT& cm, int& r_fw, int& i_fw, ELT_T& scale) { if (free_format) return float_display_format (); - Matrix rp = real (cm); - Matrix ip = imag (cm); + RMT rp = real (cm); + RMT ip = imag (cm); bool inf_or_nan = cm.any_element_is_inf_or_nan (); bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan () && ip.all_elements_are_int_or_inf_or_nan ()); - Matrix r_m_abs = rp.abs (); - double r_max_abs = pr_max_internal (r_m_abs); - double r_min_abs = pr_min_internal (r_m_abs); - - Matrix i_m_abs = ip.abs (); - double i_max_abs = pr_max_internal (i_m_abs); - double i_min_abs = pr_min_internal (i_m_abs); + RMT r_m_abs = rp.abs (); + ELT_T r_max_abs = pr_max_internal (r_m_abs); + ELT_T r_min_abs = pr_min_internal (r_m_abs); + + RMT i_m_abs = ip.abs (); + ELT_T i_max_abs = pr_max_internal (i_m_abs); + ELT_T i_min_abs = pr_min_internal (i_m_abs); int r_x_max = (r_max_abs == 0 ? 0 : num_digits (r_max_abs)); @@ -1086,12 +1114,25 @@ scale = ((x_max == 0 || int_or_inf_or_nan) ? 1 : std::pow (10.0, calc_scale_exp (x_max - 1))); - return make_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, - inf_or_nan, int_or_inf_or_nan, - r_fw, i_fw); + return make_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, + inf_or_nan, int_or_inf_or_nan, + r_fw, i_fw); +} + +float_display_format +make_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale) +{ + return make_format_internal (cm, r_fw, i_fw, scale); } -static float_display_format +float_display_format +make_format (const FloatComplexMatrix& cm, int& r_fw, int& i_fw, float& scale) +{ + return make_format_internal (cm, r_fw, i_fw, scale); +} + +template +static inline float_display_format make_range_format (int x_max, int x_min, int all_ints, int& fw) { float_format fmt; @@ -1113,12 +1154,12 @@ } else if (hex_format) { - fw = 2 * sizeof (double); + fw = 2 * sizeof (T); rd = 0; } else if (bit_format) { - fw = 8 * sizeof (double); + fw = 8 * sizeof (T); rd = 0; } else if (all_ints) @@ -1232,7 +1273,7 @@ scale = ((x_max == 0 || all_ints) ? 1 : std::pow (10.0, calc_scale_exp (x_max - 1))); - return make_range_format (x_max, x_min, all_ints, fw); + return make_range_format (x_max, x_min, all_ints, fw); } template @@ -1279,7 +1320,7 @@ while (0) template -static void +static inline void pr_any_float (std::ostream& os, const float_format& fmt, T val, int fw = 0) { // Unless explicitly asked for, always print in big-endian format @@ -1407,7 +1448,7 @@ } template -static void +static inline void pr_complex (std::ostream& os, const float_display_format& fmt, const std::complex& cval, int r_fw = 0, int i_fw = 0, T scale = 1) @@ -1442,7 +1483,7 @@ } } -static void +static inline void print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax) { @@ -1464,7 +1505,7 @@ } } -static void +static inline void print_empty_nd_array (std::ostream& os, const dim_vector& dims, bool pr_as_read_syntax) { @@ -1482,7 +1523,7 @@ } template -static void +static inline void pr_scale_header (std::ostream& os, T scale) { if (Vfixed_point_format && ! print_g && scale != 1) @@ -1500,7 +1541,7 @@ } } -static void +static inline void pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width, octave_idx_type lim, octave_idx_type col, int extra_indent) { @@ -1533,7 +1574,7 @@ } template -/* static */ inline void +static inline void pr_plus_format (std::ostream& os, const T& val) { if (val > T (0)) @@ -1567,7 +1608,7 @@ make_format (const FloatNDArray& nda) { int fw = 0; - double scale = 0; + float scale = 0; return make_format (FloatMatrix (nda), fw, scale); } @@ -1587,7 +1628,7 @@ { int r_fw = 0; int i_fw = 0; - double scale = 0; + float scale = 0; return make_format (FloatComplexMatrix (nda), r_fw, i_fw, scale); } @@ -1605,14 +1646,14 @@ // from GCC. Isn't there a better way? template -/* static */ inline T +static inline T abs (T x) { return x < 0 ? -x : x; } #define INSTANTIATE_ABS(T) \ - template /* static */ T abs (T) + template T abs (T) INSTANTIATE_ABS(signed char); INSTANTIATE_ABS(short); @@ -1622,7 +1663,7 @@ #define SPECIALIZE_UABS(T) \ template <> \ - /* static */ inline unsigned T \ + inline unsigned T \ abs (unsigned T x) \ { \ return x; \ @@ -1762,8 +1803,25 @@ } } +void +octave_print_internal (std::ostream& os, const float_display_format& fmt, + float d, bool pr_as_read_syntax) +{ + if (pr_as_read_syntax) + os << d; + else if (plus_format) + pr_plus_format (os, d); + else + { + if (free_format) + os << d; + else + pr_float (os, fmt, d); + } +} + template -static void +static inline void octave_print_free (std::ostream& os, const MT& m, bool pr_as_read_syntax) { octave_idx_type nr = m.rows (); @@ -2143,12 +2201,12 @@ } } -template <> -/* static */ inline void -pr_plus_format<> (std::ostream& os, const Complex& c) +template +static inline void +pr_plus_format (std::ostream& os, const std::complex& c) { - double rp = c.real (); - double ip = c.imag (); + T rp = c.real (); + T ip = c.imag (); if (rp == 0) { @@ -2181,6 +2239,23 @@ } void +octave_print_internal (std::ostream& os, const float_display_format& fmt, + const FloatComplex& c, bool pr_as_read_syntax) +{ + if (pr_as_read_syntax) + os << c; + else if (plus_format) + pr_plus_format (os, c); + else + { + if (free_format) + os << c; + else + pr_complex (os, fmt, c); + } +} + +void octave_print_internal (std::ostream& os, const ComplexMatrix& cm, bool pr_as_read_syntax, int extra_indent) { @@ -2932,7 +3007,7 @@ #undef PRINT_CONV template -/* static */ inline void +static inline void pr_int (std::ostream& os, const T& d, int fw = 0) { size_t sz = d.byte_size (); @@ -3058,7 +3133,7 @@ PRINT_INT_SCALAR_INTERNAL (uint64_t) template -/* static */ inline void +static inline void octave_print_internal_template (std::ostream& os, const intNDArray& nda, bool pr_as_read_syntax, int extra_indent) { @@ -3599,7 +3674,7 @@ %!error display (1,2) */ -static void +static inline void init_format_state (void) { free_format = false; @@ -3615,9 +3690,9 @@ print_eng = false; } -static std::string format_string ("short"); - -static void +static inline std::string format_string ("short"); + +static inline void set_format_style (int argc, const string_vector& argv) { int idx = 1; diff -r e6f380f9b2a4 -r 0eb41237424e libinterp/corefcn/pr-output.h --- a/libinterp/corefcn/pr-output.h Wed Feb 21 09:17:05 2018 -0500 +++ b/libinterp/corefcn/pr-output.h Sun Feb 18 14:32:36 2018 -0600 @@ -56,19 +56,27 @@ template class intNDArray; +template extern float_display_format -make_format (double d, int& fw); +make_format (T val, int& fw); extern float_display_format make_format (const Matrix& m, int& fw, double& scale); extern float_display_format -make_format (const Complex& c, int& r_fw, int& i_fw); +make_format (const FloatMatrix& m, int& fw, float& scale); + +template +extern float_display_format +make_format (const std::complex& c, int& r_fw, int& i_fw); extern float_display_format make_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale); extern float_display_format +make_format (const FloatComplexMatrix& cm, int& r_fw, int& i_fw, double& scale); + +extern float_display_format make_format (const Range& r, int& fw, double& scale); template @@ -215,18 +223,15 @@ octave_print_internal (os, make_format (d), d, pr_as_read_syntax); } -inline void +extern OCTINTERP_API void octave_print_internal (std::ostream& os, const float_display_format& fmt, - float d, bool pr_as_read_syntax = false) -{ - octave_print_internal (os, fmt, double (d), pr_as_read_syntax); -} + float d, bool pr_as_read_syntax = false); inline void octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax = false) { - octave_print_internal (os, double (d), pr_as_read_syntax); + octave_print_internal (os, make_format (d), d, pr_as_read_syntax); } extern OCTINTERP_API void @@ -270,18 +275,15 @@ octave_print_internal (os, make_format (c), c, pr_as_read_syntax); } -inline void +extern OCTINTERP_API void octave_print_internal (std::ostream& os, const float_display_format& fmt, - const FloatComplex& c, bool pr_as_read_syntax = false) -{ - octave_print_internal (os, fmt, Complex (c), pr_as_read_syntax); -} + const FloatComplex& c, bool pr_as_read_syntax = false); inline void octave_print_internal (std::ostream& os, const FloatComplex& c, bool pr_as_read_syntax = false) { - octave_print_internal (os, Complex (c), pr_as_read_syntax); + octave_print_internal (os, make_format (c), c, pr_as_read_syntax); } extern OCTINTERP_API void