changeset 22139:f8212eb6da00

Array: add constructor from std sequence containers (patch 9047) * liboctave/array/Array.h: declare and define new template constructor that supports any standard library sequence container. Heavily based on the reshape constructor code in Array.cc * liboctave/array/Array.cc: just a comment to the source. * libinterp/octave-value/ovl.h: simplify code by making use of the new Array constructor for initializer_list.
author Carnë Draug <carandraug@octave.org>
date Mon, 11 Jul 2016 15:13:27 +0100
parents 3459c25b679a
children 18eae417ffec
files libinterp/octave-value/ovl.h liboctave/array/Array.cc liboctave/array/Array.h
diffstat 3 files changed, 33 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ovl.h	Mon Jul 18 09:08:59 2016 -0700
+++ b/libinterp/octave-value/ovl.h	Mon Jul 11 15:13:27 2016 +0100
@@ -56,14 +56,8 @@
 
   template<template <typename...> class OV_Container>
   octave_value_list (const OV_Container<octave_value>& args)
-    : data (dim_vector (1, args.size ())), names ()
-  {
-    octave_idx_type i = 0;
-    for (const octave_value& x : args)
-      data(i++) = x;
-  }
+    : data (args, dim_vector (1, args.size ())), names () { }
 
-  // Shold probably be handled as a specialization of the Container template.
   octave_value_list (const Array<octave_value>& d)
     : data (d.as_row ()), names () { }
 
--- a/liboctave/array/Array.cc	Mon Jul 18 09:08:59 2016 -0700
+++ b/liboctave/array/Array.cc	Mon Jul 11 15:13:27 2016 +0100
@@ -53,6 +53,8 @@
   return &nr;
 }
 
+// This is similar to the template for containers but specialized for Array.
+// Note we can't specialize a member without also specializing the class.
 template <typename T>
 Array<T>::Array (const Array<T>& a, const dim_vector& dv)
   : dimensions (dv), rep (a.rep),
--- a/liboctave/array/Array.h	Mon Jul 18 09:08:59 2016 -0700
+++ b/liboctave/array/Array.h	Mon Jul 11 15:13:27 2016 +0100
@@ -36,6 +36,7 @@
 
 #include "dim-vector.h"
 #include "idx-vector.h"
+#include "lo-error.h"
 #include "lo-traits.h"
 #include "lo-utils.h"
 #include "oct-sort.h"
@@ -193,6 +194,10 @@
   //! Reshape constructor.
   Array (const Array<T>& a, const dim_vector& dv);
 
+  //! Constructor from standard library sequence containers.
+  template<template <typename...> class Container>
+  Array (const Container<T>& a, const dim_vector& dv);
+
   //! Type conversion case.
   template <typename U>
   Array (const Array<U>& a)
@@ -751,6 +756,31 @@
   static void instantiation_guard ();
 };
 
+// We use a variadic template for template template parameter so that
+// we don't have to specify all the template parameters and limit this
+// to Container<T>. http://stackoverflow.com/a/20499809/1609556
+template<typename T>
+template<template <typename...> class Container>
+Array<T>::Array (const Container<T>& a, const dim_vector& dv)
+  : dimensions (dv), rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
+    slice_data (rep->data), slice_len (rep->len)
+{
+  if (dimensions.safe_numel () != octave_idx_type (a.size ()))
+    {
+      std::string new_dims_str = dimensions.str ();
+
+      (*current_liboctave_error_handler)
+        ("reshape: can't reshape %i elements into %s array",
+         a.size (), new_dims_str.c_str ());
+    }
+
+  octave_idx_type i = 0;
+  for (const T& x : a)
+    slice_data[i++] = x;
+
+  dimensions.chop_trailing_singletons ();
+}
+
 //! This is a simple wrapper template that will subclass an Array<T>
 //! type or any later type derived from it and override the default
 //! non-const operator() to not check for the array's uniqueness.  It