https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Add metal::array (1d,2d,3d).
* mln/metal/all.hh: Update.
* mln/metal/array.hh: Generic.
* mln/metal/array1d.hh: Container 1d.
* mln/metal/array2d.hh: Container 2d.
* mln/metal/array3d.hh: Container 3d.
all.hh | 5
array.hh | 117 +++++++++++++++++++++++
array1d.hh | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
array2d.hh | 309 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
array3d.hh | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 1039 insertions(+)
Index: mln/metal/all.hh
--- mln/metal/all.hh (revision 2168)
+++ mln/metal/all.hh (working copy)
@@ -79,6 +79,11 @@
# include <mln/metal/math/all.hh>
+# include <mln/metal/array.hh>
+# include <mln/metal/array1d.hh>
+# include <mln/metal/array2d.hh>
+# include <mln/metal/array3d.hh>
+
// FIXME: Remove the following includes below!
# include <mln/metal/same_coord.hh>
# include <mln/metal/same_point.hh>
Index: mln/metal/array.hh
--- mln/metal/array.hh (revision 0)
+++ mln/metal/array.hh (revision 0)
@@ -0,0 +1,117 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_METAL_ARRAY_HH
+# define MLN_METAL_ARRAY_HH
+
+# include <mln/metal/array1d.hh>
+# include <mln/metal/array2d.hh>
+# include <mln/metal/array3d.hh>
+
+namespace mln
+{
+
+ namespace metal
+ {
+
+ // a1
+
+ template<unsigned i, class T, unsigned n> inline
+ T get_at(const array1d<T, n>& arr)
+ {
+ return arr.template get_at_<i>();
+ }
+
+ template<unsigned i, class T, unsigned n> inline
+ T get(const array1d<T, n>& arr)
+ {
+ return arr.template get_<i>();
+ }
+
+ // a2
+
+ template<unsigned row, unsigned col, class T,
+ unsigned r, unsigned c> inline
+ T get_at(const array2d<T, r, c>& arr)
+ {
+ return arr.template get_at_<row, col>();
+ }
+
+ template<unsigned row, unsigned col, class T,
+ unsigned r, unsigned c> inline
+ T get(const array2d<T, r, c>& arr)
+ {
+ return arr.template get_<row, col>();
+ }
+
+ // a3
+
+ template<unsigned sli, unsigned row, unsigned col,
+ class T, unsigned s, unsigned r, unsigned c> inline
+ T get_at(const array3d<T, s, r, c>& arr)
+ {
+ return arr.template get_at_<sli, row, col>();
+ }
+
+ template<unsigned sli, unsigned row, unsigned col,
+ class T, unsigned s, unsigned r, unsigned c> inline
+ T get_(const array3d<T, s, r, c>& arr)
+ {
+ return arr.template get_<sli, row, col>();
+ }
+
+ // print
+
+ template<typename T, unsigned n>
+ std::ostream& operator<<(std::ostream& ostr, const array1d<T,
n>& rhs)
+ {
+ for (unsigned i = 0; i < n; ++i)
+ ostr << rhs[i] << " ";
+ ostr << std::endl;
+
+ return ostr;
+ }
+
+ template<typename T, unsigned r, unsigned c>
+ std::ostream& operator<<(std::ostream& ostr, const array2d<T, r,
c>& rhs)
+ {
+ for (unsigned i = 0; i < r; ++i)
+ {
+ for (unsigned j = 0; j < c; ++j)
+ ostr << rhs(i,j) << '\t';
+ ostr << '\n';
+ }
+ ostr << std::endl;
+
+ return ostr;
+ }
+
+ }
+
+}
+
+#endif /* MLN_METAL_ARRAY_HH */
Index: mln/metal/array1d.hh
--- mln/metal/array1d.hh (revision 0)
+++ mln/metal/array1d.hh (revision 0)
@@ -0,0 +1,298 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_METAL_ARRAY1D_HH
+# define MLN_METAL_ARRAY1D_HH
+
+# include <mln/core/concept/object.hh>
+
+# include <mln/trait/all.hh>
+# include <mln/trait/value_.hh>
+
+# include <mln/value/ops.hh>
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace metal {
+ template <typename T, unsigned Size> struct array1d;
+ }
+
+ namespace trait
+ {
+
+ template <typename T, unsigned Size>
+ struct value_< mln::metal::array1d<T,Size> >
+ {
+ typedef trait::value::nature::vectorial nature;
+ typedef trait::value::kind::data kind;
+
+ enum {
+ nbits = Size * mln_nbits(T),
+ card = Size * mln_card(T)
+ };
+ typedef mln_value_quant_from_(card) quant;
+
+ typedef metal::array1d<mln_sum(T),Size> sum;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ template <typename T, unsigned Size>
+ struct array1d : public Object< array1d<T,Size> >
+ {
+
+ //
+ // Constructors
+ //
+
+ array1d();
+ array1d(T* ptr);
+
+ // Copy
+
+ array1d(const array1d<T, Size>& rhs);
+ array1d<T, Size>& operator=(const array1d<T, Size>& rhs);
+
+ // Operators
+
+ template <class U>
+ array1d<T, Size> operator*(U w);
+
+ template <class U>
+ array1d<mln_trait_op_div(T,U), Size>
+ operator/(U w);
+
+ template <typename U>
+ array1d<mln_trait_op_plus(T,U), Size>
+ operator+(const array1d<U, Size>& rhs) const;
+ array1d<T, Size>& operator+=(const array1d<T, Size>& rhs);
+
+ template <typename U>
+ array1d<mln_trait_op_minus(T,U), Size>
+ operator-(const array1d<U, Size>& rhs) const;
+ array1d<T, Size>&
+ operator-=(const array1d<T, Size>& rhs);
+
+
+ // dynamic accessors:
+
+ T operator[](unsigned i) const {
+ mln_precondition(i < Size);
+ return buffer_[i];
+ }
+ T& operator[](unsigned i) {
+ mln_precondition(i < Size);
+ return buffer_[i];
+ }
+
+ // static accessor
+
+ template<unsigned i>
+ T get() const {
+ return buffer_[i];
+ }
+ template<unsigned i>
+ T& get() {
+ return buffer_[i];
+ }
+
+ enum { length = Size };
+ protected:
+
+ T buffer_[Size];
+ };
+
+ }
+
+ namespace trait
+ {
+
+ // For unary traits.
+
+ template < template <class> class Name,
+ unsigned n, typename T >
+ struct set_precise_unary_< Name, metal::array1d<T, n> >
+ {
+ typedef mln_trait_unary(Name, T) V;
+ typedef metal::array1d<V, n> ret;
+ };
+
+ // For binary traits.
+
+ template < template <class, class> class Name,
+ unsigned n, typename T,
+ typename U >
+ struct set_precise_binary_< Name,
+ metal::array1d<T, n>, metal::array1d<U, n> >
+ {
+ typedef mln_trait_binary(Name, T, U) V;
+ typedef metal::array1d<V, n> ret;
+ };
+
+ template < unsigned n, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ metal::array1d<T, n>, metal::array1d<U, n> >
+ {
+ typedef mln_sum_x(T,U) ret;
+ };
+
+ template < template <class, class> class Name,
+ unsigned n, typename T,
+ typename S >
+ struct set_precise_binary_< Name,
+ metal::array1d<T, n>, mln::value::scalar_<S> >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array1d<V, n> ret;
+ };
+
+ template < template<class, class> class Name,
+ unsigned n, typename T,
+ typename S >
+ struct set_binary_< Name,
+ mln::Object, metal::array1d<T, n>,
+ mln::value::Scalar, S >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array1d<T, n> ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ //
+ // Constructors
+ //
+
+ template <typename T, unsigned Size>
+ array1d<T,Size>::array1d()
+ {
+ }
+
+ template <typename T, unsigned Size>
+ array1d<T,Size>::array1d(T* ptr)
+ {
+ for (unsigned i = 0; i < Size; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ template <typename T, unsigned Size>
+ array1d<T,Size>::array1d(const array1d<T, Size>& rhs)
+ {
+ for (unsigned i = 0; i < Size; ++i)
+ buffer_[i] = rhs[i];
+ }
+ template <typename T, unsigned Size>
+ array1d<T, Size>&
+ array1d<T,Size>::operator=(const array1d<T, Size>& rhs)
+ {
+ for (unsigned i = 0; i < Size; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+ // Operators
+
+ template <typename T, unsigned Size>
+ template <class U>
+ array1d<T, Size>
+ array1d<T,Size>::operator*(U w)
+ {
+ //fixme mln_trait_op_mult<int,U>
+ array1d<T, Size> tmp;
+ for (unsigned i = 0; i < Size; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <typename T, unsigned Size>
+ template <class U>
+ array1d<mln_trait_op_div(T,U), Size>
+ array1d<T,Size>::operator/(U w)
+ {
+ array1d<T, Size> tmp;
+ for (unsigned i = 0; i < Size; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ template <typename T, unsigned Size>
+ template <typename U>
+ array1d<mln_trait_op_plus(T,U), Size>
+ array1d<T,Size>::operator+(const array1d<U, Size>& rhs) const
+ {
+ array1d<T, Size> tmp;
+ for (unsigned i = 0; i < Size; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned Size>
+ array1d<T, Size>&
+ array1d<T,Size>::operator+=(const array1d<T, Size>& rhs)
+ {
+ for (unsigned i = 0; i < Size; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ template <typename T, unsigned Size>
+ template <typename U>
+ array1d<mln_trait_op_minus(T,U), Size>
+ array1d<T,Size>::operator-(const array1d<U, Size>& rhs) const
+ {
+ array1d<T, Size> tmp;
+ for (unsigned i = 0; i < Size; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned Size>
+ array1d<T, Size>&
+ array1d<T,Size>::operator-=(const array1d<T, Size>& rhs)
+ {
+ for (unsigned i = 0; i < Size; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+ } // end of namespace metal
+
+} // end of namespace mln
+
+#endif /* MLN_METAL_ARRAY1D_HH */
+
Index: mln/metal/array2d.hh
--- mln/metal/array2d.hh (revision 0)
+++ mln/metal/array2d.hh (revision 0)
@@ -0,0 +1,309 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_METAL_ARRAY2D_HH
+# define MLN_METAL_ARRAY2D_HH
+
+# include <mln/core/concept/object.hh>
+
+# include <mln/trait/all.hh>
+# include <mln/trait/value_.hh>
+
+# include <mln/value/ops.hh>
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace metal {
+ template <typename T, unsigned r, unsigned c> struct array2d;
+ }
+
+ namespace trait
+ {
+
+ template <typename T, unsigned r, unsigned c>
+ struct value_< mln::metal::array2d<T, r, c> >
+ {
+ typedef trait::value::nature::vectorial nature;
+ typedef trait::value::kind::data kind;
+
+ enum {
+ nbits = r * c * mln_nbits(T),
+ card = r * c * mln_card(T)
+ };
+ typedef mln_value_quant_from_(card) quant;
+
+ typedef metal::array2d<mln_sum(T),r, c> sum;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ template <typename T, unsigned r, unsigned c>
+ struct array2d : public Object< array2d<T, r, c> >
+ {
+
+ //
+ // Constructors
+ //
+
+ array2d();
+ array2d(T* ptr);
+
+ // Copy
+
+ array2d(const array2d<T, r, c>& rhs);
+
+ array2d<T, r, c>& operator=(const array2d<T, r, c>& rhs);
+
+ // Operators
+
+ template <class U>
+ array2d<T, r, c> operator*(U w);
+
+ template <class U>
+ array2d<mln_trait_op_div(T,U), r, c>
+ operator/(U w);
+
+ template <typename U>
+ array2d<mln_trait_op_plus(T,U), r, c>
+ operator+(const array2d<U, r, c>& rhs) const;
+ array2d<T, r, c>& operator+=(const array2d<T, r, c>& rhs);
+
+ template <typename U>
+ array2d<mln_trait_op_minus(T,U), r, c>
+ operator-(const array2d<U, r, c>& rhs)
const;
+ array2d<T, r, c>&
+ operator-=(const array2d<T, r, c>& rhs);
+
+ // dynamic accessors:
+
+ T operator()(unsigned row, unsigned col) const {
+ mln_precondition(row < r * c);
+ return buffer_[col * r + row];
+ }
+ T& operator()(unsigned row, unsigned col) {
+ mln_precondition(row < r * c);
+ return buffer_[col * r + row];
+ }
+
+ // static accessor
+
+ template<unsigned row, unsigned col>
+ T get() const {
+ return buffer_[col * r + row];
+ }
+ template<unsigned row, unsigned col>
+ T& get() {
+ return buffer_[col * r + row];
+ }
+
+ template<unsigned row, unsigned col>
+ T get_at() const {
+ mln_precondition(col * r + row < r *c);
+ return buffer_[col * r + row];
+ }
+ template<unsigned row, unsigned col>
+ T& get_at() {
+ mln_precondition(col * r + row < r *c);
+ return buffer_[col * r + row];
+ }
+
+ enum { length = r * c };
+ protected:
+
+ T buffer_[r * c];
+ };
+
+ }
+
+ namespace trait
+ {
+
+ // For unary traits.
+
+ template < template <class> class Name,
+ unsigned r, unsigned c, typename T >
+ struct set_precise_unary_< Name, metal::array2d<T, r, c> >
+ {
+ typedef mln_trait_unary(Name, T) V;
+ typedef metal::array2d<V, r, c> ret;
+ };
+
+ // For binary traits.
+
+ template < template <class, class> class Name,
+ unsigned r, unsigned c, typename T,
+ typename U >
+ struct set_precise_binary_< Name,
+ metal::array2d<T, r, c>, metal::array2d<U, r, c> >
+ {
+ typedef mln_trait_binary(Name, T, U) V;
+ typedef metal::array2d<V, r, c> ret;
+ };
+
+ template < unsigned r, unsigned c, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ metal::array2d<T, r, c>, metal::array2d<U, r, c> >
+ {
+ typedef mln_sum_x(T,U) ret;
+ };
+
+ template < template <class, class> class Name,
+ unsigned r, unsigned c, typename T,
+ typename S >
+ struct set_precise_binary_< Name,
+ metal::array2d<T, r, c>, mln::value::scalar_<S> >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array2d<V, r, c> ret;
+ };
+
+ template < template<class, class> class Name,
+ unsigned r, unsigned c, typename T,
+ typename S >
+ struct set_binary_< Name,
+ mln::Object, metal::array2d<T, r, c>,
+ mln::value::Scalar, S >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array2d<T, r, c> ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ //
+ // Constructors
+ //
+
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>::array2d()
+ {
+ }
+
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>::array2d(T* ptr)
+ {
+ for (unsigned i = 0; i < r * c; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>::array2d(const array2d<T, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < r * c; ++i)
+ buffer_[i] = rhs[i];
+ }
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>&
+ array2d<T, r, c>::operator=(const array2d<T, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < r * c; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+ // Operators
+
+ template <typename T, unsigned r, unsigned c>
+ template <class U>
+ array2d<T, r, c>
+ array2d<T, r, c>::operator*(U w)
+ {
+ //fixme mln_trait_op_mult<int,U>
+ array2d<T, r, c> tmp;
+ for (unsigned i = 0; i < r * c; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <typename T, unsigned r, unsigned c>
+ template <class U>
+ array2d<mln_trait_op_div(T,U), r, c>
+ array2d<T,r, c>::operator/(U w)
+ {
+ array2d<T, r, c> tmp;
+ for (unsigned i = 0; i < r * c; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ template <typename T, unsigned r, unsigned c>
+ template <typename U>
+ array2d<mln_trait_op_plus(T,U), r, c>
+ array2d<T,r, c>::operator+(const array2d<U, r, c>& rhs) const
+ {
+ array2d<T, r, c> tmp;
+ for (unsigned i = 0; i < r * c; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>&
+ array2d<T, r, c>::operator+=(const array2d<T, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < r * c; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ template <typename T, unsigned r, unsigned c>
+ template <typename U>
+ array2d<mln_trait_op_minus(T,U), r, c>
+ array2d<T,r, c>::operator-(const array2d<U, r, c>& rhs) const
+ {
+ array2d<T, r, c> tmp;
+ for (unsigned i = 0; i < r * c; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned r, unsigned c>
+ array2d<T, r, c>&
+ array2d<T, r, c>::operator-=(const array2d<T, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < r * c; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+ } // end of namespace metal
+
+} // end of namespace mln
+
+#endif /* MLN_METAL_ARRAY2D_HH */
+
Index: mln/metal/array3d.hh
--- mln/metal/array3d.hh (revision 0)
+++ mln/metal/array3d.hh (revision 0)
@@ -0,0 +1,310 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_METAL_ARRAY3D_HH
+# define MLN_METAL_ARRAY3D_HH
+
+# include <mln/core/concept/object.hh>
+
+# include <mln/trait/all.hh>
+# include <mln/trait/value_.hh>
+
+# include <mln/value/ops.hh>
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace metal {
+ template <typename T, unsigned s, unsigned r, unsigned c> struct array3d;
+ }
+
+ namespace trait
+ {
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ struct value_< mln::metal::array3d<T,s, r, c> >
+ {
+ typedef trait::value::nature::vectorial nature;
+ typedef trait::value::kind::data kind;
+
+ enum {
+ nbits = s * r * c * mln_nbits(T),
+ card = s * r * c * mln_card(T)
+ };
+ typedef mln_value_quant_from_(card) quant;
+
+ typedef metal::array3d<mln_sum(T), s, r, c> sum;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ struct array3d : public Object< array3d<T, s, r, c> >
+ {
+
+ //
+ // Constructors
+ //
+
+ array3d();
+ array3d(T* ptr);
+
+ // Copy
+
+ array3d(const array3d<T, s, r, c>& rhs);
+ array3d<T, s, r, c>& operator=(const array3d<T, s, r, c>&
rhs);
+
+ // Operators
+
+ template <class U>
+ array3d<T, s, r, c> operator*(U w);
+
+ template <class U>
+ array3d<mln_trait_op_div(T,U), s, r, c>
+ operator/(U w);
+
+ template <typename U>
+ array3d<mln_trait_op_plus(T,U), s, r, c>
+ operator+(const array3d<U, s, r, c>& rhs) const;
+ array3d<T, s, r, c>& operator+=(const array3d<T, s, r, c>&
rhs);
+
+ template <typename U>
+ array3d<mln_trait_op_minus(T,U), s, r, c>
+ operator-(const array3d<U, s, r, c>& rhs) const;
+ array3d<T, s, r, c>&
+ operator-=(const array3d<T, s, r, c>& rhs);
+
+
+ // dynamic accessors:
+
+ T operator[](unsigned i) const {
+ mln_precondition(i < s * r * c);
+ return buffer_[i];
+ }
+ T& operator[](unsigned i) {
+ mln_precondition(i < s * r * c);
+ return buffer_[i];
+ }
+
+ // static accessor
+
+ template <unsigned sli, unsigned row, unsigned col>
+ T get() const {
+ return buffer_[sli * (row * col) + col * r + row];
+ }
+ template <unsigned sli, unsigned row, unsigned col>
+ T& get() {
+ return buffer_[sli * (row * col) + col * r + row];
+ }
+
+
+ template <unsigned sli, unsigned row, unsigned col>
+ T get_at() const {
+ mln_precondition(sli * (row * col) + col * r + row < s * r * c );
+ return buffer_[sli * (row * col) + col * r + row];
+ }
+ template <unsigned sli, unsigned row, unsigned col>
+ T& get_at() {
+ mln_precondition(sli * (row * col) + col * r + row < s * r * c );
+ return buffer_[sli * (row * col) + col * r + row];
+ }
+
+ enum { length = s * r * c };
+ protected:
+
+ T buffer_[s * r * c];
+ };
+
+ }
+
+ namespace trait
+ {
+
+ // For unary traits.
+
+ template < template <class> class Name,
+ unsigned s, unsigned r, unsigned c, typename T >
+ struct set_precise_unary_< Name, metal::array3d<T, s, r, c> >
+ {
+ typedef mln_trait_unary(Name, T) V;
+ typedef metal::array3d<V, s, r, c> ret;
+ };
+
+ // For binary traits.
+
+ template < template <class, class> class Name,
+ unsigned s, unsigned r, unsigned c, typename T,
+ typename U >
+ struct set_precise_binary_< Name,
+ metal::array3d<T, s, r, c>, metal::array3d<U, s, r, c> >
+ {
+ typedef mln_trait_binary(Name, T, U) V;
+ typedef metal::array3d<V, s, r, c> ret;
+ };
+
+ template < unsigned s, unsigned r, unsigned c, typename T,
+ typename U >
+ struct set_precise_binary_< op::times,
+ metal::array3d<T, s, r, c>, metal::array3d<U, s, r, c> >
+ {
+ typedef mln_sum_x(T,U) ret;
+ };
+
+ template < template <class, class> class Name,
+ unsigned s, unsigned r, unsigned c, typename T,
+ typename S >
+ struct set_precise_binary_< Name,
+ metal::array3d<T, s, r, c>, mln::value::scalar_<S> >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array3d<V, s, r, c> ret;
+ };
+
+ template < template<class, class> class Name,
+ unsigned s, unsigned r, unsigned c, typename T,
+ typename S >
+ struct set_binary_< Name,
+ mln::Object, metal::array3d<T, s, r, c>,
+ mln::value::Scalar, S >
+ {
+ typedef mln_trait_binary(Name, T, S) V;
+ typedef metal::array3d<T, s, r, c> ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace metal
+ {
+
+ //
+ // Constructors
+ //
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T,s, r, c>::array3d()
+ {
+ }
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T,s, r, c>::array3d(T* ptr)
+ {
+ for (unsigned i = 0; i < s * r * c; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T,s, r, c>::array3d(const array3d<T, s, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < s * r * c; ++i)
+ buffer_[i] = rhs[i];
+ }
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T, s, r, c>&
+ array3d<T,s, r, c>::operator=(const array3d<T, s, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < s * r * c; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+ // Operators
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ template <class U>
+ array3d<T, s, r, c>
+ array3d<T,s, r, c>::operator*(U w)
+ {
+ //fixme mln_trait_op_mult<int,U>
+ array3d<T, s, r, c> tmp;
+ for (unsigned i = 0; i < s * r * c; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ template <class U>
+ array3d<mln_trait_op_div(T,U), s, r, c>
+ array3d<T,s, r, c>::operator/(U w)
+ {
+ array3d<T, s, r, c> tmp;
+ for (unsigned i = 0; i < s * r * c; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ template <typename U>
+ array3d<mln_trait_op_plus(T,U), s, r, c>
+ array3d<T,s, r, c>::operator+(const array3d<U, s, r, c>& rhs) const
+ {
+ array3d<T, s, r, c> tmp;
+ for (unsigned i = 0; i < s * r * c; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T, s, r, c>&
+ array3d<T,s, r, c>::operator+=(const array3d<T, s, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < s * r * c; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ template <typename U>
+ array3d<mln_trait_op_minus(T,U), s, r, c>
+ array3d<T,s, r, c>::operator-(const array3d<U, s, r, c>& rhs) const
+ {
+ array3d<T, s, r, c> tmp;
+ for (unsigned i = 0; i < s * r * c; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ template <typename T, unsigned s, unsigned r, unsigned c>
+ array3d<T, s, r, c>&
+ array3d<T,s, r, c>::operator-=(const array3d<T, s, r, c>& rhs)
+ {
+ for (unsigned i = 0; i < s * r * c; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+ } // end of namespace metal
+
+} // end of namespace mln
+
+#endif /* MLN_METAL_ARRAY3D_HH */
+