
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Ugo Jardonnet <ugo.jardonnet@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 */ +