changeset 21574:ae4d7dfea337

maint: merge stable to default.
author John W. Eaton <jwe@octave.org>
date Fri, 01 Apr 2016 12:57:49 -0400
parents feac06371be1 (current diff) f3f8e1d3e399 (diff)
children bc9aa534bc29
files libinterp/corefcn/Cell.cc libinterp/corefcn/Cell.h libinterp/corefcn/oct-map.cc libinterp/corefcn/oct-map.h libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h libinterp/octave-value/ov-base-scalar.cc libinterp/octave-value/ov-base-scalar.h libinterp/octave-value/ov-bool.cc libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-fcn-handle.h libinterp/octave-value/ov-flt-complex.cc libinterp/octave-value/ov-int16.cc libinterp/octave-value/ov-int32.cc libinterp/octave-value/ov-int64.cc libinterp/octave-value/ov-int8.cc libinterp/octave-value/ov-scalar.cc libinterp/octave-value/ov-uint16.cc libinterp/octave-value/ov-uint32.cc libinterp/octave-value/ov-uint64.cc libinterp/octave-value/ov-uint8.cc libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/template-inst/Array-jit.cc libinterp/template-inst/Array-tc.cc liboctave/array/Array-C.cc liboctave/array/Array-b.cc liboctave/array/Array-ch.cc liboctave/array/Array-d.cc liboctave/array/Array-f.cc liboctave/array/Array-fC.cc liboctave/array/Array-i.cc liboctave/array/Array-idx-vec.cc liboctave/array/Array-s.cc liboctave/array/Array-str.cc liboctave/array/Array-voidp.cc liboctave/array/Array.cc liboctave/array/Array.h liboctave/array/DiagArray2.cc liboctave/array/DiagArray2.h liboctave/array/Sparse.cc liboctave/array/Sparse.h liboctave/array/dim-vector.cc liboctave/array/dim-vector.h liboctave/array/idx-vector.cc liboctave/array/idx-vector.h liboctave/util/oct-inttypes.cc liboctave/util/oct-inttypes.h
diffstat 50 files changed, 334 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/Cell.cc	Thu Mar 31 14:12:13 2016 -0700
+++ b/libinterp/corefcn/Cell.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -339,6 +339,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 14:12:13 2016 -0700
+++ b/libinterp/corefcn/Cell.h	Fri Apr 01 12:57:49 2016 -0400
@@ -111,11 +111,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 14:12:13 2016 -0700
+++ b/libinterp/corefcn/oct-map.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/corefcn/oct-map.h	Fri Apr 01 12:57:49 2016 -0400
@@ -53,11 +53,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 14:12:13 2016 -0700
+++ b/libinterp/corefcn/symtab.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -49,6 +49,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;
@@ -151,6 +153,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 14:12:13 2016 -0700
+++ b/libinterp/corefcn/symtab.h	Fri Apr 01 12:57:49 2016 -0400
@@ -49,6 +49,8 @@
 {
 public:
 
+  static octave_value dummy_octave_value;
+
   typedef int scope_id;
   typedef size_t context_id;
 
@@ -262,12 +264,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
           {
@@ -654,6 +654,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
@@ -1310,11 +1312,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,
@@ -1333,8 +1333,6 @@
                       context_id context = xdefault_context,
                       bool force_add = false)
   {
-    static octave_value foobar;
-
     symbol_table *inst = get_instance (scope);
 
     if (inst)
@@ -1346,11 +1344,9 @@
   varref (const std::string& name, scope_id scope = xcurrent_scope,
           context_id context = xdefault_context, bool force_add = false)
   {
-    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
@@ -1369,11 +1365,9 @@
   force_varref (const std::string& name, scope_id scope = xcurrent_scope,
                 context_id context = xdefault_context)
   {
-    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,
@@ -1427,11 +1421,9 @@
   static octave_value&
   top_level_varref (const std::string& name)
   {
-    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
@@ -1454,11 +1446,9 @@
   static octave_value&
   persistent_varref (const std::string& name)
   {
-    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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-base-scalar.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -100,6 +100,14 @@
 }
 
 template <typename ST>
+dim_vector
+octave_base_scalar<ST>::dims (void) const
+{
+  static dim_vector dv (1, 1);
+  return dv;
+}
+
+template <typename 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-base-scalar.h	Fri Apr 01 12:57:49 2016 -0400
@@ -79,7 +79,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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-bool.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -45,6 +45,12 @@
 #include "ls-oct-text.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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-complex.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -50,6 +50,13 @@
 #include "ls-oct-text.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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-fcn-handle.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-fcn-handle.h	Fri Apr 01 12:57:49 2016 -0400
@@ -106,7 +106,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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-flt-complex.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -49,6 +49,12 @@
 #include "ls-oct-text.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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-int16.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-int32.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-int64.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-int8.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-scalar.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -52,6 +52,12 @@
 #include "ls-oct-text.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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-uint16.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-uint32.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-uint64.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov-uint8.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -108,6 +108,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 14:12:13 2016 -0700
+++ b/libinterp/octave-value/ov.h	Fri Apr 01 12:57:49 2016 -0400
@@ -167,9 +167,8 @@
   enum magic_colon { magic_colon_t };
 
   octave_value (void)
+    : rep (nil_rep ())
   {
-    static octave_base_value nil_rep;
-    rep = &nil_rep;
     rep->count++;
   }
 
@@ -1425,6 +1424,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 14:12:13 2016 -0700
+++ b/libinterp/template-inst/Array-jit.cc	Fri Apr 01 12:57:49 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-tc.cc	Thu Mar 31 14:12:13 2016 -0700
+++ b/libinterp/template-inst/Array-tc.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-C.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-b.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -28,10 +28,17 @@
 
 #include "Array.h"
 #include "Array.cc"
+
 #define INLINE_ASCENDING_SORT 1
 #define INLINE_DESCENDING_SORT 1
 #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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-ch.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -28,10 +28,17 @@
 
 #include "Array.h"
 #include "Array.cc"
+
 #define INLINE_ASCENDING_SORT 1
 #define INLINE_DESCENDING_SORT 1
 #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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-d.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -36,6 +36,12 @@
 #define INLINE_DESCENDING_SORT 1
 #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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-f.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -36,6 +36,12 @@
 #define INLINE_DESCENDING_SORT 1
 #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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-fC.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-i.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -35,6 +35,11 @@
 #define INLINE_DESCENDING_SORT 1
 #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 (OCTAVE_HAVE_LONG_LONG_INT)
--- a/liboctave/array/Array-idx-vec.cc	Thu Mar 31 14:12:13 2016 -0700
+++ b/liboctave/array/Array-idx-vec.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-s.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -33,6 +33,12 @@
 #define INLINE_DESCENDING_SORT 1
 #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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-str.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array-voidp.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -45,6 +45,14 @@
 // all the derived classes.
 
 template <typename T>
+typename Array<T>::ArrayRep *
+Array<T>::nil_rep (void)
+{
+  static ArrayRep nr;
+  return &nr;
+}
+
+template <typename 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 14:12:13 2016 -0700
+++ b/liboctave/array/Array.h	Fri Apr 01 12:57:49 2016 -0400
@@ -151,15 +151,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 14:12:13 2016 -0700
+++ b/liboctave/array/DiagArray2.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -89,6 +89,22 @@
 // A two-dimensional array with diagonal elements only.
 
 template <typename 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 <typename 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 <typename T>
 void
 DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c,
                        const T& rfv)
--- a/liboctave/array/DiagArray2.h	Thu Mar 31 14:12:13 2016 -0700
+++ b/liboctave/array/DiagArray2.h	Fri Apr 01 12:57:49 2016 -0400
@@ -116,11 +116,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); }
@@ -142,11 +138,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 14:12:13 2016 -0700
+++ b/liboctave/array/Sparse.cc	Fri Apr 01 12:57:49 2016 -0400
@@ -53,6 +53,14 @@
 #include "PermMatrix.h"
 
 template <typename T>
+typename Sparse<T>::SparseRep *
+Sparse<T>::nil_rep (void)
+{
+  static typename Sparse<T>::SparseRep nr;
+  return &nr;
+}
+
+template <typename 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 14:12:13 2016 -0700
+++ b/liboctave/array/Sparse.h	Fri Apr 01 12:57:49 2016 -0400
@@ -169,11 +169,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 14:12:13 2016 -0700
+++ b/liboctave/array/dim-vector.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/dim-vector.h	Fri Apr 01 12:57:49 2016 -0400
@@ -276,11 +276,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 14:12:13 2016 -0700
+++ b/liboctave/array/idx-vector.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/array/idx-vector.h	Fri Apr 01 12:57:49 2016 -0400
@@ -433,19 +433,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 14:12:13 2016 -0700
+++ b/liboctave/util/oct-inttypes.cc	Fri Apr 01 12:57:49 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 14:12:13 2016 -0700
+++ b/liboctave/util/oct-inttypes.h	Fri Apr 01 12:57:49 2016 -0400
@@ -317,34 +317,11 @@
   }
 
 public:
+
   // Convert a real number (check NaN and non-int).
   template <typename 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