diff --git a/libinterp/octave-value/module.mk b/libinterp/octave-value/module.mk
index 62a978eaff..24a1fc6756 100644
--- a/libinterp/octave-value/module.mk
+++ b/libinterp/octave-value/module.mk
@@ -97,9 +97,11 @@ OCTAVE_VALUE_SRC = \
%reldir%/cdef-package.cc \
%reldir%/cdef-property.cc \
%reldir%/cdef-utils.cc \
+ %reldir%/ov-base-diag-inst.cc \
%reldir%/ov-base-int-inst.cc \
%reldir%/ov-base-mat-inst.cc \
%reldir%/ov-base-scalar-inst.cc \
+ %reldir%/ov-base-sparse-inst.cc \
%reldir%/ov-base.cc \
%reldir%/ov-bool-mat.cc \
%reldir%/ov-bool.cc \
diff --git a/libinterp/octave-value/ov-base-diag-inst.cc b/libinterp/octave-value/ov-base-diag-inst.cc
new file mode 100644
index 0000000000..c959154f3a
--- /dev/null
+++ b/libinterp/octave-value/ov-base-diag-inst.cc
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2024 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or .
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING. If not, see
+// .
+//
+////////////////////////////////////////////////////////////////////////
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include "ov-base-diag.cc"
+
+// instantiate template class with types that need to be exported from library
+
+template class OCTINTERP_API octave_base_diag;
+template class OCTINTERP_API octave_base_diag;
+template class OCTINTERP_API octave_base_diag;
+template class OCTINTERP_API octave_base_diag;
+
diff --git a/libinterp/octave-value/ov-base-diag.h b/libinterp/octave-value/ov-base-diag.h
index 6af2753e83..30985202fc 100644
--- a/libinterp/octave-value/ov-base-diag.h
+++ b/libinterp/octave-value/ov-base-diag.h
@@ -43,28 +43,34 @@
// Real matrix values.
template
-class OCTINTERP_API octave_base_diag : public octave_base_value
+class OCTINTERP_TEMPLATE_API octave_base_diag : public octave_base_value
{
public:
+ OCTINTERP_API
octave_base_diag ()
: octave_base_value (), m_matrix (), m_dense_cache () { }
+ OCTINTERP_API
octave_base_diag (const DMT& m)
: octave_base_value (), m_matrix (m), m_dense_cache ()
{ }
+ OCTINTERP_API
octave_base_diag (const octave_base_diag& m)
: octave_base_value (), m_matrix (m.m_matrix), m_dense_cache () { }
- ~octave_base_diag () = default;
+ OCTINTERP_API ~octave_base_diag () = default;
- std::size_t byte_size () const { return m_matrix.byte_size (); }
+ OCTINTERP_API std::size_t byte_size () const
+ { return m_matrix.byte_size (); }
- octave_value squeeze () const { return m_matrix; }
+ OCTINTERP_API octave_value squeeze () const
+ { return m_matrix; }
- octave_value full_value () const { return to_dense (); }
+ OCTINTERP_API octave_value full_value () const
+ { return to_dense (); }
// We don't need to override all three forms of subsref. The using
// declaration will avoid warnings about partially-overloaded virtual
@@ -74,8 +80,9 @@ class OCTINTERP_API octave_base_diag : public octave_base_value
OCTINTERP_API octave_value
subsref (const std::string& type, const std::list& idx);
- octave_value_list subsref (const std::string& type,
- const std::list& idx, int)
+ OCTINTERP_API octave_value_list
+ subsref (const std::string& type, const std::list& idx,
+ int)
{ return subsref (type, idx); }
OCTINTERP_API octave_value
@@ -85,14 +92,17 @@ class OCTINTERP_API octave_base_diag : public octave_base_value
subsasgn (const std::string& type, const std::list& idx,
const octave_value& rhs);
- dim_vector dims () const { return m_matrix.dims (); }
+ OCTINTERP_API dim_vector dims () const
+ { return m_matrix.dims (); }
- octave_idx_type nnz () const { return diag ().nnz (); }
+ OCTINTERP_API octave_idx_type nnz () const
+ { return diag ().nnz (); }
- octave_value reshape (const dim_vector& new_dims) const
+ OCTINTERP_API octave_value reshape (const dim_vector& new_dims) const
{ return to_dense ().reshape (new_dims); }
- octave_value permute (const Array& vec, bool inv = false) const
+ OCTINTERP_API octave_value
+ permute (const Array& vec, bool inv = false) const
{
if (vec.numel () == 2
&& ((vec.xelem (0) == 1 && vec.xelem (1) == 0)
@@ -105,11 +115,15 @@ class OCTINTERP_API octave_base_diag : public octave_base_value
OCTINTERP_API octave_value
resize (const dim_vector& dv, bool fill = false) const;
- octave_value all (int dim = 0) const { return MT (m_matrix).all (dim); }
- octave_value any (int dim = 0) const { return MT (m_matrix).any (dim); }
+ OCTINTERP_API octave_value all (int dim = 0) const
+ { return MT (m_matrix).all (dim); }
+
+ OCTINTERP_API octave_value any (int dim = 0) const
+ { return MT (m_matrix).any (dim); }
- MatrixType matrix_type () const { return MatrixType::Diagonal; }
- MatrixType matrix_type (const MatrixType&) const
+ OCTINTERP_API MatrixType matrix_type () const
+ { return MatrixType::Diagonal; }
+ OCTINTERP_API MatrixType matrix_type (const MatrixType&) const
{ return matrix_type (); }
// We don't need to override both forms of the diag method. The using
@@ -119,38 +133,42 @@ class OCTINTERP_API octave_base_diag : public octave_base_value
OCTINTERP_API octave_value diag (octave_idx_type k = 0) const;
- octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+ OCTINTERP_API octave_value
+ sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
{ return to_dense ().sort (dim, mode); }
- octave_value sort (Array& sidx, octave_idx_type dim = 0,
- sortmode mode = ASCENDING) const
+ OCTINTERP_API octave_value
+ sort (Array& sidx, octave_idx_type dim = 0,
+ sortmode mode = ASCENDING) const
{ return to_dense ().sort (sidx, dim, mode); }
- sortmode issorted (sortmode mode = UNSORTED) const
+ OCTINTERP_API sortmode issorted (sortmode mode = UNSORTED) const
{ return to_dense ().issorted (mode); }
- Array sort_rows_idx (sortmode mode = ASCENDING) const
+ OCTINTERP_API Array
+ sort_rows_idx (sortmode mode = ASCENDING) const
{ return to_dense ().sort_rows_idx (mode); }
- sortmode is_sorted_rows (sortmode mode = UNSORTED) const
+ OCTINTERP_API sortmode is_sorted_rows (sortmode mode = UNSORTED) const
{ return to_dense ().is_sorted_rows (mode); }
- bool is_matrix_type () const { return true; }
+ OCTINTERP_API bool is_matrix_type () const { return true; }
- bool isnumeric () const { return true; }
+ OCTINTERP_API bool isnumeric () const { return true; }
- bool is_defined () const { return true; }
+ OCTINTERP_API bool is_defined () const { return true; }
- bool is_constant () const { return true; }
+ OCTINTERP_API bool is_constant () const { return true; }
OCTINTERP_API bool is_true () const;
- bool is_diag_matrix () const { return true; }
+ OCTINTERP_API bool is_diag_matrix () const { return true; }
OCTINTERP_API double double_value (bool = false) const;
OCTINTERP_API float float_value (bool = false) const;
- double scalar_value (bool frc_str_conv = false) const
+ OCTINTERP_API double
+ scalar_value (bool frc_str_conv = false) const
{ return double_value (frc_str_conv); }
OCTINTERP_API octave::idx_vector
@@ -187,29 +205,29 @@ class OCTINTERP_API octave_base_diag : public octave_base_value
OCTINTERP_API SparseComplexMatrix
sparse_complex_matrix_value (bool = false) const;
- int8NDArray
- int8_array_value () const { return to_dense ().int8_array_value (); }
+ OCTINTERP_API int8NDArray int8_array_value () const
+ { return to_dense ().int8_array_value (); }
- int16NDArray
- int16_array_value () const { return to_dense ().int16_array_value (); }
+ OCTINTERP_API int16NDArray int16_array_value () const
+ { return to_dense ().int16_array_value (); }
- int32NDArray
- int32_array_value () const { return to_dense ().int32_array_value (); }
+ OCTINTERP_API int32NDArray int32_array_value () const
+ { return to_dense ().int32_array_value (); }
- int64NDArray
- int64_array_value () const { return to_dense ().int64_array_value (); }
+ OCTINTERP_API int64NDArray int64_array_value () const
+ { return to_dense ().int64_array_value (); }
- uint8NDArray
- uint8_array_value () const { return to_dense ().uint8_array_value (); }
+ OCTINTERP_API uint8NDArray uint8_array_value () const
+ { return to_dense ().uint8_array_value (); }
- uint16NDArray
- uint16_array_value () const { return to_dense ().uint16_array_value (); }
+ OCTINTERP_API uint16NDArray uint16_array_value () const
+ { return to_dense ().uint16_array_value (); }
- uint32NDArray
- uint32_array_value () const { return to_dense ().uint32_array_value (); }
+ OCTINTERP_API uint32NDArray uint32_array_value () const
+ { return to_dense ().uint32_array_value (); }
- uint64NDArray
- uint64_array_value () const { return to_dense ().uint64_array_value (); }
+ OCTINTERP_API uint64NDArray uint64_array_value () const
+ { return to_dense ().uint64_array_value (); }
OCTINTERP_API octave_value
convert_to_str_internal (bool pad, bool force, char type) const;
diff --git a/libinterp/octave-value/ov-base-sparse-inst.cc b/libinterp/octave-value/ov-base-sparse-inst.cc
new file mode 100644
index 0000000000..026c4df231
--- /dev/null
+++ b/libinterp/octave-value/ov-base-sparse-inst.cc
@@ -0,0 +1,36 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2024 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or .
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING. If not, see
+// .
+//
+////////////////////////////////////////////////////////////////////////
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include "ov-base-sparse.cc"
+
+// instantiate template class with types that need to be exported from library
+
+template class OCTINTERP_API octave_base_sparse;
+template class OCTINTERP_API octave_base_sparse;
+template class OCTINTERP_API octave_base_sparse;
diff --git a/libinterp/octave-value/ov-base-sparse.cc b/libinterp/octave-value/ov-base-sparse.cc
index 9e32923928..f943fb0eaf 100644
--- a/libinterp/octave-value/ov-base-sparse.cc
+++ b/libinterp/octave-value/ov-base-sparse.cc
@@ -38,6 +38,7 @@
#include "pr-output.h"
#include "byte-swap.h"
+#include "errwarn.h"
#include "ls-oct-text.h"
#include "ls-utils.h"
#include "ls-hdf5.h"
diff --git a/libinterp/octave-value/ov-base-sparse.h b/libinterp/octave-value/ov-base-sparse.h
index 1bb5272912..4395897cd4 100644
--- a/libinterp/octave-value/ov-base-sparse.h
+++ b/libinterp/octave-value/ov-base-sparse.h
@@ -46,14 +46,16 @@
class octave_sparse_bool_matrix;
template
-class OCTINTERP_API octave_base_sparse : public octave_base_value
+class OCTINTERP_TEMPLATE_API octave_base_sparse : public octave_base_value
{
public:
+ OCTINTERP_OVERRIDABLE_FUNC_API
octave_base_sparse ()
: octave_base_value (), matrix (), typ (MatrixType ())
{ }
+ OCTINTERP_OVERRIDABLE_FUNC_API
octave_base_sparse (const T& a)
: octave_base_value (), matrix (a), typ (MatrixType ())
{
@@ -61,6 +63,7 @@ class OCTINTERP_API octave_base_sparse : public octave_base_value
matrix.resize (dim_vector (0, 0));
}
+ OCTINTERP_OVERRIDABLE_FUNC_API
octave_base_sparse (const T& a, const MatrixType& t)
: octave_base_value (), matrix (a), typ (t)
{
@@ -68,22 +71,29 @@ class OCTINTERP_API octave_base_sparse : public octave_base_value
matrix.resize (dim_vector (0, 0));
}
+ OCTINTERP_OVERRIDABLE_FUNC_API
octave_base_sparse (const octave_base_sparse& a)
: octave_base_value (), matrix (a.matrix), typ (a.typ) { }
- ~octave_base_sparse () = default;
+ OCTINTERP_OVERRIDABLE_FUNC_API ~octave_base_sparse () = default;
- octave_idx_type numel () const { return dims ().safe_numel (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_idx_type numel () const
+ { return dims ().safe_numel (); }
- octave_idx_type nnz () const { return matrix.nnz (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_idx_type nnz () const
+ { return matrix.nnz (); }
- octave_idx_type nzmax () const { return matrix.nzmax (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_idx_type nzmax () const
+ { return matrix.nzmax (); }
- std::size_t byte_size () const { return matrix.byte_size (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API std::size_t byte_size () const
+ { return matrix.byte_size (); }
- octave_value squeeze () const { return matrix.squeeze (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value squeeze () const
+ { return matrix.squeeze (); }
- octave_value full_value () const { return matrix.matrix_value (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value full_value () const
+ { return matrix.matrix_value (); }
// We don't need to override all three forms of subsref. The using
// declaration will avoid warnings about partially-overloaded virtual
@@ -93,8 +103,9 @@ class OCTINTERP_API octave_base_sparse : public octave_base_value
OCTINTERP_API octave_value
subsref (const std::string& type, const std::list& idx);
- octave_value_list subsref (const std::string& type,
- const std::list& idx, int)
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value_list
+ subsref (const std::string& type, const std::list& idx,
+ int)
{ return subsref (type, idx); }
OCTINTERP_API octave_value
@@ -161,52 +172,63 @@ class OCTINTERP_API octave_base_sparse : public octave_base_value
OCTINTERP_API void delete_elements (const octave_value_list& idx);
- dim_vector dims () const { return matrix.dims (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API dim_vector dims () const
+ { return matrix.dims (); }
OCTINTERP_API octave_value
do_index_op (const octave_value_list& idx, bool resize_ok = false);
- octave_value reshape (const dim_vector& new_dims) const
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value reshape (const dim_vector& new_dims) const
{ return T (matrix.reshape (new_dims)); }
- octave_value permute (const Array& vec, bool inv = false) const
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value
+ permute (const Array& vec, bool inv = false) const
{ return T (matrix.permute (vec, inv)); }
OCTINTERP_API octave_value resize (const dim_vector& dv, bool = false) const;
- octave_value all (int dim = 0) const { return matrix.all (dim); }
- octave_value any (int dim = 0) const { return matrix.any (dim); }
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value all (int dim = 0) const
+ { return matrix.all (dim); }
+
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value any (int dim = 0) const
+ { return matrix.any (dim); }
// We don't need to override both forms of the diag method. The using
// declaration will avoid warnings about partially-overloaded virtual
// functions.
using octave_base_value::diag;
- octave_value diag (octave_idx_type k = 0) const
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value diag (octave_idx_type k = 0) const
{ return octave_value (matrix.diag (k)); }
- octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value
+ sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
{ return octave_value (matrix.sort (dim, mode)); }
- octave_value sort (Array& sidx, octave_idx_type dim = 0,
- sortmode mode = ASCENDING) const
+
+ OCTINTERP_OVERRIDABLE_FUNC_API octave_value
+ sort (Array& sidx, octave_idx_type dim = 0,
+ sortmode mode = ASCENDING) const
{ return octave_value (matrix.sort (sidx, dim, mode)); }
- sortmode issorted (sortmode mode = UNSORTED) const
+ OCTINTERP_OVERRIDABLE_FUNC_API sortmode
+ issorted (sortmode mode = UNSORTED) const
{ return full_value ().issorted (mode); }
- MatrixType matrix_type () const { return typ; }
- MatrixType matrix_type (const MatrixType& _typ) const
+ OCTINTERP_OVERRIDABLE_FUNC_API MatrixType matrix_type () const
+ { return typ; }
+ OCTINTERP_OVERRIDABLE_FUNC_API MatrixType
+ matrix_type (const MatrixType& _typ) const
{ MatrixType ret = typ; typ = _typ; return ret; }
- bool is_matrix_type () const { return true; }
+ OCTINTERP_OVERRIDABLE_FUNC_API bool is_matrix_type () const { return true; }
- bool isnumeric () const { return true; }
+ OCTINTERP_OVERRIDABLE_FUNC_API bool isnumeric () const { return true; }
- bool issparse () const { return true; }
+ OCTINTERP_OVERRIDABLE_FUNC_API bool issparse () const { return true; }
- bool is_defined () const { return true; }
+ OCTINTERP_OVERRIDABLE_FUNC_API bool is_defined () const { return true; }
- bool is_constant () const { return true; }
+ OCTINTERP_OVERRIDABLE_FUNC_API bool is_constant () const { return true; }
OCTINTERP_API bool is_true () const;
@@ -232,11 +254,14 @@ class OCTINTERP_API octave_base_sparse : public octave_base_value
// These functions exists to support the MEX interface.
// You should not use them anywhere else.
- const void * mex_get_data () const { return matrix.data (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API const void * mex_get_data () const
+ { return matrix.data (); }
- const octave_idx_type * mex_get_ir () const { return matrix.ridx (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API const octave_idx_type * mex_get_ir () const
+ { return matrix.ridx (); }
- const octave_idx_type * mex_get_jc () const { return matrix.cidx (); }
+ OCTINTERP_OVERRIDABLE_FUNC_API const octave_idx_type * mex_get_jc () const
+ { return matrix.cidx (); }
OCTINTERP_API octave_value fast_elem_extract (octave_idx_type n) const;
diff --git a/libinterp/octave-value/ov-bool-sparse.cc b/libinterp/octave-value/ov-bool-sparse.cc
index c1086e100f..0b71db9fe6 100644
--- a/libinterp/octave-value/ov-bool-sparse.cc
+++ b/libinterp/octave-value/ov-bool-sparse.cc
@@ -34,10 +34,6 @@
#include "dim-vector.h"
#include "mxarray.h"
-#include "ov-base.h"
-#include "ov-scalar.h"
-#include "ov-bool.h"
-#include "ov-bool-mat.h"
#include "errwarn.h"
#include "ops.h"
#include "oct-locbuf.h"
@@ -51,8 +47,6 @@
#include "ov-base-sparse.h"
#include "ov-base-sparse.cc"
-template class octave_base_sparse;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_bool_matrix,
"sparse bool matrix", "logical");
diff --git a/libinterp/octave-value/ov-bool-sparse.h b/libinterp/octave-value/ov-bool-sparse.h
index 28a51a2ffa..ed66651e83 100644
--- a/libinterp/octave-value/ov-bool-sparse.h
+++ b/libinterp/octave-value/ov-bool-sparse.h
@@ -47,6 +47,9 @@
class octave_value_list;
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_sparse;
+
class OCTINTERP_API octave_sparse_bool_matrix : public octave_base_sparse
{
public:
diff --git a/libinterp/octave-value/ov-cx-diag.cc b/libinterp/octave-value/ov-cx-diag.cc
index ab692ad849..3f769534bc 100644
--- a/libinterp/octave-value/ov-cx-diag.cc
+++ b/libinterp/octave-value/ov-cx-diag.cc
@@ -32,14 +32,9 @@
#include "ov-cx-diag.h"
#include "ov-flt-cx-diag.h"
#include "ov-re-diag.h"
-#include "ov-base-diag.cc"
#include "ov-complex.h"
-#include "ov-cx-mat.h"
#include "ls-utils.h"
-
-template class octave_base_diag;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_diag_matrix,
"complex diagonal matrix", "double");
diff --git a/libinterp/octave-value/ov-cx-diag.h b/libinterp/octave-value/ov-cx-diag.h
index 6050edf586..00cfba976f 100644
--- a/libinterp/octave-value/ov-cx-diag.h
+++ b/libinterp/octave-value/ov-cx-diag.h
@@ -35,6 +35,9 @@
// Real diagonal matrix values.
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_diag;
+
class octave_complex_diag_matrix
: public octave_base_diag
{
diff --git a/libinterp/octave-value/ov-cx-sparse.cc b/libinterp/octave-value/ov-cx-sparse.cc
index d5a4a06f1f..38b8c99212 100644
--- a/libinterp/octave-value/ov-cx-sparse.cc
+++ b/libinterp/octave-value/ov-cx-sparse.cc
@@ -36,9 +36,6 @@
#include "oct-locbuf.h"
#include "mxarray.h"
-#include "ov-base.h"
-#include "ov-scalar.h"
-#include "ov-complex.h"
#include "errwarn.h"
#include "oct-hdf5.h"
@@ -51,9 +48,6 @@
#include "ov-bool-sparse.h"
-
-template class octave_base_sparse;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_complex_matrix,
"sparse complex matrix", "double");
diff --git a/libinterp/octave-value/ov-cx-sparse.h b/libinterp/octave-value/ov-cx-sparse.h
index 8637eb3fbc..8a215850af 100644
--- a/libinterp/octave-value/ov-cx-sparse.h
+++ b/libinterp/octave-value/ov-cx-sparse.h
@@ -47,6 +47,9 @@
class octave_value_list;
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_sparse;
+
class OCTINTERP_API octave_sparse_complex_matrix : public octave_base_sparse
{
public:
diff --git a/libinterp/octave-value/ov-flt-cx-diag.cc b/libinterp/octave-value/ov-flt-cx-diag.cc
index d152dfc171..16c5846fda 100644
--- a/libinterp/octave-value/ov-flt-cx-diag.cc
+++ b/libinterp/octave-value/ov-flt-cx-diag.cc
@@ -30,15 +30,10 @@
#include "byte-swap.h"
#include "ov-flt-cx-diag.h"
-#include "ov-base-diag.cc"
#include "ov-flt-re-diag.h"
#include "ov-flt-complex.h"
-#include "ov-flt-cx-mat.h"
#include "ls-utils.h"
-
-template class octave_base_diag;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_diag_matrix,
"float complex diagonal matrix", "single");
diff --git a/libinterp/octave-value/ov-flt-cx-diag.h b/libinterp/octave-value/ov-flt-cx-diag.h
index 9cb0c67bf9..6411a2c427 100644
--- a/libinterp/octave-value/ov-flt-cx-diag.h
+++ b/libinterp/octave-value/ov-flt-cx-diag.h
@@ -35,6 +35,9 @@
// Real diagonal matrix values.
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_diag;
+
class OCTINTERP_API octave_float_complex_diag_matrix
: public octave_base_diag
{
diff --git a/libinterp/octave-value/ov-flt-re-diag.cc b/libinterp/octave-value/ov-flt-re-diag.cc
index 9fdb850b61..3480c5c6fc 100644
--- a/libinterp/octave-value/ov-flt-re-diag.cc
+++ b/libinterp/octave-value/ov-flt-re-diag.cc
@@ -30,14 +30,9 @@
#include "byte-swap.h"
#include "ov-flt-re-diag.h"
-#include "ov-base-diag.cc"
#include "ov-float.h"
-#include "ov-flt-re-mat.h"
#include "ls-utils.h"
-
-template class octave_base_diag;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_diag_matrix,
"float diagonal matrix", "single");
diff --git a/libinterp/octave-value/ov-flt-re-diag.h b/libinterp/octave-value/ov-flt-re-diag.h
index 38ecf9b18b..e8ffc65e69 100644
--- a/libinterp/octave-value/ov-flt-re-diag.h
+++ b/libinterp/octave-value/ov-flt-re-diag.h
@@ -35,6 +35,9 @@
// Real diagonal matrix values.
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_diag;
+
class OCTINTERP_API octave_float_diag_matrix
: public octave_base_diag
{
diff --git a/libinterp/octave-value/ov-re-diag.cc b/libinterp/octave-value/ov-re-diag.cc
index e4cab1d104..04cdb1e7ad 100644
--- a/libinterp/octave-value/ov-re-diag.cc
+++ b/libinterp/octave-value/ov-re-diag.cc
@@ -31,14 +31,9 @@
#include "ov-re-diag.h"
#include "ov-flt-re-diag.h"
-#include "ov-base-diag.cc"
#include "ov-scalar.h"
-#include "ov-re-mat.h"
#include "ls-utils.h"
-
-template class octave_base_diag;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_diag_matrix, "diagonal matrix",
"double");
diff --git a/libinterp/octave-value/ov-re-diag.h b/libinterp/octave-value/ov-re-diag.h
index 634b9b59ae..b876054d04 100644
--- a/libinterp/octave-value/ov-re-diag.h
+++ b/libinterp/octave-value/ov-re-diag.h
@@ -35,6 +35,9 @@
// Real diagonal matrix values.
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_diag;
+
class OCTINTERP_API octave_diag_matrix
: public octave_base_diag
{
diff --git a/libinterp/octave-value/ov-re-sparse.cc b/libinterp/octave-value/ov-re-sparse.cc
index 1ba08285e2..9a9f27405a 100644
--- a/libinterp/octave-value/ov-re-sparse.cc
+++ b/libinterp/octave-value/ov-re-sparse.cc
@@ -37,8 +37,6 @@
#include "oct-locbuf.h"
#include "mxarray.h"
-#include "ov-base.h"
-#include "ov-scalar.h"
#include "errwarn.h"
#include "oct-hdf5.h"
@@ -51,9 +49,6 @@
#include "ov-bool-sparse.h"
-
-template class octave_base_sparse;
-
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix",
"double");
diff --git a/libinterp/octave-value/ov-re-sparse.h b/libinterp/octave-value/ov-re-sparse.h
index f6acc62775..eca54a6ba8 100644
--- a/libinterp/octave-value/ov-re-sparse.h
+++ b/libinterp/octave-value/ov-re-sparse.h
@@ -48,6 +48,9 @@
class octave_value_list;
+extern template class OCTINTERP_EXTERN_TEMPLATE_API
+octave_base_sparse;
+
class OCTINTERP_API octave_sparse_matrix : public octave_base_sparse
{
public: