Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* mlc/makefile.src: Add new files.
* mlc/array: New.
* mlc/array/nd.hh: New.
* mlc/array/1d.hh: New.
* mlc/array/2d.hh: New.
* mlc/array/3d.hh: New.
* mlc/array/all.hh: New.
* mlc/array/1d.hxx: New.
* mlc/array/2d.hxx: New.
* mlc/array/objs.hh: New.
* mlc/array/3d.hxx: New.
array/1d.hh | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++
array/1d.hxx | 237 +++++++++++++++++++++++++++++++++++++++++
array/2d.hh | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
array/2d.hxx | 283 +++++++++++++++++++++++++++++++++++++++++++++++++
array/3d.hh | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
array/3d.hxx | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++
array/all.hh | 35 ++++++
array/nd.hh | 50 ++++++++
array/objs.hh | 78 +++++++++++++
makefile.src | 11 +
10 files changed, 1940 insertions(+)
Index: mlc/makefile.src
--- mlc/makefile.src (revision 61)
+++ mlc/makefile.src (working copy)
@@ -5,11 +5,22 @@
MLC_DEP = \
any.hh \
+ array/1d.hh \
+ array/1d.hxx \
+ array/2d.hh \
+ array/2d.hxx \
+ array/3d.hh \
+ array/3d.hxx \
+ array/all.hh \
+ array/nd.hh \
+ array/objs.hh \
bool.hh \
box.hh \
cmp.hh \
config/system.hh \
contract.hh \
+ is_a.hh \
+ properties.hh \
tracked_ptr.hh \
traits.hh \
types.hh
Index: mlc/array/nd.hh
--- mlc/array/nd.hh (revision 0)
+++ mlc/array/nd.hh (revision 0)
@@ -0,0 +1,50 @@
+// Copyright (C) 2001, 2003 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_ND_HH
+# define METALIC_ARRAY_ND_HH
+
+
+namespace mlc
+{
+
+ namespace internal
+ {
+
+ //
+ // mlc::internal misc
+ //
+ ////////////////////////////////////////
+
+ static const unsigned max_card_ = 4096; // 64 x 64
+ static const unsigned unknown_ = max_card_ + 1;
+
+ } // end of internal
+
+} // end of namespace mlc
+
+#endif // ! METALIC_ARRAY_ND_HH
Index: mlc/array/1d.hh
--- mlc/array/1d.hh (revision 0)
+++ mlc/array/1d.hh (revision 0)
@@ -0,0 +1,294 @@
+// Copyright (C) 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_1D_HH
+# define METALIC_ARRAY_1D_HH
+
+# include <mlc/contract.hh>
+# include <mlc/cmp.hh>
+# include <mlc/array/objs.hh>
+# include <ntg/basics.hh>
+# include <iostream>
+
+
+// impl
+# include <mlc/array/1d.hxx>
+
+namespace mlc
+{
+
+ template<class Info_, class T_>
+ struct array1d
+ {
+ typedef array1d self;
+ typedef T_ T;
+ typedef Info_ Info;
+
+
+ //
+ // Constructors
+ //
+
+ array1d()
+ {
+ }
+
+ array1d(T* ptr)
+ {
+ less<0, Info_::card>::ensure();
+ less< Info_::card, internal::max_card_ >::ensure();
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ array1d(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ }
+ self& operator=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+
+ // Name
+
+ static std::string
+ name()
+ {
+ return std::string("array1d< Info, ") + ntg_name(T) + "
>";
+ }
+
+
+
+ //
+ // Operations on array
+ //
+
+ // Normalize (absolute values -> relative values)
+
+ array1d<Info_, ntg::float_s>
+ normalize()
+ {
+ array1d<Info_, ntg::float_s> tmp;
+ ntg::float_s sum = 0.f;
+ const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+ unsigned i;
+ for (i = 0; i < Info_::card; ++i)
+ sum += this->buffer_[i];
+ for (i = 0; i < Info_::card; ++i)
+ tmp[i] = this->buffer_[i] / sum;
+ // security
+ sum = 0.f;
+ for (i = 0; i < Info_::card; ++i)
+ sum += tmp[i];
+ postcondition(std::abs(sum - 1) <= epsilon);
+ return tmp;
+ }
+
+ // Central symmetry
+
+ array1d<array1d_info<Info_::card,
+ Info_::card - Info_::center - 1,
+ Info_::i>, T>
+ operator-() const
+ {
+ enum { new_center = Info_::card - Info_::center - 1 };
+ array1d<array1d_info< Info_::card, new_center, Info_::i>,T> tmp;
+
+ for (unsigned i = 0; i < Info_::card; ++i)
+ tmp[Info_::card - i - 1] = this->operator[](i);
+ return tmp;
+ }
+
+
+ // Operators
+
+ // FIXME: This code should be factorized between 1d, 2d and 3d.
+ // Think of a mechanism similar to apply() and apply2().
+
+ template <class U>
+ array1d< Info, ntg_return_type(times, T, U) >
+ operator*(U w)
+ {
+ array1d< Info, ntg_return_type(times, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <class U>
+ array1d< Info, ntg_return_type(div, T, U) >
+ operator/(U w)
+ {
+ array1d< Info, ntg_return_type(div, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ self operator+(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator+=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ self operator-(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator-=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+
+ //
+ // Accessors
+ //
+
+ unsigned size() const
+ {
+ return Info_::card;
+ }
+
+ const T* buffer() const
+ {
+ return buffer_;
+ }
+
+ // dynamic accessors:
+
+ T operator[](unsigned i) const // Absolute position
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+ T& operator[](unsigned i)
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+
+ T operator()(int i) const // Relative position
+ {
+ precondition(-Info_::center <= i);
+ precondition(i <= Info_::card - Info_::center - 1);
+ return *(buffer_ + Info_::center + i);
+ }
+ T& operator()(int i)
+ {
+ precondition(-Info_::center <= i);
+ precondition(i <= Info_::card - Info_::center - 1);
+ return *(buffer_ + Info_::center + i);
+ }
+
+
+ // do not use these methods...
+
+ template<unsigned i>
+ T get_at_() const {
+ lesseq<i, Info_::card>::ensure();
+ return *(buffer_ + i);
+ }
+
+ template<int i>
+ T get_() const {
+ lesseq<-Info_::center, i>::ensure();
+ lesseq<i, Info_::card - Info_::center - 1>::ensure();
+ return *(buffer_ + Info_::center + i);
+ }
+
+ protected:
+
+ T buffer_[Info_::card];
+ };
+
+
+ // ...but these static accessors:
+
+ template<unsigned i, class Info, class T> inline
+ T get_at(const array1d<Info, T>& arr)
+ {
+ return arr.template get_at_<i>();
+ }
+
+ template<int i, class Info, class T> inline
+ T get(const array1d<Info, T>& arr)
+ {
+ return arr.template get_<i>();
+ }
+
+ // starter objects
+
+ // FIXME: what about other types? Replace this by a function
+ // returning a starter.
+
+# define array1d_starter(T) \
+ static internal::array1d_start_<T > T##s_1d = internal::array1d_start_<T
>()
+
+ array1d_starter(int); // ints_1d
+ array1d_starter(float); // floats_1d
+
+
+
+ // print
+
+ template<class Info, class T>
+ std::ostream& operator<<(std::ostream& ostr, const array1d<Info,
T>& rhs)
+ {
+ for (int i = 0; i < Info::card; ++i)
+ if (i == Info::center)
+ ostr << "<" << rhs[i] << "> ";
+ else
+ ostr << rhs[i] << " ";
+ ostr << std::endl;
+
+ return ostr;
+ }
+
+} // end of mlc
+
+#endif // ! METALIC_ARRAY_1D_HH
Index: mlc/array/2d.hh
--- mlc/array/2d.hh (revision 0)
+++ mlc/array/2d.hh (revision 0)
@@ -0,0 +1,326 @@
+// Copyright (C) 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_2D_HH
+# define METALIC_ARRAY_2D_HH
+
+# include <mlc/array/objs.hh>
+# include <mlc/contract.hh>
+# include <mlc/cmp.hh>
+# include <ntg/basics.hh>
+
+# include <iostream>
+
+// impl
+# include <mlc/array/2d.hxx>
+
+namespace mlc
+{
+
+ template<class Info_, class T_>
+ struct array2d
+ {
+ typedef array2d self;
+ typedef T_ T;
+ typedef Info_ Info;
+
+ //
+ // Constructors
+ //
+
+ array2d()
+ {
+ }
+
+ array2d(T* ptr)
+ {
+ less< 0, Info_::nrows >::ensure();
+ less< 0, Info_::ncols >::ensure();
+ less< Info_::card, internal::max_card_ >::ensure();
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ array2d(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ }
+ self& operator=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+
+ // Name
+
+ static std::string
+ name()
+ {
+ return std::string("array2d< Info, ") + ntg_name(T) + "
>";
+ }
+
+
+
+ //
+ // Operations on array
+ //
+
+
+ // Normalize (absolute values -> relative values)
+
+ array2d<Info_, ntg::float_s>
+ normalize()
+ {
+ array2d<Info_, ntg::float_s> tmp;
+ ntg::float_s sum = 0.f;
+ const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+ unsigned i;
+ for (i = 0; i < Info_::card; ++i)
+ sum += this->buffer_[i];
+ for (i = 0; i < Info_::card; ++i)
+ tmp[i] = this->buffer_[i] / sum;
+ // security
+ sum = 0.f;
+ for (i = 0; i < Info_::card; ++i)
+ sum += tmp[i];
+ postcondition(std::abs(sum - 1) <= epsilon);
+ return tmp;
+ }
+
+ // Central symmetry
+
+ array2d<array2d_info<Info_::nrows,
+ Info_::ncols,
+ Info_::card - Info_::center - 1,
+ Info_::i>, T>
+ operator-() const
+ {
+ enum { new_center = Info_::card - Info_::center - 1 };
+ array2d<array2d_info< Info_::nrows, Info_::ncols, new_center,
Info_::i>,T> tmp;
+
+ for (unsigned i = 0; i < Info_::card; ++i)
+ tmp[Info_::card - i - 1] = this->operator[](i);
+ return tmp;
+ }
+
+
+ // Transpose
+
+ typedef array2d<array2d_info<
+ Info_::ncols,
+ Info_::nrows,
+ (Info_::center * Info_::nrows + Info_::center / Info_::ncols) % Info_::card,
+ Info_::i
+ >, T> transposed_array_t;
+
+ transposed_array_t transpose() const
+ {
+ transposed_array_t tmp;
+ for (int i = 0; i < Info::card; ++i)
+ tmp[i] = this->operator[]((i * Info_::ncols + i / Info_::nrows) % Info_::card);
+ return tmp;
+ }
+
+ // Operators
+
+ // FIXME: This code should be factorized between 1d, 2d and 3d.
+ // Think of a mechanism similar to apply() and apply2().
+
+ template <class U>
+ array2d< Info, ntg_return_type(times, T, U) >
+ operator*(U w)
+ {
+ array2d< Info, ntg_return_type(times, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <class U>
+ array2d< Info, ntg_return_type(div, T, U) >
+ operator/(U w)
+ {
+ array2d< Info, ntg_return_type(div, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ self operator+(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator+=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ self operator-(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator-=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+
+ //
+ // Accessors
+ //
+
+ unsigned size() const
+ {
+ return Info_::card;
+ }
+
+ const T* buffer() const
+ {
+ return buffer_;
+ }
+
+ // dynamic accessors:
+
+ T operator[](unsigned i) const // Absolute position
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+ T& operator[](unsigned i)
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+
+
+ T operator()(int row, int col) const // Relative position
+ {
+ precondition(-Info_::center_row <= row);
+ precondition(row <= Info_::nrows - Info_::center_row - 1);
+ precondition(-Info_::center_col <= col);
+ precondition(col <= Info_::ncols - Info_::center_col - 1);
+
+ return *(buffer_ + Info_::center + (row * Info_::ncols) + col);
+ }
+ T& operator()(int row, int col)
+ {
+ precondition(-Info_::center_row <= row);
+ precondition(row <= Info_::nrows - Info_::center_row - 1);
+ precondition(-Info_::center_col <= col);
+ precondition(col <= Info_::ncols - Info_::center_col - 1);
+
+ return *(buffer_ + Info_::center + (row * Info_::ncols) + col);
+ }
+
+
+ // do not use these methods...
+
+ template<unsigned i>
+ T get_at_() const {
+ lesseq<i, Info_::card>::ensure();
+ return *(buffer_ + i);
+ }
+
+ template<int nrow, int ncol>
+ T get_() const {
+ lesseq< -Info_::center_row, nrow >::ensure();
+ lesseq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
+ lesseq< -Info_::center_col, ncol >::ensure();
+ lesseq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
+ return *(buffer_ + Info_::center + (nrow * Info_::ncols) + ncol);
+ }
+
+
+ protected:
+
+ T buffer_[internal::max_card_];
+ };
+
+
+ // ...but these static accessors:
+
+ template<unsigned i, class Info, class T> inline
+ T get_at(const array2d<Info, T>& arr)
+ {
+ return arr.template get_at_<i>();
+ }
+
+ template<int row, int col, class Info, class T> inline
+ T get(const array2d<Info, T>& arr)
+ {
+ return arr.template get_<row, col>();
+ }
+
+ // starter objects
+
+ // FIXME: what about other types? Replace this by a function
+ // returning a starter.
+
+# define array2d_starter(T) \
+ static internal::array2d_start_<T > T##s_2d = internal::array2d_start_<T
>()
+
+ array2d_starter(int); // ints_2d
+ array2d_starter(float); // floats_2d
+
+
+ // print
+
+ template<class Info, class T>
+ std::ostream& operator<<(std::ostream& ostr, const array2d<Info,
T>& rhs)
+ {
+ for (int i = 0; i < Info::card; ++i)
+ {
+ if (i == Info::center)
+ ostr << "<" << rhs[i] << ">";
+ else
+ ostr << rhs[i];
+
+ ostr << ((i + 1) % Info::ncols == 0 ? "\n" : "\t");
+ }
+ ostr << std::flush;
+ return ostr;
+ }
+
+} // end of mlc
+
+
+#endif // ! METALIC_ARRAY_2D_HH
Index: mlc/array/3d.hh
--- mlc/array/3d.hh (revision 0)
+++ mlc/array/3d.hh (revision 0)
@@ -0,0 +1,333 @@
+// Copyright (C) 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_3D_HH
+# define METALIC_ARRAY_3D_HH
+
+# include <mlc/array/objs.hh>
+# include <mlc/contract.hh>
+# include <mlc/cmp.hh>
+# include <ntg/basics.hh>
+
+# include <iostream>
+
+// impl
+# include <mlc/array/3d.hxx>
+
+namespace mlc
+{
+
+ class not_implemented_yet{}; // FIXME
+
+ template<class Info_, class T_>
+ struct array3d
+ {
+ typedef array3d self;
+ typedef T_ T;
+ typedef Info_ Info;
+
+ //
+ // Constructors
+ //
+
+ array3d()
+ {
+ }
+
+ array3d(T* ptr)
+ {
+ less< 0, Info_::nplanes >::ensure();
+ less< 0, Info_::nrows >::ensure();
+ less< 0, Info_::ncols >::ensure();
+ less< Info_::card, internal::max_card_ >::ensure();
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = *ptr++;
+ }
+
+ // Copy
+
+ array3d(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ }
+ self& operator=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info_::card; ++i)
+ buffer_[i] = rhs[i];
+ return *this;
+ }
+
+
+ // Name
+
+ static std::string
+ name()
+ {
+ return std::string("array3d< Info, ") + ntg_name(T) + "
>";
+ }
+
+
+
+ //
+ // Operations on array
+ //
+
+ // Normalize (absolute values -> relative values)
+
+ array3d<Info_, ntg::float_s>
+ normalize()
+ {
+ array3d<Info_, ntg::float_s> tmp;
+ ntg::float_s sum = 0.f;
+ const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
+ unsigned i;
+ for (i = 0; i < Info_::card; ++i)
+ sum += this->buffer_[i];
+ for (i = 0; i < Info_::card; ++i)
+ tmp[i] = this->buffer_[i] / sum;
+ // security
+ sum = 0.f;
+ for (i = 0; i < Info_::card; ++i)
+ sum += tmp[i];
+ postcondition(std::abs(sum - 1) <= epsilon);
+ return tmp;
+ }
+
+ // Central symmetry
+
+ array3d<array3d_info<Info_::nplanes,
+ Info_::nrows,
+ Info_::ncols,
+ Info_::card - Info_::center - 1,
+ Info_::i>, T>
+ operator-() const
+ {
+ enum { new_center = Info_::card - Info_::center - 1 };
+ array3d<array3d_info< Info_::nplanes, Info_::nrows, Info_::ncols, new_center,
Info_::i>,T> tmp;
+
+ for (unsigned i = 0; i < Info_::card; ++i)
+ tmp[Info_::card - i - 1] = this->operator[](i);
+ return tmp;
+ }
+
+
+ // Transpose
+
+ array3d<Info, T> transpose() const // FIXME
+ {
+ std::cerr << "[31m===> 3D transposition not implemented yet.
<===[0m" << std::endl;
+ throw not_implemented_yet();
+ }
+
+
+ // Operators
+
+ // FIXME: This code should be factorized between 1d, 2d and 3d.
+ // Think of a mechanism similar to apply() and apply2().
+
+ template <class U>
+ array3d< Info, ntg_return_type(times, T, U) >
+ operator*(U w)
+ {
+ array3d< Info, ntg_return_type(times, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] * w;
+ return tmp;
+ }
+
+ template <class U>
+ array3d< Info, ntg_return_type(div, T, U) >
+ operator/(U w)
+ {
+ array3d< Info, ntg_return_type(div, T, U) > tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] / w;
+ return tmp;
+ }
+
+ self operator+(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] + rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator+=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] += rhs.buffer_[i];
+ return *this;
+ }
+
+ self operator-(const self& rhs) const
+ {
+ self tmp;
+ for (unsigned i = 0; i < Info::card; ++i)
+ tmp[i] = this->buffer_[i] - rhs.buffer_[i];
+ return tmp;
+ }
+ self& operator-=(const self& rhs)
+ {
+ for (unsigned i = 0; i < Info::card; ++i)
+ this->buffer_[i] -= rhs.buffer_[i];
+ return *this;
+ }
+
+
+
+ // template<class U> int operator,(U); // FIXME: why this?
+
+ //
+ // Accessors
+ //
+
+ unsigned size() const
+ {
+ return Info_::card;
+ }
+
+ const T* buffer() const
+ {
+ return buffer_;
+ }
+
+ // dynamic accessors:
+
+ T operator[](unsigned i) const // Absolute position
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+ T& operator[](unsigned i)
+ {
+ precondition(i < Info_::card);
+ return *(buffer_ + i);
+ }
+
+
+ T operator()(int plane, int row, int col) const // Relative position
+ {
+ precondition(-Info_::center_plane <= plane);
+ precondition(plane <= Info::nplanes - Info_::center_plane - 1);
+ precondition(-Info_::center_row <= row);
+ precondition(row <= Info_::nrows - Info_::center_row - 1);
+ precondition(-Info_::center_col <= col);
+ precondition(col <= Info_::ncols - Info_::center_col - 1);
+
+ return *(buffer_ + Info_::center + (plane * Info::nrows * Info::ncols) + (row *
Info::ncols) + col);
+ }
+
+ T& operator()(int plane, int row, int col)
+ {
+ precondition(-Info_::center_plane <= plane);
+ precondition(plane <= Info::nplanes - Info_::center_plane - 1);
+ precondition(-Info_::center_row <= row);
+ precondition(row <= Info_::nrows - Info_::center_row - 1);
+ precondition(-Info_::center_col <= col);
+ precondition(col <= Info_::ncols - Info_::center_col - 1);
+
+ return *(buffer_ + Info_::center + (plane * Info::nrows * Info::ncols) + (row *
Info::ncols) + col);
+ }
+
+
+ // do not use these methods...
+
+ template<unsigned i>
+ T get_at_() const {
+ lesseq<i, Info_::card>::ensure();
+ return *(buffer_ + i);
+ }
+
+ template<int nplane, int nrow, int ncol>
+ T get_() const {
+ lesseq< -Info_::center_plane, nplane >::ensure();
+ lesseq< nplane, Info::nplanes - Info_::center_plane - 1 >::ensure();
+ lesseq< -Info_::center_row, nrow >::ensure();
+ lesseq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
+ lesseq< -Info_::center_col, ncol >::ensure();
+ lesseq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
+ return *(buffer_ + Info_::center + (nplane * Info::nrows * Info::ncols) + (nrow *
Info::ncols) + ncol);
+ }
+
+
+ protected:
+
+ T buffer_[internal::max_card_];
+ };
+
+
+ // ...but these static accessors:
+
+ template<unsigned i, class Info, class T> inline
+ T get_at(const array3d<Info, T>& arr)
+ {
+ return arr.template get_at_<i>();
+ }
+
+ template<int plane, int row, int col, class Info, class T> inline
+ T get(const array3d<Info, T>& arr)
+ {
+ return arr.template get_<plane, row, col>();
+ }
+
+ // starter objects
+
+ // FIXME: what about other types? Replace this by a function
+ // returning a starter.
+
+# define array3d_starter(T) \
+ static internal::array3d_start_<T > T##s_3d = internal::array3d_start_<T
>()
+
+ array3d_starter(int); // ints_3d
+ array3d_starter(float); // floats_3d
+
+
+ // print
+
+ template<class Info, class T>
+ std::ostream& operator<<(std::ostream& ostr, const array3d<Info,
T>& rhs)
+ {
+ for (int i = 0; i < Info::card; ++i)
+ {
+ if (i == Info::center)
+ ostr << "<" << rhs[i] << "> ";
+ else
+ ostr << rhs[i] << " ";
+
+ ostr << ((i + 1) % Info::ncols == 0 ? "\n" : "\t");
+ ostr << ((i + 1) % (Info::ncols * Info::nrows) == 0 ? "\n" :
"");
+ }
+ ostr << std::flush;
+
+ return ostr;
+ }
+
+
+} // end of mlc
+
+#endif // ! METALIC_ARRAY_3D_HH
Index: mlc/array/all.hh
--- mlc/array/all.hh (revision 0)
+++ mlc/array/all.hh (revision 0)
@@ -0,0 +1,35 @@
+// Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY__HH
+# define METALIC_ARRAY__HH
+
+# include <mlc/array/1d.hh>
+# include <mlc/array/2d.hh>
+# include <mlc/array/3d.hh>
+
+#endif // ! METALIC_ARRAY__HH
Index: mlc/array/1d.hxx
--- mlc/array/1d.hxx (revision 0)
+++ mlc/array/1d.hxx (revision 0)
@@ -0,0 +1,237 @@
+// Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_1D_HXX
+# define METALIC_ARRAY_1D_HXX
+
+# include <mlc/array/nd.hh>
+
+namespace mlc
+{
+
+ //
+ // mlc::array1d_info
+ //
+ ////////////////////////////////////////
+
+
+ // card_ -> total number of elements (1-indexed)
+
+ // center_ -> position of the central element (0-indexed)
+ // domain : [ 0, card [
+
+ // i_ -> number of elements that have been eaten yet (0-indexed)
+ // domain : [ 0, card ] -> watch out !!
+
+
+ template < unsigned card_, unsigned center_ = card_ / 2, unsigned i_ = card_>
+ struct array1d_info
+ {
+ enum {
+ card = card_,
+ center = center_,
+ i = i_,
+ well_formed = true,
+ get_real_center = center_
+ };
+
+ typedef array1d_info< card_, center_, i + 1 > next_elt;
+
+ };
+
+ template < unsigned card_, unsigned i_ >
+ struct array1d_info <card_, internal::unknown_, i_ >
+ {
+ enum {
+ card = card_,
+ center = internal::unknown_,
+ i = i_,
+ well_formed = true,
+ get_real_center = i_ / 2
+ };
+
+ typedef array1d_info< card_, internal::unknown_, i + 1 > next_elt;
+
+ };
+
+ // fwd decl
+ template<class, class> struct array1d;
+
+
+ namespace internal
+ {
+
+ // fwd decl
+
+ template<class T, class Info>
+ struct array1d_elt_;
+
+ // for error messages
+
+ template<class U>
+ struct here_a_value_is_not_of_type_;
+
+
+ //
+ // mlc::internal::array1d_start_ decl
+ //
+ ////////////////////////////////////////
+
+ template<class T>
+ struct array1d_start_ {
+
+ array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > > operator=(T
val);
+ array1d_elt_< T, array1d_info< unknown_, 0, 1 > > operator=(x_<T>
val);
+ array1d_elt_< T, array1d_info< unknown_, 0, 1 > >
operator=(x_<void> val);
+
+ T ptr[max_card_]; // could be static
+ };
+
+
+
+ //
+ // mlc::internal::array1d_elt_
+ //
+ ////////////////////////////////////////
+
+ template<class T, class Info>
+ struct array1d_elt_
+ {
+ typedef array1d_elt_<T, typename Info::next_elt> next_elt_t_;
+
+ typedef array1d_elt_< T, array1d_info< Info::card, Info::i, Info::i + 1>
> eat_center_t_;
+
+ typedef array1d< array1d_info< Info::i, Info::get_real_center, Info::i > ,
T> array1d_t_;
+
+ public:
+
+ // Constructor
+
+ array1d_elt_(T* ptr, array1d_start_<T>* arr) : ptr(ptr), arr(arr)
+ {
+ }
+
+
+
+ //
+ // Overloading "operator,"
+ //
+
+
+ // elt, elt
+
+ next_elt_t_ operator,(T val)
+ {
+ is_true<Info::card == unknown_>::ensure();
+ *ptr = val;
+ return next_elt_t_(ptr + 1, arr);
+ }
+
+
+ // elt, x(elt) -> center
+
+ eat_center_t_ operator,(x_<T> val)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = val.ue; // FIXME : give a *name* to this variable !!
+ return eat_center_t_(ptr+1, arr);
+ }
+
+
+ // elt, x() -> center
+
+ eat_center_t_ operator,(x_<void>)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = T(0);
+ return eat_center_t_(ptr+1, arr);
+ }
+
+
+ // elt, end
+
+ array1d_t_ operator,(end_type)
+ {
+ // array is well-formed :
+ is_true<Info::well_formed>::ensure();
+ // centering is automatic or user-defined :
+ // (commented out to allow automatic centering on even sized arrays)
+ // mlc::logical_or< mlc::eq< Info::i % 2, 1 >::ret, mlc::neq< Info::center,
unknown_ >::ret >::ensure();
+ return array1d_t_(arr->ptr);
+ }
+
+
+ // else -> error
+
+ template<class U>
+ void operator,(array1d< Info, U >);
+
+ template<class U>
+ here_a_value_is_not_of_type_<T> operator,(U u) const;
+
+ T* ptr;
+ array1d_start_<T>* arr;
+ };
+
+
+
+ //
+ // mlc::internal::array1d_start_ impl
+ //
+ ////////////////////////////////////////
+
+ template<class T> inline
+ array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > >
+ array1d_start_<T>::operator=(T val)
+ {
+ ptr[0] = val;
+ return array1d_elt_< T, array1d_info< unknown_, unknown_, 1 > >(ptr+1,
this);
+ }
+
+ template<class T> inline
+ array1d_elt_< T, array1d_info< unknown_, 0, 1 > >
+ array1d_start_<T>::operator=(x_<T> val)
+ {
+ ptr[0] = val.ue;
+ // center <- 0
+ return array1d_elt_< T, array1d_info< unknown_, 0, 1 > >(ptr+1, this);
+ }
+
+ template<class T> inline
+ array1d_elt_< T, array1d_info< unknown_, 0, 1 > >
+ array1d_start_<T>::operator=(x_<void> val)
+ {
+ ptr[0] = T(0);
+ // center <- 0
+ return array1d_elt_< T, array1d_info< unknown_, 0, 1 > >(ptr+1,this);
+ }
+
+ } // end of internal
+
+} // end of mlc
+
+#endif // ! METALIC_ARRAY_1D_HXX
Index: mlc/array/2d.hxx
--- mlc/array/2d.hxx (revision 0)
+++ mlc/array/2d.hxx (revision 0)
@@ -0,0 +1,283 @@
+// Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_2D_HXX
+# define METALIC_ARRAY_2D_HXX
+
+# include <mlc/array/nd.hh>
+
+namespace mlc
+{
+
+ //
+ // mlc::array2d_info
+ //
+ ////////////////////////////////////////
+
+
+ // nrows_ -> total number of rows (1-indexed)
+ // ncols_ -> total number of columns (1-indexed)
+
+ // center_ -> position of the central element (0-indexed)
+ // domain : [ 0, card [
+
+ // i_ -> number of elements that have been eaten yet (0-indexed)
+ // domain : [ 0, card ] -> watch out !!
+
+
+
+ // Center is user-defined
+
+ template < unsigned nrows_,
+ unsigned ncols_,
+ unsigned center_ = ncols_ * (nrows_ / 2) + (ncols_ / 2),
+ unsigned i_ = nrows_ * ncols_>
+ struct array2d_info
+ {
+ enum {
+ nrows = nrows_,
+ ncols = ncols_,
+ center = center_,
+ center_row = center_ / ncols_,
+ center_col = center_ % ncols_,
+ card = nrows_ * ncols_,
+ i = i_,
+ well_formed = ((i_ % ncols_) == 0),
+ get_real_center = center_
+ };
+
+ typedef array2d_info< nrows_, ncols_, center_, i + 1 > next_elt;
+
+ };
+
+ // Center is defined automatically, if nrows and ncols are both odd
+
+ template < unsigned nrows_, unsigned ncols_, unsigned i_ >
+ struct array2d_info <nrows_, ncols_, internal::unknown_, i_ >
+ {
+ enum {
+ nrows = nrows_,
+ ncols = ncols_,
+ center = internal::unknown_,
+ i = i_,
+ card = nrows_ * ncols_,
+ well_formed = ((i_ % ncols_) == 0),
+ get_real_center = i_ / 2
+ };
+
+ typedef array2d_info< nrows_, ncols_, internal::unknown_, i + 1 > next_elt;
+
+ };
+
+ // fwd decl
+ template<class, class> struct array2d;
+
+
+ namespace internal
+ {
+
+ // fwd decl
+
+ template<class T, class Info>
+ struct array2d_elt_;
+
+ // for error messages
+
+ template<class U>
+ struct here_a_value_is_not_of_type_;
+
+
+ //
+ // mlc::internal::array2d_start_ decl
+ //
+ ////////////////////////////////////////
+
+ template<class T>
+ struct array2d_start_ {
+
+ array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 > >
+ operator=(T val);
+
+ array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
+ operator=(x_<T> val);
+
+ array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
+ operator=(x_<void> val);
+
+ T ptr[max_card_]; // could be static
+ };
+
+
+ //
+ // mlc::internal::array2d_elt_
+ //
+ ////////////////////////////////////////
+
+ template<class T, class Info>
+ struct array2d_elt_
+ {
+ typedef array2d_elt_< T, typename Info::next_elt >
+ next_elt_t_;
+
+ typedef array2d_elt_< T, array2d_info< Info::nrows, Info::ncols, Info::i, Info::i
+ 1> >
+ eat_center_t_;
+
+ typedef array2d_elt_< T, array2d_info< Info::nrows, Info::i, Info::center, Info::i
> >
+ eat_lbrk_t_;
+
+ typedef array2d< array2d_info< Info::i / Info::ncols, Info::ncols,
Info::get_real_center, Info::i > , T>
+ array2d_t_;
+
+ public:
+
+ // Constructor
+
+ array2d_elt_(T* ptr, array2d_start_<T>* arr) : ptr(ptr), arr(arr)
+ {
+ }
+
+
+ //
+ // Overloading "operator,"
+ //
+
+
+ // elt, elt
+
+ next_elt_t_ operator,(T val)
+ {
+ is_true<Info::nrows == unknown_>::ensure();
+ *ptr = val;
+ return next_elt_t_(ptr + 1, arr);
+ }
+
+
+ // elt, x(elt) -> center
+
+ eat_center_t_ operator,(x_<T> val)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = val.ue; // FIXME : give a *name* to this variable !!
+ return eat_center_t_(ptr + 1, arr);
+ }
+
+
+ // elt, x() -> center
+
+ eat_center_t_ operator,(x_<void>)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = T(0);
+ return eat_center_t_(ptr + 1, arr);
+ }
+
+
+ // elt, lbrk
+
+ eat_lbrk_t_ operator,(lbrk_)
+ {
+ is_true<Info::ncols == unknown_>::ensure();
+ is_true<Info::ncols != 0>::ensure();
+ return eat_lbrk_t_(ptr, arr);
+ }
+
+
+ // elt, end
+
+ array2d_t_ operator,(end_type)
+ {
+ enum { nrows = Info::i / Info::ncols };
+
+ // array is well-formed :
+ is_true<Info::well_formed == true>::ensure();
+ // centering is automatic or user-defined :
+
+ is_true<Info::ncols != unknown_>::ensure();
+
+
+ // both nrows and ncols must be odd
+ // or the center must be user-defined
+
+ is_true<
+ ((Info::ncols % 2 == 1) && (nrows % 2 == 1))
+ || (Info::center != unknown_)
+ >::ensure();
+
+ return array2d_t_(arr->ptr);
+ }
+
+
+ // else -> error
+
+ template<class U>
+ void operator,(array2d< Info, U >);
+
+ template<class U>
+ here_a_value_is_not_of_type_<T> operator,(U u) const;
+
+ T* ptr;
+ array2d_start_<T>* arr;
+ };
+
+
+
+ //
+ // mlc::internal::array2d_start_ impl
+ //
+ ////////////////////////////////////////
+
+ template<class T> inline
+ array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 > >
+ array2d_start_<T>::operator=(T val)
+ {
+ ptr[0] = val;
+ return array2d_elt_< T, array2d_info< unknown_, unknown_, unknown_, 1 >
>(ptr+1,this);
+ }
+
+ template<class T> inline
+ array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
+ array2d_start_<T>::operator=(x_<T> val)
+ {
+ ptr[0] = val.ue;
+ // center <- 0
+ return array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 >
>(ptr+1,this);
+ }
+
+ template<class T> inline
+ array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 > >
+ array2d_start_<T>::operator=(x_<void> val)
+ {
+ ptr[0] = T(0);
+ // center <- 0
+ return array2d_elt_< T, array2d_info< unknown_, unknown_, 0, 1 >
>(ptr+1,this);
+ }
+
+ } // end of internal
+
+} // end of mlc
+
+#endif // ! METALIC_ARRAY_2D_HXX
Index: mlc/array/objs.hh
--- mlc/array/objs.hh (revision 0)
+++ mlc/array/objs.hh (revision 0)
@@ -0,0 +1,78 @@
+// Copyright (C) 2001, 2002, 2003, 2005 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_OBJS_HH
+# define METALIC_ARRAY_OBJS_HH
+
+// FIXME: rename, objs is not precise enough.
+
+//
+// Defines common objects useful for array declarations.
+//
+
+namespace mlc
+{
+
+ class begin_type {};
+ class end_type {};
+
+ static const begin_type begin = begin_type();
+ static const end_type end = end_type();
+
+ namespace internal
+ {
+
+ class lbrk_ {};
+ class pbrk_ {};
+
+ template<class T>
+ struct x_ {
+ x_(T val) : ue(val) {}
+ T ue;
+ };
+ template<> struct x_<void> {};
+ template<> struct x_<lbrk_>;
+ template<> struct x_<end_type>;
+
+ } // end of internal
+
+ // cross means origin
+
+ template<class T> inline
+ internal::x_<T>
+ x(T val) { return internal::x_<T>(val); }
+
+ inline
+ internal::x_<void>
+ x() { return internal::x_<void>(); }
+
+ static const internal::lbrk_ lbrk = internal::lbrk_();
+ static const internal::pbrk_ pbrk = internal::pbrk_();
+
+} // end of mlc
+
+#endif // METALIC_ARRAY_OBJS_HH
Index: mlc/array/3d.hxx
--- mlc/array/3d.hxx (revision 0)
+++ mlc/array/3d.hxx (revision 0)
@@ -0,0 +1,293 @@
+// Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, 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 METALIC_ARRAY_3D_HXX
+# define METALIC_ARRAY_3D_HXX
+
+# include <mlc/array/nd.hh>
+
+namespace mlc
+{
+
+ //
+ // mlc::array3d_info
+ //
+ ////////////////////////////////////////
+
+
+ // nrows_ -> total number of rows (1-indexed)
+ // ncols_ -> total number of columns (1-indexed)
+ // nplanes_ -> total number of planes (1-indexed)
+
+ // center_ -> position of the central element (0-indexed)
+ // domain : [ 0, card [
+
+ // i_ -> number of elements that have been eaten yet (0-indexed)
+ // domain : [ 0, card ] -> watch out !!
+
+ // Center is user-defined
+
+ template < unsigned nplanes_,
+ unsigned nrows_,
+ unsigned ncols_,
+ unsigned center_ = (ncols_ * nrows_) * (nplanes_ / 2) + ncols_ * (nrows_ / 2) +
(ncols_ / 2),
+ unsigned i_ = nplanes_ * nrows_ * ncols_>
+ struct array3d_info
+ {
+ enum {
+ nplanes = nplanes_,
+ nrows = nrows_,
+ ncols = ncols_,
+ center = center_,
+ center_plane = center_ / (nrows_ * ncols_),
+ center_row = (center_ % (nrows_ * ncols_)) / ncols_,
+ center_col = (center_ % (nrows_ * ncols_)) % ncols_,
+ i = i_,
+ card = nplanes_ * nrows_ * ncols_,
+ well_formed = (i_ % (ncols_ * nrows) == 0),
+ get_real_center = center_
+ };
+
+ typedef array3d_info< nplanes_, nrows_, ncols_, center_, i + 1 > next_elt;
+
+ };
+
+ // Center is defined automatically, if nrows and ncols are both odd
+
+ template < unsigned nplanes_, unsigned nrows_, unsigned ncols_, unsigned i_ >
+ struct array3d_info < nplanes_, nrows_, ncols_, internal::unknown_, i_ >
+ {
+ enum {
+ nplanes = nplanes_,
+ nrows = nrows_,
+ ncols = ncols_,
+ center = internal::unknown_,
+ i = i_,
+ card = nplanes_ * nrows_ * ncols_,
+ well_formed = (i_ % (ncols_ * nrows_) == 0),
+ get_real_center = i_ / 2
+ };
+
+ typedef array3d_info< nplanes_, nrows_, ncols_, internal::unknown_, i + 1 >
next_elt;
+
+ };
+
+ // fwd decl
+ template<class, class> struct array3d;
+
+ namespace internal
+ {
+
+ // fwd decl
+
+ template<class T, class Info>
+ struct array3d_elt_;
+
+ // for error messages
+
+ template<class U>
+ struct here_a_value_is_not_of_type_;
+
+
+ //
+ // mlc::internal::array3d_start_ decl
+ //
+ ////////////////////////////////////////
+
+ template<class T>
+ struct array3d_start_ {
+
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_, 1 >
>
+ operator=(T val);
+
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
+ operator=(x_<T> val);
+
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
+ operator=(x_<void> val);
+
+ T ptr[max_card_]; // could be static
+ };
+
+ //
+ // mlc::internal::array3d_elt_
+ //
+ ////////////////////////////////////////
+
+ template<class T, class Info>
+ struct array3d_elt_
+ {
+ typedef array3d_elt_< T, typename Info::next_elt >
+ next_elt_t_;
+
+ typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::nrows,
Info::ncols, Info::i, Info::i + 1> >
+ eat_center_t_;
+
+ typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::nrows, Info::i,
Info::center, Info::i > >
+ eat_lbrk_t_;
+
+ typedef array3d_elt_< T, array3d_info< Info::nplanes, Info::i / Info::ncols,
Info::ncols, Info::center, Info::i > >
+ eat_pbrk_t_;
+
+ typedef array3d< array3d_info< Info::i / (Info::ncols * Info::nrows),
Info::nrows, Info::ncols, Info::get_real_center, Info::i > , T>
+ array3d_t_;
+
+ public:
+
+ // Constructor
+
+ array3d_elt_(T* ptr, array3d_start_<T>* arr) : ptr(ptr), arr(arr)
+ {
+ }
+
+
+ //
+ // Overloading "operator,"
+ //
+
+
+ // elt, elt
+
+ next_elt_t_ operator,(T val)
+ {
+ is_true<Info::nplanes == unknown_>::ensure();
+ *ptr = val;
+ return next_elt_t_(ptr + 1, arr);
+ }
+
+
+ // elt, x(elt) -> center
+
+ eat_center_t_ operator,(x_<T> val)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = val.ue; // FIXME : give a *name* to this variable !!
+ return eat_center_t_(ptr + 1, arr);
+ }
+
+
+ // elt, x() -> center
+
+ eat_center_t_ operator,(x_<void>)
+ {
+ is_true<Info::center == unknown_>::ensure();
+ *ptr = T(0);
+ return eat_center_t_(ptr + 1, arr);
+ }
+
+
+ // elt, lbrk
+
+ eat_lbrk_t_ operator,(lbrk_)
+ {
+ is_true<Info::ncols == unknown_>::ensure();
+ return eat_lbrk_t_(ptr, arr);
+ }
+
+
+ // elt, pbrk
+ eat_pbrk_t_ operator,(pbrk_)
+ {
+ is_true<Info::nplanes == unknown_>::ensure();
+ return eat_pbrk_t_(ptr, arr);
+ }
+
+ // elt, end
+
+ array3d_t_ operator,(end_type)
+ {
+ enum { nplanes = (Info::i / (Info::ncols * Info::nrows)) };
+
+ // array is well-formed :
+ is_true<Info::well_formed>::ensure();
+ // centering is automatic or user-defined :
+
+ is_true<Info::ncols != unknown_>::ensure();
+ is_true<Info::nrows != unknown_>::ensure();
+
+ // all of nplanes, nrows and ncols are odd
+ // or the center is user-defined
+
+ is_true<
+ (Info::ncols % 2 == 1 && Info::nrows % 2 == 1 && nplanes % 2 == 1)
+ || (Info::center != unknown_)
+ >::ensure();
+
+ return array3d_t_(arr->ptr);
+ }
+
+
+ // else -> error
+
+ template<class U>
+ void operator,(array3d< Info, U >);
+
+ template<class U>
+ here_a_value_is_not_of_type_<T> operator,(U u) const;
+
+ T* ptr;
+ array3d_start_<T>* arr;
+ };
+
+
+ //
+ // mlc::internal::array3d_start_ impl
+ //
+ ////////////////////////////////////////
+
+ template<class T> inline
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_, 1 >
>
+ array3d_start_<T>::operator=(T val)
+ {
+ ptr[0] = val;
+ return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, unknown_,
1 > >(ptr+1,this);
+ }
+
+ template<class T> inline
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
+ array3d_start_<T>::operator=(x_<T> val)
+ {
+ ptr[0] = val.ue;
+ // center <- 0
+ return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 >
>(ptr+1,this);
+ }
+
+ template<class T> inline
+ array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 > >
+ array3d_start_<T>::operator=(x_<void> val)
+ {
+ ptr[0] = T(0);
+ // center <- 0
+ return array3d_elt_< T, array3d_info< unknown_, unknown_, unknown_, 0, 1 >
>(ptr+1,this);
+ }
+
+ } // end of internal
+
+} // end of mlc
+
+
+#endif // ! METALIC_ARRAY_3D_HXX