# HG changeset patch
# User Petter Tomner <tomner@kth.se>
# Date 1641772797 -3600
#      Mon Jan 10 00:59:57 2022 +0100
# Node ID da9cdf93d2cf18b5d6938634eee1833437618568
# Parent  19f7b7854cbaa5801a1f0c3a9983ac47dbecac2a
WIP: Make storable value into octave_base_valus' derived classes

diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-base-scalar.cc
--- a/libinterp/octave-value/ov-base-scalar.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-base-scalar.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -38,6 +38,7 @@
 #include "ov-re-mat.h"
 #include "ov-base-scalar.h"
 #include "pr-output.h"
+#include "ov-inline.h"
 
 // We don't want the new or delete operator in the header, since dynamically
 // loaded object files can't have access to the thread_local objects, since
@@ -81,6 +82,14 @@
     octave_base_scalar<ST>::operator delete (obj_pool[i]);
 }
 
+
+template <typename ST>
+octave_value
+octave_base_scalar<ST>::storable_value (void)
+{
+  return octave_value_factory::make_copy (this);
+}
+
 template <typename ST>
 octave_value
 octave_base_scalar<ST>::subsref (const std::string& type,
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-base-scalar.h
--- a/libinterp/octave-value/ov-base-scalar.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-base-scalar.h	Mon Jan 10 00:59:57 2022 +0100
@@ -153,6 +153,8 @@
 
   OCTINTERP_API bool is_true (void) const;
 
+  OCTINTERP_API octave_value storable_value (void);
+
   OCTINTERP_API void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   OCTINTERP_API void
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-base.cc
--- a/libinterp/octave-value/ov-base.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-base.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -2,7 +2,8 @@
 //
 // Copyright (C) 1996-2022 The Octave Project Developers
 //
-// See the file COPYRIGHT.md in the top-level directory of this
+// See the file COPY
+// RIGHT.md in the top-level directory of this
 // distribution or <https://octave.org/copyright/>.
 //
 // This file is part of Octave.
@@ -62,6 +63,7 @@
 #include "utils.h"
 #include "variables.h"
 #include "ov-magic-int.h"
+#include "ov-inline.h"
 
 builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y)
 {
@@ -110,6 +112,13 @@
 }
 
 octave_value
+octave_base_value::storable_value (void)
+{
+  maybe_economize ();
+  return octave_value_factory::make_copy (this);
+}
+
+octave_value
 octave_base_value::squeeze (void) const
 {
   std::string nm = type_name ();
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-base.h
--- a/libinterp/octave-value/ov-base.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-base.h	Mon Jan 10 00:59:57 2022 +0100
@@ -892,6 +892,8 @@
 
   virtual octave_value dump (void) const;
 
+  virtual octave_value storable_value (void);
+
   // Standard mappers.  Register new ones here.
   enum unary_mapper_t
   {
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-inline.h
--- a/libinterp/octave-value/ov-inline.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-inline.h	Mon Jan 10 00:59:57 2022 +0100
@@ -35,6 +35,7 @@
 #include "ov-complex.h"
 #include "ov-flt-complex.h"
 #include "ov-bool.h"
+#include "ov-base.h"
 
 
 // class to construct octave_value:s inline
@@ -116,6 +117,10 @@
     return octave_value (0, new octave_bool (b));
   }
 
+  static octave_value make_copy (octave_base_value *rep)
+  {
+    return octave_value (0, 0, rep);
+  }
 
   private:
   ~octave_value_factory () = delete;
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-magic-int.cc
--- a/libinterp/octave-value/ov-magic-int.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-magic-int.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -85,6 +85,13 @@
 }
 
 template <typename T>
+octave_value
+octave_base_magic_int<T>::storable_value(void)
+{
+  return octave_value (double_value ());
+}
+
+template <typename T>
 octave::idx_vector
 octave_base_magic_int<T>::index_vector (bool require_integers) const
 {
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-magic-int.h
--- a/libinterp/octave-value/ov-magic-int.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-magic-int.h	Mon Jan 10 00:59:57 2022 +0100
@@ -156,6 +156,10 @@
   float float_scalar_value (bool = false) const
   { return float_value (); }
 
+  octave_value make_storable_value (void);
+
+  octave_value storable_value (void);
+
   Matrix matrix_value (bool = false) const
   { return Matrix (1, 1, double_value ()); }
 
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-null-mat.cc
--- a/libinterp/octave-value/ov-null-mat.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-null-mat.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -69,6 +69,24 @@
   return a.empty_clone ();
 }
 
+octave_value
+octave_null_str::storable_value (void)
+{
+  return octave_value (empty_clone ());
+}
+
+octave_value
+octave_null_matrix::storable_value (void)
+{
+  return octave_value (empty_clone ());
+}
+
+octave_value
+octave_null_sq_str::storable_value (void)
+{
+  return octave_value (empty_clone ());
+}
+
 octave_base_value::type_conv_info
 octave_null_str::numeric_conversion_function (void) const
 {
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-null-mat.h
--- a/libinterp/octave-value/ov-null-mat.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-null-mat.h	Mon Jan 10 00:59:57 2022 +0100
@@ -55,6 +55,8 @@
 
   type_conv_info numeric_conversion_function (void) const;
 
+  octave_value storable_value (void);
+
 private:
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA_CONST(virtual,
@@ -79,6 +81,8 @@
 
   type_conv_info numeric_conversion_function (void) const;
 
+  octave_value storable_value (void);
+
 private:
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA_CONST(virtual,
@@ -103,6 +107,8 @@
 
   type_conv_info numeric_conversion_function (void) const;
 
+  octave_value storable_value (void);
+
 private:
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA_CONST(
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-range.cc
--- a/libinterp/octave-value/ov-range.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-range.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -193,6 +193,16 @@
 }
 
 template <typename T>
+octave_value
+ov_range<T>::storable_value (void)
+{
+  if (!is_storable ())
+    error ("range with infinite number of elements cannot be stored");
+
+  return octave_value (this, true);
+}
+
+template <typename T>
 octave_base_value *
 ov_range<T>::try_narrowing_conversion (void)
 {
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov-range.h
--- a/libinterp/octave-value/ov-range.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov-range.h	Mon Jan 10 00:59:57 2022 +0100
@@ -148,6 +148,8 @@
     return raw_array_value ().reshape (new_dims);
   }
 
+  octave_value storable_value (void);
+
   octave_value permute (const Array<int>& vec, bool inv = false) const
   {
     return raw_array_value ().permute (vec, inv);
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov.cc
--- a/libinterp/octave-value/ov.cc	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov.cc	Mon Jan 10 00:59:57 2022 +0100
@@ -2267,6 +2267,8 @@
 octave_value
 octave_value::storable_value (void) const
 {
+  return m_rep->storable_value ();
+  /*
   octave_value retval = *this;
   if (isnull ())
     retval = octave_value (m_rep->empty_clone ());
@@ -2277,7 +2279,7 @@
   else
     retval.maybe_economize ();
 
-  return retval;
+  return retval;*/
 }
 
 void
diff -r 19f7b7854cba -r da9cdf93d2cf libinterp/octave-value/ov.h
--- a/libinterp/octave-value/ov.h	Sun Jan 09 22:58:31 2022 +0100
+++ b/libinterp/octave-value/ov.h	Mon Jan 10 00:59:57 2022 +0100
@@ -291,6 +291,11 @@
 private:
   // For use by inline octave_value "factory" octave_value_inline
   octave_value (int /* dummy */, octave_base_value *rep) : m_rep (rep) {}
+  // Also increase the counter, for a "copy"
+  octave_value(int /* dummy */, int, octave_base_value *rep) : m_rep (rep)
+  {
+    m_rep->count++;
+  }
 
   friend class octave_value_factory;
 
