Mercurial > octave
changeset 21573:f3f8e1d3e399 stable
avoid mulitple definitions of static function-scope vars (bug #47372)
Some systems (Windows, others?) may generate multiple definitions of
function-scope static variables if those functions appear in header
files. This can cause trouble in various ways. Attempt to avoid the
problem by moving functions that contain file-scope varaibles from
header files to source files, or by using class-scope static variables
instead. Also attempt to avoid similar problems caused by implicit
instantiations of templates that have functions with static variables.
* Cell.h, Cell.cc (Cell::resize_fill_value):
Move definition from header to source file.
* oct-map.h, oct-map.cc (octave_fields::nil_rep): Likewise.
* ov-base-scalar.h, ov-base-scalar.cc (octave_base_scalar<ST>::dims):
Likewise.
* ov-fcn-handle.h, ov-fcn-handle.cc (octave_fcn_handle::dims): Likewise.
* ov.h, ov.cc (octave_value::nil_rep): Likewise.
* Array.h, Array.cc (Array<T>::nil_rep): Likewise.
* DiagArray2.h, DiagArray2.cc (DiagArray2<T>::elem,
DiagArray2<T>::checkelem): Likewise.
* Sparse.h, Sparse.cc (Sparse<T>::nil_rep): Likewise.
* dim-vector.h, dim-vector.cc (dim_vector::nil_rep): Likewise.
* idx-vector.h, idx-vector.cc (idx_vector::nil_rep,
idx_vector::err_rep): Likewise.
* oct-inttypes.h, oct-inttypes.cc (octave_int_base<T>::convert_real):
Likewise.
* symtab.h, symtab.cc (octave_value symbol_table::dummy_octave_value,
symbol_table::symbol_record symbol_table::dummy_symbol_record): New
class-scope static variables. Use them to eliminate function-scope
static variables.
* ov-int8.cc, ov-int16.cc, ov-int32.cc, ov-int64.cc, ov-uint8.cc,
ov-uint16.cc, ov-uint32.cc, ov-uint64.cc, ov-scalar.cc,
ov-flt-complex.cc, ov-complex.cc, ov-classdef.cc, ov-bool.cc,
Array-jit.cc, Array-os.cc, Array-tc.cc, Array-C.cc, Array-b.cc,
Array-ch.cc, Array-d.cc, Array-f.cc, Array-fC.cc, Array-i.cc,
Array-idx-vec.cc, Array-s.cc, Array-str.cc, Array-voidp.cc:
Prevent impliticit template instantiation.
* Array-tc.cc: Also instantiate Array<cdef_object>.
line wrap: on
line diff
--- a/libinterp/corefcn/Cell.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/Cell.cc Fri Apr 01 12:04:04 2016 -0400 @@ -319,6 +319,13 @@ return retval; } +octave_value +Cell::resize_fill_value (void) const +{ + static octave_value rfv = octave_value (Matrix ()); + return rfv; +} + Cell Cell::diag (octave_idx_type k) const {
--- a/libinterp/corefcn/Cell.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/Cell.h Fri Apr 01 12:04:04 2016 -0400 @@ -109,11 +109,7 @@ bool any_element_is_nan (void) const { return false; } bool is_true (void) const { return false; } - octave_value resize_fill_value (void) const - { - static Matrix rfv; - return rfv; - } + octave_value resize_fill_value (void) const; Cell diag (octave_idx_type k = 0) const;
--- a/libinterp/corefcn/oct-map.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/oct-map.cc Fri Apr 01 12:04:04 2016 -0400 @@ -33,6 +33,13 @@ #include "oct-map.h" #include "utils.h" +octave_fields::fields_rep * +octave_fields::nil_rep (void) +{ + static fields_rep nr; + return &nr; +} + octave_fields::octave_fields (const string_vector& fields) : rep (new fields_rep) {
--- a/libinterp/corefcn/oct-map.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/oct-map.h Fri Apr 01 12:04:04 2016 -0400 @@ -51,11 +51,7 @@ fields_rep *rep; - static fields_rep *nil_rep (void) - { - static fields_rep nr; - return &nr; - } + static fields_rep *nil_rep (void); public:
--- a/libinterp/corefcn/symtab.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/symtab.cc Fri Apr 01 12:04:04 2016 -0400 @@ -48,6 +48,8 @@ #include "unwind-prot.h" #include "utils.h" +octave_value symbol_table::dummy_octave_value; + symbol_table *symbol_table::instance = 0; symbol_table::scope_id_cache *symbol_table::scope_id_cache::instance = 0; @@ -150,6 +152,8 @@ return retval; } +symbol_table::symbol_record symbol_table::dummy_symbol_record; + static void split_name_with_package (const std::string& name, std::string& fname, std::string& pname)
--- a/libinterp/corefcn/symtab.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/corefcn/symtab.h Fri Apr 01 12:04:04 2016 -0400 @@ -47,6 +47,8 @@ { public: + static octave_value dummy_octave_value; + typedef int scope_id; typedef size_t context_id; @@ -266,12 +268,10 @@ } else if (is_persistent ()) { - static octave_value foobar; - symbol_table *inst = symbol_table::get_instance (symbol_table::current_scope ()); - return inst ? inst->do_persistent_varref (name) : foobar; + return inst ? inst->do_persistent_varref (name) : dummy_octave_value; } else { @@ -658,6 +658,8 @@ symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { } }; + static symbol_record dummy_symbol_record; + // Always access a symbol from the current scope. // Useful for scripts, as they may be executed in more than one scope. class @@ -1315,11 +1317,9 @@ static symbol_record& insert (const std::string& name, scope_id scope = xcurrent_scope) { - static symbol_record foobar; - symbol_table *inst = get_instance (scope); - return inst ? inst->do_insert (name) : foobar; + return inst ? inst->do_insert (name) : symbol_table::dummy_symbol_record; } static void rename (const std::string& old_name, @@ -1338,8 +1338,6 @@ context_id context = xdefault_context, bool force_add = false) { - static octave_value foobar; - symbol_table *inst = get_instance (scope); if (inst) @@ -1352,11 +1350,9 @@ context_id context = xdefault_context, bool force_add = false) GCC_ATTR_DEPRECATED { - static octave_value foobar; - symbol_table *inst = get_instance (scope); - return inst ? inst->do_varref (name, context, force_add) : foobar; + return inst ? inst->do_varref (name, context, force_add) : dummy_octave_value; } // Convenience function to simplify @@ -1375,11 +1371,9 @@ force_varref (const std::string& name, scope_id scope = xcurrent_scope, context_id context = xdefault_context) GCC_ATTR_DEPRECATED { - static octave_value foobar; - symbol_table *inst = get_instance (scope); - return inst ? inst->do_varref (name, context, true) : foobar; + return inst ? inst->do_varref (name, context, true) : dummy_octave_value; } static octave_value varval (const std::string& name, @@ -1433,11 +1427,9 @@ static octave_value& top_level_varref (const std::string& name) GCC_ATTR_DEPRECATED { - static octave_value foobar; - symbol_table *inst = get_instance (top_scope ()); - return inst ? inst->do_varref (name, 0, true) : foobar; + return inst ? inst->do_varref (name, 0, true) : dummy_octave_value; } static octave_value @@ -1460,11 +1452,9 @@ static octave_value& persistent_varref (const std::string& name) GCC_ATTR_DEPRECATED { - static octave_value foobar; - symbol_table *inst = get_instance (xcurrent_scope); - return inst ? inst->do_persistent_varref (name) : foobar; + return inst ? inst->do_persistent_varref (name) : dummy_octave_value; } static octave_value persistent_varval (const std::string& name)
--- a/libinterp/octave-value/ov-base-scalar.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-base-scalar.cc Fri Apr 01 12:04:04 2016 -0400 @@ -100,6 +100,14 @@ } template <class ST> +dim_vector +octave_base_scalar<ST>::dims (void) const +{ + static dim_vector dv (1, 1); + return dv; +} + +template <class ST> octave_value octave_base_scalar<ST>::permute (const Array<int>& vec, bool inv) const {
--- a/libinterp/octave-value/ov-base-scalar.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-base-scalar.h Fri Apr 01 12:04:04 2016 -0400 @@ -77,7 +77,7 @@ bool is_defined (void) const { return true; } - dim_vector dims (void) const { static dim_vector dv (1, 1); return dv; } + dim_vector dims (void) const; octave_idx_type numel (void) const { return 1; }
--- a/libinterp/octave-value/ov-bool.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-bool.cc Fri Apr 01 12:04:04 2016 -0400 @@ -45,6 +45,12 @@ #include "ls-oct-ascii.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_scalar<bool>;
--- a/libinterp/octave-value/ov-classdef.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-classdef.cc Fri Apr 01 12:04:04 2016 -0400 @@ -43,8 +43,6 @@ #include "symtab.h" #include "toplev.h" -#include "Array.cc" - // Define to 1 to enable debugging statements. #define DEBUG_TRACE 0
--- a/libinterp/octave-value/ov-complex.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-complex.cc Fri Apr 01 12:04:04 2016 -0400 @@ -49,6 +49,13 @@ #include "ls-oct-ascii.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; +extern template class OCTINTERP_API octave_base_scalar<FloatComplex>; + + template class octave_base_scalar<Complex>;
--- a/libinterp/octave-value/ov-fcn-handle.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Fri Apr 01 12:04:04 2016 -0400 @@ -226,6 +226,13 @@ return retval; } +dim_vector +octave_fcn_handle::dims (void) const +{ + static dim_vector dv (1, 1); + return dv; +} + bool octave_fcn_handle::is_equal_to (const octave_fcn_handle& h) const {
--- a/libinterp/octave-value/ov-fcn-handle.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.h Fri Apr 01 12:04:04 2016 -0400 @@ -104,7 +104,7 @@ bool is_overloaded (void) const { return has_overloads; } - dim_vector dims (void) const { static dim_vector dv (1, 1); return dv; } + dim_vector dims (void) const; octave_function *function_value (bool = false) { return fcn.function_value (); }
--- a/libinterp/octave-value/ov-flt-complex.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-flt-complex.cc Fri Apr 01 12:04:04 2016 -0400 @@ -49,6 +49,12 @@ #include "ls-oct-ascii.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<float>; + + template class octave_base_scalar<FloatComplex>;
--- a/libinterp/octave-value/ov-int16.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-int16.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<int16NDArray>; template class octave_base_int_matrix<int16NDArray>;
--- a/libinterp/octave-value/ov-int32.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-int32.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<int32NDArray>; template class octave_base_int_matrix<int32NDArray>;
--- a/libinterp/octave-value/ov-int64.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-int64.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<int64NDArray>; template class octave_base_int_matrix<int64NDArray>;
--- a/libinterp/octave-value/ov-int8.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-int8.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<int8NDArray>; template class octave_base_int_matrix<int8NDArray>;
--- a/libinterp/octave-value/ov-scalar.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-scalar.cc Fri Apr 01 12:04:04 2016 -0400 @@ -52,6 +52,12 @@ #include "ls-oct-ascii.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<float>; + + template class octave_base_scalar<double>;
--- a/libinterp/octave-value/ov-uint16.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-uint16.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<uint16NDArray>; template class octave_base_int_matrix<uint16NDArray>;
--- a/libinterp/octave-value/ov-uint32.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-uint32.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<uint32NDArray>; template class octave_base_int_matrix<uint32NDArray>;
--- a/libinterp/octave-value/ov-uint64.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-uint64.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<uint64NDArray>; template class octave_base_int_matrix<uint64NDArray>;
--- a/libinterp/octave-value/ov-uint8.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov-uint8.cc Fri Apr 01 12:04:04 2016 -0400 @@ -56,6 +56,12 @@ #include "ls-utils.h" #include "ls-hdf5.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTINTERP_API octave_base_scalar<double>; + + template class octave_base_matrix<uint8NDArray>; template class octave_base_int_matrix<uint8NDArray>;
--- a/libinterp/octave-value/ov.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov.cc Fri Apr 01 12:04:04 2016 -0400 @@ -110,6 +110,13 @@ // Octave's value type. +octave_base_value * +octave_value::nil_rep (void) +{ + static octave_base_value nr; + return &nr; +} + std::string octave_value::unary_op_as_string (unary_op op) {
--- a/libinterp/octave-value/ov.h Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/octave-value/ov.h Fri Apr 01 12:04:04 2016 -0400 @@ -169,9 +169,8 @@ enum magic_colon { magic_colon_t }; octave_value (void) + : rep (nil_rep ()) { - static octave_base_value nil_rep; - rep = &nil_rep; rep->count++; } @@ -1249,6 +1248,8 @@ private: + static octave_base_value *nil_rep (void); + assign_op unary_op_to_assign_op (unary_op op); binary_op op_eq_to_binary_op (assign_op op);
--- a/libinterp/template-inst/Array-jit.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/template-inst/Array-jit.cc Fri Apr 01 12:04:04 2016 -0400 @@ -31,9 +31,13 @@ #include "Array.h" #include "Array.cc" -extern template class OCTAVE_API Array<octave_idx_type>; +#include "jit-ir.h" -#include "jit-ir.h" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; NO_INSTANTIATE_ARRAY_SORT (jit_function);
--- a/libinterp/template-inst/Array-os.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/template-inst/Array-os.cc Fri Apr 01 12:04:04 2016 -0400 @@ -29,11 +29,15 @@ #include "Array.h" #include "Array.cc" +#include "oct-stream.h" + +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + extern template class OCTAVE_API Array<bool>; +extern template class OCTAVE_API Array<idx_vector>; extern template class OCTAVE_API Array<octave_idx_type>; -#include "oct-stream.h" - typedef scanf_format_elt* scanf_format_elt_ptr; typedef printf_format_elt* printf_format_elt_ptr;
--- a/libinterp/template-inst/Array-tc.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/libinterp/template-inst/Array-tc.cc Fri Apr 01 12:04:04 2016 -0400 @@ -30,9 +30,25 @@ #include "Array.cc" #include "ov.h" +#include "ov-classdef.h" #include "oct-sort.cc" -NO_INSTANTIATE_ARRAY_SORT (octave_value); +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. +extern template class OCTAVE_API Array<Complex>; +extern template class OCTAVE_API Array<FloatComplex>; +extern template class OCTAVE_API Array<bool>; +extern template class OCTAVE_API Array<char>; +extern template class OCTAVE_API Array<double>; +extern template class OCTAVE_API Array<float>; +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; +extern template class OCTAVE_API Array<std::string>; + +NO_INSTANTIATE_ARRAY_SORT (octave_value); INSTANTIATE_ARRAY (octave_value, OCTINTERP_API); + +NO_INSTANTIATE_ARRAY_SORT (cdef_object); +INSTANTIATE_ARRAY (cdef_object, OCTINTERP_API);
--- a/liboctave/array/Array-C.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-C.cc Fri Apr 01 12:04:04 2016 -0400 @@ -34,6 +34,12 @@ #include "Array.cc" #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template <> inline bool sort_isnan<Complex> (const Complex& x)
--- a/liboctave/array/Array-b.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-b.cc Fri Apr 01 12:04:04 2016 -0400 @@ -28,10 +28,17 @@ #include "Array.h" #include "Array.cc" + #define INLINE_ASCENDING_SORT #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + // Specialize bool sorting (aka stable partitioning). template<bool desc>
--- a/liboctave/array/Array-ch.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-ch.cc Fri Apr 01 12:04:04 2016 -0400 @@ -28,10 +28,17 @@ #include "Array.h" #include "Array.cc" + #define INLINE_ASCENDING_SORT #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template class OCTAVE_API octave_sort<char>; INSTANTIATE_ARRAY (char, OCTAVE_API);
--- a/liboctave/array/Array-d.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-d.cc Fri Apr 01 12:04:04 2016 -0400 @@ -36,6 +36,12 @@ #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template <> inline bool sort_isnan<double> (double x)
--- a/liboctave/array/Array-f.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-f.cc Fri Apr 01 12:04:04 2016 -0400 @@ -36,6 +36,12 @@ #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template <> inline bool sort_isnan<float> (float x)
--- a/liboctave/array/Array-fC.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-fC.cc Fri Apr 01 12:04:04 2016 -0400 @@ -34,6 +34,12 @@ #include "Array.cc" #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template <> inline bool sort_isnan<FloatComplex> (const FloatComplex& x)
--- a/liboctave/array/Array-i.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-i.cc Fri Apr 01 12:04:04 2016 -0400 @@ -35,6 +35,11 @@ #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; + template class OCTAVE_API octave_sort<int>; template class OCTAVE_API octave_sort<long>; #if defined (HAVE_LONG_LONG_INT)
--- a/liboctave/array/Array-idx-vec.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-idx-vec.cc Fri Apr 01 12:04:04 2016 -0400 @@ -31,6 +31,11 @@ #include "Array.h" #include "Array.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<octave_idx_type>; + NO_INSTANTIATE_ARRAY_SORT (idx_vector); INSTANTIATE_ARRAY (idx_vector, OCTAVE_API);
--- a/liboctave/array/Array-s.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-s.cc Fri Apr 01 12:04:04 2016 -0400 @@ -33,6 +33,12 @@ #define INLINE_DESCENDING_SORT #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template class OCTAVE_API octave_sort<short>; INSTANTIATE_ARRAY (short, OCTAVE_API);
--- a/liboctave/array/Array-str.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-str.cc Fri Apr 01 12:04:04 2016 -0400 @@ -30,8 +30,15 @@ #include "Array.h" #include "Array.cc" + #include "oct-sort.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + template class OCTAVE_API octave_sort<std::string>; INSTANTIATE_ARRAY (std::string, OCTAVE_API);
--- a/liboctave/array/Array-voidp.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array-voidp.cc Fri Apr 01 12:04:04 2016 -0400 @@ -31,6 +31,12 @@ #include "Array.h" #include "Array.cc" +// Prevent implicit instantiations on some systems (Windows, others?) +// that can lead to duplicate definitions of static data members. + +extern template class OCTAVE_API Array<idx_vector>; +extern template class OCTAVE_API Array<octave_idx_type>; + NO_INSTANTIATE_ARRAY_SORT (void *); INSTANTIATE_ARRAY (void *, OCTAVE_API);
--- a/liboctave/array/Array.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array.cc Fri Apr 01 12:04:04 2016 -0400 @@ -45,6 +45,14 @@ // all the derived classes. template <class T> +typename Array<T>::ArrayRep * +Array<T>::nil_rep (void) +{ + static ArrayRep nr; + return &nr; +} + +template <class T> Array<T>::Array (const Array<T>& a, const dim_vector& dv) : dimensions (dv), rep (a.rep), slice_data (a.slice_data), slice_len (a.slice_len)
--- a/liboctave/array/Array.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Array.h Fri Apr 01 12:04:04 2016 -0400 @@ -149,15 +149,7 @@ private: - typename Array<T>::ArrayRep *nil_rep (void) const - { - // NR was originally allocated with new, but that does not seem - // to be necessary since it will never be deleted. So just use - // a static object instead. - - static typename Array<T>::ArrayRep nr; - return &nr; - } + static typename Array<T>::ArrayRep *nil_rep (void); protected:
--- a/liboctave/array/DiagArray2.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/DiagArray2.cc Fri Apr 01 12:04:04 2016 -0400 @@ -89,6 +89,22 @@ // A two-dimensional array with diagonal elements only. template <class T> +T& +DiagArray2<T>::elem (octave_idx_type r, octave_idx_type c) +{ + static T zero (0); + return (r == c) ? Array<T>::elem (r) : zero; +} + +template <class T> +T& +DiagArray2<T>::checkelem (octave_idx_type r, octave_idx_type c) +{ + static T zero (0); + return check_idx (r, c) ? elem (r, c) : zero; +} + +template <class T> void DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c, const T& rfv)
--- a/liboctave/array/DiagArray2.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/DiagArray2.h Fri Apr 01 12:04:04 2016 -0400 @@ -112,11 +112,7 @@ return (r == c) ? Array<T>::elem (r) : T (0); } - T& elem (octave_idx_type r, octave_idx_type c) - { - static T zero (0); - return (r == c) ? Array<T>::elem (r) : zero; - } + T& elem (octave_idx_type r, octave_idx_type c); T dgelem (octave_idx_type i) const { return Array<T>::elem (i); } @@ -138,11 +134,7 @@ #endif } - T& checkelem (octave_idx_type r, octave_idx_type c) - { - static T zero (0); - return check_idx (r, c) ? elem (r, c) : zero; - } + T& checkelem (octave_idx_type r, octave_idx_type c); T& operator () (octave_idx_type r, octave_idx_type c) {
--- a/liboctave/array/Sparse.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Sparse.cc Fri Apr 01 12:04:04 2016 -0400 @@ -53,6 +53,14 @@ #include "PermMatrix.h" template <class T> +typename Sparse<T>::SparseRep * +Sparse<T>::nil_rep (void) +{ + static typename Sparse<T>::SparseRep nr; + return &nr; +} + +template <class T> Sparse<T>::Sparse (const PermMatrix& a) : rep (new typename Sparse<T>::SparseRep (a.rows (), a.cols (), a.rows ())), dimensions (dim_vector (a.rows (), a.cols ()))
--- a/liboctave/array/Sparse.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/Sparse.h Fri Apr 01 12:04:04 2016 -0400 @@ -167,11 +167,7 @@ private: - typename Sparse<T>::SparseRep *nil_rep (void) const - { - static typename Sparse<T>::SparseRep nr; - return &nr; - } + static typename Sparse<T>::SparseRep *nil_rep (void); public:
--- a/liboctave/array/dim-vector.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/dim-vector.cc Fri Apr 01 12:04:04 2016 -0400 @@ -29,6 +29,13 @@ #include "dim-vector.h" +octave_idx_type * +dim_vector::nil_rep (void) +{ + static dim_vector zv (0, 0); + return zv.rep; +} + // The maximum allowed value for a dimension extent. This will normally be a // tiny bit off the maximum value of octave_idx_type. // Currently 1 is subtracted to allow safe conversion of any 2D Array into
--- a/liboctave/array/dim-vector.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/dim-vector.h Fri Apr 01 12:04:04 2016 -0400 @@ -243,11 +243,7 @@ private: - static octave_idx_type *nil_rep (void) - { - static dim_vector zv (0, 0); - return zv.rep; - } + static octave_idx_type *nil_rep (void); public:
--- a/liboctave/array/idx-vector.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/idx-vector.cc Fri Apr 01 12:04:04 2016 -0400 @@ -54,6 +54,21 @@ ("internal error: idx_vector index out of range"); } +idx_vector::idx_vector_rep * +idx_vector::nil_rep (void) +{ + static idx_vector_rep ivr; + return &ivr; +} + +idx_vector::idx_vector_rep * +idx_vector::err_rep (void) +{ + static idx_vector_rep ivr; + ivr.err = true; + return &ivr; +} + Array<octave_idx_type> idx_vector::idx_base_rep::as_array (void) {
--- a/liboctave/array/idx-vector.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/array/idx-vector.h Fri Apr 01 12:04:04 2016 -0400 @@ -431,19 +431,10 @@ // The shared empty vector representation (for fast default // constructor). - static idx_vector_rep *nil_rep (void) - { - static idx_vector_rep ivr; - return &ivr; - } + static idx_vector_rep *nil_rep (void); // The shared empty vector representation with the error flag set. - static idx_vector_rep *err_rep (void) - { - static idx_vector_rep ivr; - ivr.err = true; - return &ivr; - } + static idx_vector_rep *err_rep (void); // If there was an error in constructing the rep, replace it with // empty vector for safety.
--- a/liboctave/util/oct-inttypes.cc Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/util/oct-inttypes.cc Fri Apr 01 12:04:04 2016 -0400 @@ -52,6 +52,57 @@ DECLARE_OCTAVE_INT_TYPENAME (uint32_t, "uint32") DECLARE_OCTAVE_INT_TYPENAME (uint64_t, "uint64") +template <class T> +template <class S> +T +octave_int_base<T>::convert_real (const S& value) +{ + // Compute proper thresholds. + static const S thmin = compute_threshold (static_cast<S> (min_val ()), + min_val ()); + static const S thmax = compute_threshold (static_cast<S> (max_val ()), + max_val ()); + if (xisnan (value)) + { + return static_cast<T> (0); + } + else if (value < thmin) + { + return min_val (); + } + else if (value > thmax) + { + return max_val (); + } + else + { + S rvalue = xround (value); + return static_cast<T> (rvalue); + } +} + +#define INSTANTIATE_CONVERT_REAL_1(T, S) \ + template \ + OCTAVE_API \ + T \ + octave_int_base<T>::convert_real (const S&) + +#define INSTANTIATE_CONVERT_REAL(S) \ + INSTANTIATE_CONVERT_REAL_1 (int8_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (uint8_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (int16_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (uint16_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (int32_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (uint32_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (int64_t, S); \ + INSTANTIATE_CONVERT_REAL_1 (uint64_t, S) + +INSTANTIATE_CONVERT_REAL (double); +INSTANTIATE_CONVERT_REAL (float); +#if defined (OCTAVE_INT_USE_LONG_DOUBLE) +INSTANTIATE_CONVERT_REAL (long double); +#endif + #ifdef OCTAVE_INT_USE_LONG_DOUBLE #ifdef OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED
--- a/liboctave/util/oct-inttypes.h Thu Mar 31 16:13:48 2016 -0400 +++ b/liboctave/util/oct-inttypes.h Fri Apr 01 12:04:04 2016 -0400 @@ -315,34 +315,11 @@ } public: + // Convert a real number (check NaN and non-int). template <class S> static T - convert_real (const S& value) - { - // Compute proper thresholds. - static const S thmin = compute_threshold (static_cast<S> (min_val ()), - min_val ()); - static const S thmax = compute_threshold (static_cast<S> (max_val ()), - max_val ()); - if (xisnan (value)) - { - return static_cast<T> (0); - } - else if (value < thmin) - { - return min_val (); - } - else if (value > thmax) - { - return max_val (); - } - else - { - S rvalue = xround (value); - return static_cast<T> (rvalue); - } - } + convert_real (const S& value); }; // Saturated (homogeneous) integer arithmetics. The signed and unsigned