# HG changeset patch # User John W. Eaton # Date 1459526644 14400 # Node ID f3f8e1d3e39937f8fde12082f170e8aa5b466bdc # Parent 8fc45dd1cac6f4c9de90472545688bc5d8bc0f05 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::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::nil_rep): Likewise. * DiagArray2.h, DiagArray2.cc (DiagArray2::elem, DiagArray2::checkelem): Likewise. * Sparse.h, Sparse.cc (Sparse::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::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. diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/Cell.cc --- 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 { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/Cell.h --- 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; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/oct-map.cc --- 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) { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/oct-map.h --- 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: diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/symtab.cc --- 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) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/corefcn/symtab.h --- 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) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-base-scalar.cc --- 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 +dim_vector +octave_base_scalar::dims (void) const +{ + static dim_vector dv (1, 1); + return dv; +} + +template octave_value octave_base_scalar::permute (const Array& vec, bool inv) const { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-base-scalar.h --- 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; } diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-bool.cc --- 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; + + template class octave_base_scalar; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-classdef.cc --- 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 diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-complex.cc --- 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; +extern template class OCTINTERP_API octave_base_scalar; + + template class octave_base_scalar; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-fcn-handle.cc --- 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 { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-fcn-handle.h --- 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 (); } diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-flt-complex.cc --- 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; + + template class octave_base_scalar; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-int16.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-int32.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-int64.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-int8.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-scalar.cc --- 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; + + template class octave_base_scalar; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-uint16.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-uint32.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-uint64.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov-uint8.cc --- 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; + + template class octave_base_matrix; template class octave_base_int_matrix; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov.cc --- 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) { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/octave-value/ov.h --- 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); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/template-inst/Array-jit.cc --- 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; +#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; +extern template class OCTAVE_API Array; NO_INSTANTIATE_ARRAY_SORT (jit_function); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/template-inst/Array-os.cc --- 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; +extern template class OCTAVE_API Array; extern template class OCTAVE_API Array; -#include "oct-stream.h" - typedef scanf_format_elt* scanf_format_elt_ptr; typedef printf_format_elt* printf_format_elt_ptr; diff -r 8fc45dd1cac6 -r f3f8e1d3e399 libinterp/template-inst/Array-tc.cc --- 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; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; +extern template class OCTAVE_API Array; + +NO_INSTANTIATE_ARRAY_SORT (octave_value); INSTANTIATE_ARRAY (octave_value, OCTINTERP_API); + +NO_INSTANTIATE_ARRAY_SORT (cdef_object); +INSTANTIATE_ARRAY (cdef_object, OCTINTERP_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-C.cc --- 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; +extern template class OCTAVE_API Array; + template <> inline bool sort_isnan (const Complex& x) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-b.cc --- 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; +extern template class OCTAVE_API Array; + // Specialize bool sorting (aka stable partitioning). template diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-ch.cc --- 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; +extern template class OCTAVE_API Array; + template class OCTAVE_API octave_sort; INSTANTIATE_ARRAY (char, OCTAVE_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-d.cc --- 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; +extern template class OCTAVE_API Array; + template <> inline bool sort_isnan (double x) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-f.cc --- 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; +extern template class OCTAVE_API Array; + template <> inline bool sort_isnan (float x) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-fC.cc --- 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; +extern template class OCTAVE_API Array; + template <> inline bool sort_isnan (const FloatComplex& x) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-i.cc --- 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; + template class OCTAVE_API octave_sort; template class OCTAVE_API octave_sort; #if defined (HAVE_LONG_LONG_INT) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-idx-vec.cc --- 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; + NO_INSTANTIATE_ARRAY_SORT (idx_vector); INSTANTIATE_ARRAY (idx_vector, OCTAVE_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-s.cc --- 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; +extern template class OCTAVE_API Array; + template class OCTAVE_API octave_sort; INSTANTIATE_ARRAY (short, OCTAVE_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-str.cc --- 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; +extern template class OCTAVE_API Array; + template class OCTAVE_API octave_sort; INSTANTIATE_ARRAY (std::string, OCTAVE_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array-voidp.cc --- 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; +extern template class OCTAVE_API Array; + NO_INSTANTIATE_ARRAY_SORT (void *); INSTANTIATE_ARRAY (void *, OCTAVE_API); diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array.cc --- 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 +typename Array::ArrayRep * +Array::nil_rep (void) +{ + static ArrayRep nr; + return &nr; +} + +template Array::Array (const Array& a, const dim_vector& dv) : dimensions (dv), rep (a.rep), slice_data (a.slice_data), slice_len (a.slice_len) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Array.h --- 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::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::ArrayRep nr; - return &nr; - } + static typename Array::ArrayRep *nil_rep (void); protected: diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/DiagArray2.cc --- 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 +T& +DiagArray2::elem (octave_idx_type r, octave_idx_type c) +{ + static T zero (0); + return (r == c) ? Array::elem (r) : zero; +} + +template +T& +DiagArray2::checkelem (octave_idx_type r, octave_idx_type c) +{ + static T zero (0); + return check_idx (r, c) ? elem (r, c) : zero; +} + +template void DiagArray2::resize (octave_idx_type r, octave_idx_type c, const T& rfv) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/DiagArray2.h --- 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::elem (r) : T (0); } - T& elem (octave_idx_type r, octave_idx_type c) - { - static T zero (0); - return (r == c) ? Array::elem (r) : zero; - } + T& elem (octave_idx_type r, octave_idx_type c); T dgelem (octave_idx_type i) const { return Array::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) { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Sparse.cc --- 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 +typename Sparse::SparseRep * +Sparse::nil_rep (void) +{ + static typename Sparse::SparseRep nr; + return &nr; +} + +template Sparse::Sparse (const PermMatrix& a) : rep (new typename Sparse::SparseRep (a.rows (), a.cols (), a.rows ())), dimensions (dim_vector (a.rows (), a.cols ())) diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/Sparse.h --- 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::SparseRep *nil_rep (void) const - { - static typename Sparse::SparseRep nr; - return &nr; - } + static typename Sparse::SparseRep *nil_rep (void); public: diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/dim-vector.cc --- 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 diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/dim-vector.h --- 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: diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/idx-vector.cc --- 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 idx_vector::idx_base_rep::as_array (void) { diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/array/idx-vector.h --- 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. diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/util/oct-inttypes.cc --- 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 +template +T +octave_int_base::convert_real (const S& value) +{ + // Compute proper thresholds. + static const S thmin = compute_threshold (static_cast (min_val ()), + min_val ()); + static const S thmax = compute_threshold (static_cast (max_val ()), + max_val ()); + if (xisnan (value)) + { + return static_cast (0); + } + else if (value < thmin) + { + return min_val (); + } + else if (value > thmax) + { + return max_val (); + } + else + { + S rvalue = xround (value); + return static_cast (rvalue); + } +} + +#define INSTANTIATE_CONVERT_REAL_1(T, S) \ + template \ + OCTAVE_API \ + T \ + octave_int_base::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 diff -r 8fc45dd1cac6 -r f3f8e1d3e399 liboctave/util/oct-inttypes.h --- 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 static T - convert_real (const S& value) - { - // Compute proper thresholds. - static const S thmin = compute_threshold (static_cast (min_val ()), - min_val ()); - static const S thmax = compute_threshold (static_cast (max_val ()), - max_val ()); - if (xisnan (value)) - { - return static_cast (0); - } - else if (value < thmin) - { - return min_val (); - } - else if (value > thmax) - { - return max_val (); - } - else - { - S rvalue = xround (value); - return static_cast (rvalue); - } - } + convert_real (const S& value); }; // Saturated (homogeneous) integer arithmetics. The signed and unsigned