Mercurial > hg > octave-nkf
changeset 17416:6690dba6078a
improve efficiency of fwrite
* oct-stream.h, oct-stream.cc (write_int, do_write): Delete.
(convert_ints, convert_data, octave_stream::write_bytes
octave_stream::skip_bytes): New functions.
(octave_stream::write): Improve efficiency by writing data in larger
chunks.
* oct-stream.cc: Delete unnecessary template instantiations.
* data-conv.h, data-conv.cc (is_equivalent_type): New template.
Provide specializations for core Octave data types.
(oct_data_conv::data_type_size): New function.
(oct_data_conv::data_type_to_string): Correct spelling of unsigned.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 13 Sep 2013 23:31:11 -0400 |
parents | 3856298f1ff8 |
children | 9289bb0ff4dd |
files | libinterp/corefcn/file-io.cc libinterp/corefcn/oct-stream.cc libinterp/corefcn/oct-stream.h liboctave/util/data-conv.cc liboctave/util/data-conv.h |
diffstat | 5 files changed, 471 insertions(+), 322 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/file-io.cc +++ b/libinterp/corefcn/file-io.cc @@ -1556,10 +1556,6 @@ IEEE little endian.\n\ @end table\n\ \n\ -@noindent\n\ -Conversions are currently only supported for @qcode{\"ieee-be\"} and\n\ -@qcode{\"ieee-le\"} formats.\n\ -\n\ The data read from the file is returned in @var{val}, and the number of\n\ values read is returned in @code{count}\n\ @seealso{fwrite, fgets, fgetl, fscanf, fopen}\n\
--- a/libinterp/corefcn/oct-stream.cc +++ b/libinterp/corefcn/oct-stream.cc @@ -1189,29 +1189,6 @@ return is >> valptr; } -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, long int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, short int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned long int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned short int*); - -#if 0 -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, float*); -#endif - template<> std::istream& octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double* valptr) @@ -1278,36 +1255,6 @@ } template void -do_scanf_conv (std::istream&, const scanf_format_elt&, int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, long int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, short int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned long int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned short int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -#if 0 -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, float*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); -#endif - -template void do_scanf_conv (std::istream&, const scanf_format_elt&, double*, Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); @@ -2402,30 +2349,6 @@ return retval; } -template int -do_printf_conv (std::ostream&, const char*, int, int, int, int, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, long, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, unsigned int, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, unsigned long, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, double, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, const char*, - const std::string&); - #define DO_DOUBLE_CONV(TQUAL) \ do \ { \ @@ -3199,44 +3122,11 @@ return retval; } -#define DO_READ_VAL_TEMPLATE(RET_T, READ_T) \ - template octave_value \ - do_read<RET_T, READ_T> (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, \ - oct_mach_info::float_format, octave_idx_type&) - -// FIXME -- should we only have float if it is a different -// size from double? - -#define INSTANTIATE_DO_READ(VAL_T) \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int8); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint8); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int16); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint16); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int32); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint32); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int64); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint64); \ - DO_READ_VAL_TEMPLATE (VAL_T, float); \ - DO_READ_VAL_TEMPLATE (VAL_T, double); \ - DO_READ_VAL_TEMPLATE (VAL_T, char); \ - DO_READ_VAL_TEMPLATE (VAL_T, signed char); \ - DO_READ_VAL_TEMPLATE (VAL_T, unsigned char) - -INSTANTIATE_DO_READ (int8NDArray); -INSTANTIATE_DO_READ (uint8NDArray); -INSTANTIATE_DO_READ (int16NDArray); -INSTANTIATE_DO_READ (uint16NDArray); -INSTANTIATE_DO_READ (int32NDArray); -INSTANTIATE_DO_READ (uint32NDArray); -INSTANTIATE_DO_READ (int64NDArray); -INSTANTIATE_DO_READ (uint64NDArray); -INSTANTIATE_DO_READ (FloatNDArray); -INSTANTIATE_DO_READ (NDArray); -INSTANTIATE_DO_READ (charNDArray); -INSTANTIATE_DO_READ (boolNDArray); - -typedef octave_value (*read_fptr) (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, - oct_mach_info::float_format ffmt, octave_idx_type&); +typedef octave_value (*read_fptr) (octave_stream&, octave_idx_type, + octave_idx_type, octave_idx_type, + octave_idx_type, bool, bool, + oct_mach_info::float_format ffmt, + octave_idx_type&); #define FILL_TABLE_ROW(R, VAL_T) \ read_fptr_table[R][oct_data_conv::dt_int8] = do_read<VAL_T, octave_int8>; \ @@ -3381,103 +3271,106 @@ return retval; } -template <class T> -void -write_int (std::ostream& os, bool swap, const T& val) +template <class T, class V> +static void +convert_ints (const T *data, void *conv_data, octave_idx_type n_elts, + bool swap) { - typename T::val_type tmp = val.value (); - - if (swap) - swap_bytes<sizeof (typename T::val_type)> (&tmp); - - os.write (reinterpret_cast<const char *> (&tmp), - sizeof (typename T::val_type)); + typedef typename V::val_type val_type; + + val_type *vt_data = static_cast <val_type *> (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + V val (data[i]); + + vt_data[i] = val.value (); + + if (swap) + swap_bytes<sizeof (val_type)> (&vt_data[i]); + } } -template void write_int (std::ostream&, bool, const octave_int8&); -template void write_int (std::ostream&, bool, const octave_uint8&); -template void write_int (std::ostream&, bool, const octave_int16&); -template void write_int (std::ostream&, bool, const octave_uint16&); -template void write_int (std::ostream&, bool, const octave_int32&); -template void write_int (std::ostream&, bool, const octave_uint32&); -template void write_int (std::ostream&, bool, const octave_int64&); -template void write_int (std::ostream&, bool, const octave_uint64&); - template <class T> -static inline bool -do_write (std::ostream& os, const T& val, oct_data_conv::data_type output_type, - oct_mach_info::float_format flt_fmt, bool swap, - bool do_float_conversion) +static bool +convert_data (const T *data, void *conv_data, octave_idx_type n_elts, + oct_data_conv::data_type output_type, + oct_mach_info::float_format flt_fmt) { bool retval = true; - // For compatibility, Octave converts to the output type, then - // writes. This means that truncation happens on the conversion. - // For example, the following program prints 0: - // - // x = int8 (-1) - // f = fopen ("foo.dat", "w"); - // fwrite (f, x, "unsigned char"); - // fclose (f); - // f = fopen ("foo.dat", "r"); - // y = fread (f, 1, "unsigned char"); - // printf ("%d\n", y); + bool swap + = ((oct_mach_info::words_big_endian () + && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian) + || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + bool do_float_conversion = flt_fmt != oct_mach_info::float_format (); + + // We use octave_intN classes here instead of converting directly to + // intN_t so that we get integer saturation semantics. switch (output_type) { case oct_data_conv::dt_char: case oct_data_conv::dt_schar: case oct_data_conv::dt_int8: - write_int (os, swap, octave_int8 (val)); + convert_ints<T, octave_int8> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uchar: case oct_data_conv::dt_uint8: - write_int (os, swap, octave_uint8 (val)); + convert_ints<T, octave_uint8> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int16: - write_int (os, swap, octave_int16 (val)); + convert_ints<T, octave_int16> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint16: - write_int (os, swap, octave_uint16 (val)); + convert_ints<T, octave_uint16> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int32: - write_int (os, swap, octave_int32 (val)); + convert_ints<T, octave_int32> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint32: - write_int (os, swap, octave_uint32 (val)); + convert_ints<T, octave_uint32> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int64: - write_int (os, swap, octave_int64 (val)); + convert_ints<T, octave_int64> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint64: - write_int (os, swap, octave_uint64 (val)); + convert_ints<T, octave_uint64> (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_single: { - float f = static_cast<float> (val); - - if (do_float_conversion) - do_float_format_conversion (&f, 1, flt_fmt); - - os.write (reinterpret_cast<const char *> (&f), sizeof (float)); + float *vt_data = static_cast <float *> (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + vt_data[i] = data[i]; + + if (do_float_conversion) + do_float_format_conversion (&vt_data[i], 1, flt_fmt); + } } break; case oct_data_conv::dt_double: { - double d = static_cast<double> (val); - if (do_float_conversion) - do_double_format_conversion (&d, 1, flt_fmt); - - os.write (reinterpret_cast<const char *> (&d), sizeof (double)); + double *vt_data = static_cast <double *> (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + vt_data[i] = data[i]; + + if (do_float_conversion) + do_double_format_conversion (&vt_data[i], 1, flt_fmt); + } } break; @@ -3491,162 +3384,174 @@ return retval; } +bool +octave_stream::write_bytes (const void *data, size_t nbytes) +{ + bool status = false; + + std::ostream *osp = output_stream (); + + if (osp) + { + std::ostream& os = *osp; + + if (os) + { + os.write (static_cast<const char *> (data), nbytes); + + if (os) + status = true; + } + } + + return status; +} + +bool +octave_stream::skip_bytes (size_t skip) +{ + bool status = false; + + std::ostream *osp = output_stream (); + + if (osp) + { + std::ostream& os = *osp; + + // Seek to skip when inside bounds of existing file. + // Otherwise, write NUL to skip. + + off_t orig_pos = tell (); + + seek (0, SEEK_END); + + off_t eof_pos = tell (); + + // Is it possible for this to fail to return us to the + // original position? + seek (orig_pos, SEEK_SET); + + size_t remaining = eof_pos - orig_pos; + + if (remaining < skip) + { + seek (0, SEEK_END); + + // FIXME -- probably should try to write larger blocks... + + unsigned char zero = 0; + for (size_t j = 0; j < skip - remaining; j++) + os.write (reinterpret_cast<const char *> (&zero), 1); + } + else + seek (skip, SEEK_CUR); + + if (os) + status = true; + } + + return status; +} + template <class T> octave_idx_type octave_stream::write (const Array<T>& data, octave_idx_type block_size, oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt) + octave_idx_type skip, + oct_mach_info::float_format flt_fmt) { - octave_idx_type retval = -1; - - bool status = true; - - octave_idx_type count = 0; - - const T *d = data.data (); - - octave_idx_type n = data.length (); - - oct_mach_info::float_format native_flt_fmt - = oct_mach_info::float_format (); - - bool do_float_conversion = (flt_fmt != native_flt_fmt); - - bool swap = false; - - if (oct_mach_info::words_big_endian ()) - swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian); + bool swap + = ((oct_mach_info::words_big_endian () + && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian) + || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + bool do_data_conversion + = (swap || ! is_equivalent_type<T> (output_type) + || flt_fmt != oct_mach_info::float_format ()); + + octave_idx_type nel = data.numel (); + + octave_idx_type chunk_size; + + if (skip != 0) + chunk_size = block_size; + else if (do_data_conversion) + chunk_size = 1024 * 1024; else - swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); - - for (octave_idx_type i = 0; i < n; i++) + chunk_size = nel; + + octave_idx_type i = 0; + + const T *pdata = data.data (); + + while (i < nel) { - std::ostream *osp = output_stream (); - - if (osp) + if (skip != 0) { - std::ostream& os = *osp; - - if (skip != 0 && (i % block_size) == 0) - { - // Seek to skip when inside bounds of existing file. - // Otherwise, write NUL to skip. - - off_t orig_pos = tell (); - - seek (0, SEEK_END); - - off_t eof_pos = tell (); - - // Is it possible for this to fail to return us to the - // original position? - seek (orig_pos, SEEK_SET); - - off_t remaining = eof_pos - orig_pos; - - if (remaining < skip) - { - seek (0, SEEK_END); - - // FIXME -- probably should try to write larger - // blocks... - - unsigned char zero = 0; - for (octave_idx_type j = 0; j < skip - remaining; j++) - os.write (reinterpret_cast<const char *> (&zero), 1); - } - else - seek (skip, SEEK_CUR); - } - - if (os) - { - status = do_write (os, d[i], output_type, flt_fmt, swap, - do_float_conversion); - - if (os && status) - count++; - else - break; - } - else - { - status = false; - break; - } + if (! skip_bytes (skip)) + return -1; + } + + octave_idx_type remaining_nel = nel - i; + + if (chunk_size > remaining_nel) + chunk_size = remaining_nel; + + bool status = false; + + if (do_data_conversion) + { + size_t output_size + = chunk_size * oct_data_conv::data_type_size (output_type); + + OCTAVE_LOCAL_BUFFER (unsigned char, conv_data, output_size); + + status = convert_data (&pdata[i], conv_data, chunk_size, + output_type, flt_fmt); + + if (status) + status = write_bytes (conv_data, output_size); } else - { - status = false; - break; - } + status = write_bytes (pdata, sizeof (T) * chunk_size); + + if (! status) + return -1; + + i += chunk_size; } - if (status) - retval = count; - - return retval; + return nel; } -template octave_idx_type -octave_stream::write (const Array<char>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<bool>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<double>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<float>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_int8>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_uint8>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_int16>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_uint16>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_int32>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_uint32>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_int64>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array<octave_uint64>&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); +#define INSTANTIATE_WRITE(T) \ + template \ + octave_idx_type \ + octave_stream::write (const Array<T>& data, octave_idx_type block_size, \ + oct_data_conv::data_type output_type, \ + octave_idx_type skip, \ + oct_mach_info::float_format flt_fmt) + +INSTANTIATE_WRITE (octave_int8); +INSTANTIATE_WRITE (octave_uint8); +INSTANTIATE_WRITE (octave_int16); +INSTANTIATE_WRITE (octave_uint16); +INSTANTIATE_WRITE (octave_int32); +INSTANTIATE_WRITE (octave_uint32); +INSTANTIATE_WRITE (octave_int64); +INSTANTIATE_WRITE (octave_uint64); +INSTANTIATE_WRITE (int8_t); +INSTANTIATE_WRITE (uint8_t); +INSTANTIATE_WRITE (int16_t); +INSTANTIATE_WRITE (uint16_t); +INSTANTIATE_WRITE (int32_t); +INSTANTIATE_WRITE (uint32_t); +INSTANTIATE_WRITE (int64_t); +INSTANTIATE_WRITE (uint64_t); +INSTANTIATE_WRITE (bool); +INSTANTIATE_WRITE (char); +INSTANTIATE_WRITE (float); +INSTANTIATE_WRITE (double); octave_value octave_stream::scanf (const std::string& fmt, const Array<double>& size,
--- a/libinterp/corefcn/oct-stream.h +++ b/libinterp/corefcn/oct-stream.h @@ -37,6 +37,7 @@ #include "data-conv.h" #include "lo-utils.h" #include "mach-info.h" +#include "oct-locbuf.h" #include "oct-refcount.h" class @@ -539,13 +540,19 @@ octave_idx_type& count); octave_idx_type write (const octave_value& data, octave_idx_type block_size, - oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt); + oct_data_conv::data_type output_type, + octave_idx_type skip, + oct_mach_info::float_format flt_fmt); + + bool write_bytes (const void *data, size_t n_elts); + + bool skip_bytes (size_t n_elts); template <class T> - octave_idx_type write (const Array<T>&, octave_idx_type block_size, - oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt); + octave_idx_type write (const Array<T>& data, octave_idx_type block_size, + oct_data_conv::data_type output_type, + octave_idx_type skip, + oct_mach_info::float_format flt_fmt); octave_value scanf (const std::string& fmt, const Array<double>& size, octave_idx_type& count, const std::string& who /* = "scanf" */);
--- a/liboctave/util/data-conv.cc +++ b/liboctave/util/data-conv.cc @@ -174,6 +174,111 @@ } \ while (0) +size_t +oct_data_conv::data_type_size (data_type dt) +{ + size_t retval = -1; + + switch (dt) + { + case oct_data_conv::dt_int8: + retval = sizeof (int8_t); + break; + + case oct_data_conv::dt_uint8: + retval = sizeof (uint8_t); + break; + + case oct_data_conv::dt_int16: + retval = sizeof (int16_t); + break; + + case oct_data_conv::dt_uint16: + retval = sizeof (uint16_t); + break; + + case oct_data_conv::dt_int32: + retval = sizeof (int32_t); + break; + + case oct_data_conv::dt_uint32: + retval = sizeof (uint32_t); + break; + + case oct_data_conv::dt_int64: + retval = sizeof (int64_t); + break; + + case oct_data_conv::dt_uint64: + retval = sizeof (uint64_t); + break; + + case oct_data_conv::dt_float: + case oct_data_conv::dt_single: + retval = sizeof (float); + break; + + case oct_data_conv::dt_double: + retval = sizeof (double); + break; + + case oct_data_conv::dt_char: + retval = sizeof (char); + break; + + case oct_data_conv::dt_schar: + retval = sizeof (signed char); + break; + + case oct_data_conv::dt_uchar: + retval = sizeof (unsigned char); + break; + + case oct_data_conv::dt_short: + retval = sizeof (short); + break; + + case oct_data_conv::dt_ushort: + retval = sizeof (unsigned short); + break; + + case oct_data_conv::dt_int: + retval = sizeof (int); + break; + + case oct_data_conv::dt_uint: + retval = sizeof (unsigned int); + break; + + case oct_data_conv::dt_long: + retval = sizeof (long); + break; + + case oct_data_conv::dt_ulong: + retval = sizeof (unsigned long); + break; + + case oct_data_conv::dt_longlong: + retval = sizeof (long long); + break; + + case oct_data_conv::dt_ulonglong: + retval = sizeof (unsigned long long); + break; + + case oct_data_conv::dt_logical: + retval = sizeof (bool); + break; + + case oct_data_conv::dt_unknown: + default: + abort (); + break; + } + + return retval; +} + oct_data_conv::data_type oct_data_conv::string_to_data_type (const std::string& str) { @@ -426,7 +531,7 @@ break; case oct_data_conv::dt_uchar: - retval = "usigned char"; + retval = "unsigned char"; break; case oct_data_conv::dt_short: @@ -442,7 +547,7 @@ break; case oct_data_conv::dt_uint: - retval = "usigned int"; + retval = "unsigned int"; break; case oct_data_conv::dt_long: @@ -450,7 +555,7 @@ break; case oct_data_conv::dt_ulong: - retval = "usigned long"; + retval = "unsigned long"; break; case oct_data_conv::dt_longlong:
--- a/liboctave/util/data-conv.h +++ b/liboctave/util/data-conv.h @@ -26,6 +26,7 @@ #include <limits> #include "mach-info.h" +#include "oct-inttypes.h" class OCTAVE_API @@ -61,6 +62,8 @@ dt_unknown = 23 // Must be last, have largest value! }; + static size_t data_type_size (data_type dt); + static data_type string_to_data_type (const std::string& s); static void string_to_data_type (const std::string& s, int& block_size, @@ -125,4 +128,137 @@ write_floats (std::ostream& os, const float *data, save_type type, octave_idx_type len); +template <typename T> +inline bool +is_equivalent_type (oct_data_conv::data_type) +{ + return false; +} + +template <> +inline bool +is_equivalent_type<int8_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int8; +} + +template <> +inline bool +is_equivalent_type<int16_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int16; +} + +template <> +inline bool +is_equivalent_type<int32_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int32; +} + +template <> +inline bool +is_equivalent_type<int64_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int64; +} + +template <> +inline bool +is_equivalent_type<uint8_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint8; +} + +template <> +inline bool +is_equivalent_type<uint16_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint16; +} + +template <> +inline bool +is_equivalent_type<uint32_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint32; +} + +template <> +inline bool +is_equivalent_type<uint64_t> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint64; +} + +template <> +inline bool +is_equivalent_type<octave_int8> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int8; +} + +template <> +inline bool +is_equivalent_type<octave_int16> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int16; +} + +template <> +inline bool +is_equivalent_type<octave_int32> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int32; +} + +template <> +inline bool +is_equivalent_type<octave_int64> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int64; +} + +template <> +inline bool +is_equivalent_type<octave_uint8> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint8; +} + +template <> +inline bool +is_equivalent_type<octave_uint16> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint16; +} + +template <> +inline bool +is_equivalent_type<octave_uint32> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint32; +} + +template <> +inline bool +is_equivalent_type<octave_uint64> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint64; +} + +template <> +inline bool +is_equivalent_type<double> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_double; +} + +template <> +inline bool +is_equivalent_type<float> (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_single || t == oct_data_conv::dt_float; +} + #endif