https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Start the image traits mechanism.
The big deal of image traits!
* mln/trait/images.hh: Add contents.
* mln/core/concept/image.hh: Include above file.
* tests/trait_images.cc: New.
The "data kind" trait is updated.
* mln/trait/kind.hh: New.
* mln/value/kind.hh: Remove; obsolete.
* mln/core/macros.hh (mln_value_kind): Move to...
* mln/value/props.hh: ...here.
(mln_kind): Remove; too ambiguous.
(<whatever>_kind): Update.
* mln/morpho/min.hh,
* mln/morpho/plus.hh,
* mln/morpho/minus.hh,
* mln/morpho/complementation.hh,
* mln/morpho/dilation.hh,
* mln/morpho/erosion.hh,
* mln/morpho/hit_or_miss.hh,
* mln/value/int_u_sat.hh,
* mln/value/rgb.hh,
* mln/value/rgb8_non_templated.hh,
* mln/value/int_s.hh,
* mln/value/int_u.hh,
* mln/value/label.hh: Update.
Then declare traits for a couple of classes.
* mln/core/image2d_b.hh,
* mln/core/sub_image.hh (image_): New trait.
Misc.
* mln/fun/x2x/translation.hh,
* mln/fun/x2x/rotation.hh: Change layout.
* mln/core/point.hh (point_to_): New in internal.
(operator vec): Use point_to_ to help g++-2.95.
* mln/metal/mat.hh (operator-): Fix sig.
(mult): New; just for the record.
Sort operators.
* mln/metal/bool.hh (to_bool): New; for completion.
* mln/metal/if.hh: Update.
* mln/metal/binary_arith_trait.hh: New overload.
mln/core/concept/image.hh | 1
mln/core/image2d_b.hh | 19 ++++
mln/core/macros.hh | 3
mln/core/point.hh | 22 ++++
mln/core/sub_image.hh | 20 ++++
mln/fun/x2x/rotation.hh | 1
mln/metal/binary_arith_trait.hh | 6 +
mln/metal/bool.hh | 2
mln/metal/if.hh | 2
mln/metal/mat.hh | 124 ++++++++++++++++-----------
mln/morpho/complementation.hh | 4
mln/morpho/dilation.hh | 4
mln/morpho/erosion.hh | 4
mln/morpho/hit_or_miss.hh | 4
mln/morpho/min.hh | 8 -
mln/morpho/minus.hh | 4
mln/morpho/plus.hh | 4
mln/trait/images.hh | 179 ++++++++++++++++++++++++++++++++++++++++
mln/trait/kind.hh | 61 +++++++++++++
mln/value/int_s.hh | 2
mln/value/int_u.hh | 2
mln/value/int_u_sat.hh | 2
mln/value/label.hh | 2
mln/value/props.hh | 35 ++++---
mln/value/rgb.hh | 2
mln/value/rgb8_non_templated.hh | 2
tests/trait_images.cc | 49 ++++++++++
27 files changed, 470 insertions(+), 98 deletions(-)
Index: tests/trait_images.cc
--- tests/trait_images.cc (revision 0)
+++ tests/trait_images.cc (revision 0)
@@ -0,0 +1,49 @@
+// Copyright (C) 2007 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.
+
+/*! \file tests/trait_ch_value.cc
+ *
+ * \brief Tests on mln::trait::ch_value.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/sub_image.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d_b<int> I;
+
+ std::cout << "image2d_b: ";
+ mln::trait::print<I>(std::cout);
+
+ std::cout << std::endl
+ << "sub_image< image2d_b >: ";
+ mln::trait::print< sub_image<I, box2d> >(std::cout);
+}
Index: mln/trait/images.hh
--- mln/trait/images.hh (revision 1198)
+++ mln/trait/images.hh (working copy)
@@ -33,6 +33,17 @@
* \brief Forward declarations of all image types.
*/
+# include <iostream>
+# include <string>
+
+# include <mln/value/props.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/bool.hh>
+
+
+
+# define mln_trait_image_data(I) typename mln::trait::image_< I >::data
+
namespace mln
{
@@ -54,6 +65,174 @@
template <typename T, typename I> class cast_image_;
namespace value { template <unsigned n, typename I> struct stack_image; }
+
+
+ namespace trait
+ {
+
+ struct undef { std::string str() const { return "undef"; } };
+
+
+ template <typename I>
+ struct undefined_image_
+ {
+ // related to I::value
+ typedef undef kind; // color, gray, binary < label, data
+ typedef undef quant; // low or high
+ typedef undef value; // scalar, vectorial, structed
+
+ // related to I::pset
+ typedef undef access; // random, browse
+ typedef undef space; // one_d, two_d, three_d
+ typedef undef size; // huge or regular
+ typedef undef support; // irregular, aligned < regular
+
+ // global
+ typedef undef border; // none, stored, computed
+ typedef undef data; // linear < stored, computed
+ typedef undef io; // read_only < read_write
+ typedef undef speed; // slow, fast, or fastest
+ };
+
+
+ template <typename I>
+ struct image_ : undefined_image_<I>
+ {
+ };
+
+
+ template <typename I>
+ void print(std::ostream& ostr)
+ {
+ typedef image_<I> the;
+ ostr << "{ "
+ << the::data().str() << ", "
+ << the::kind().str() << ", "
+ << the::quant().str() << ", "
+ << the::value().str() << ", "
+ << the::access().str() << ", "
+ << the::space().str() << ", "
+ << the::size().str() << ", "
+ << the::support().str() << ", "
+ << the::border().str() << ", "
+ << the::io().str() << ", "
+ << the::speed().str() << " }" << std::endl;
+ }
+
+
+ struct data
+ {
+ struct computed { std::string str() const { return
"data::computed"; } };
+ struct stored { std::string str() const { return "data::stored";
} };
+ struct linear : stored { std::string str() const { return "data::linear";
} };
+ };
+
+ struct quant
+ {
+ struct low { std::string str() const { return "quant::low"; } };
+ struct high { std::string str() const { return "quant::high"; } };
+ };
+
+ struct value
+ {
+ struct scalar { std::string str() const { return "value::scalar"; }
};
+ struct vectorial { std::string str() const { return "value::vectorial"; }
};
+ struct structed { std::string str() const { return "value::structed"; }
};
+ };
+
+
+ struct access
+ {
+ struct random { std::string str() const { return "access::random"; }
};
+ struct iterative { std::string str() const { return "access::iterative";
} };
+ };
+
+ struct space
+ {
+ struct one_d { std::string str() const { return "space::one_d"; } };
+ struct two_d { std::string str() const { return "space::two_d"; } };
+ struct three_d { std::string str() const { return "space::three_d"; } };
+ };
+
+ struct size
+ {
+ struct huge { std::string str() const { return "size::huge"; } };
+ struct regular { std::string str() const { return "size::regular"; } };
+ };
+
+ struct support
+ {
+ struct irregular { std::string str() const { return
"support::irregular"; } };
+ struct regular { std::string str() const { return
"support::regular"; } };
+ struct aligned : regular { std::string str() const { return
"support::aligned"; } };
+ };
+
+ struct border
+ {
+ struct none { std::string str() const { return "border::none"; } };
+ struct stored { std::string str() const { return "border::stored"; }
};
+ struct computed { std::string str() const { return "border::computed"; }
};
+ };
+
+ struct io
+ {
+ struct read_only { std::string str() const { return "io::read_only"; }
};
+ struct read_write { std::string str() const { return "io::read_write"; }
};
+ };
+
+ struct speed
+ {
+ struct slow { std::string str() const { return "speed::slow"; } };
+ struct fast { std::string str() const { return "speed::fast"; } };
+ struct fastest { std::string str() const { return "speed::fastest"; } };
+ };
+
+
+
+
+ template <typename I>
+ struct default_image_ : undefined_image_<I>
+ {
+ private:
+ typedef mln_value(I) T_;
+ typedef metal::bool_<( mln_value_card_(T_) != 0 )> is_high_quant_;
+ public:
+ typedef mln_value_kind(T_) kind;
+ typedef mlc_if( is_high_quant_, trait::quant::high, trait::quant::low ) quant;
+ // FIXME: typedef undef value; // scalar, vectorial, structed
+ };
+
+
+ template <typename I>
+ struct default_image_morpher_ : default_image_<I>
+ {
+ private:
+ typedef typename I::delegatee D_;
+ public:
+
+ // value-related => delegation
+ typedef typename image_<D_>::kind kind;
+ typedef typename image_<D_>::quant quant;
+ typedef typename image_<D_>::value value;
+
+ // domain-related => delegation
+ typedef typename image_<D_>::access access;
+ typedef typename image_<D_>::space space;
+ typedef typename image_<D_>::size size;
+ typedef typename image_<D_>::support support;
+
+ // mostly global-related => delegation
+ typedef typename image_<D_>::border border;
+ typedef typename image_<D_>::data data;
+ typedef typename image_<D_>::io io;
+
+ // *but* speed is fast by default (not fastest!)
+ typedef trait::speed::fast speed;
+ };
+
+
+ } // end of namespace mln::trait
+
} // end of namespace mln
Index: mln/trait/kind.hh
--- mln/trait/kind.hh (revision 0)
+++ mln/trait/kind.hh (revision 0)
@@ -0,0 +1,61 @@
+// Copyright (C) 2007 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_TRAIT_KIND_HH
+# define MLN_TRAIT_KIND_HH
+
+/*! \file mln/core/trait/kind.hh
+ *
+ * \brief Kind of values in images.
+ */
+
+# include <iostream>
+# include <string>
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ struct kind
+ {
+ struct color { std::string str() const { return "kind::color"; } };
+ struct gray { std::string str() const { return "kind::gray"; } };
+ struct label { std::string str() const { return "kind::label"; } };
+ struct logic : label { std::string str() const { return "kind::logic"; }
};
+ struct binary : logic { std::string str() const { return "kind::binary";
} };
+ struct data { std::string str() const { return "kind::data"; } };
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_KIND_HH
Index: mln/fun/x2x/translation.hh
Index: mln/fun/x2x/rotation.hh
--- mln/fun/x2x/rotation.hh (revision 1198)
+++ mln/fun/x2x/rotation.hh (working copy)
@@ -118,7 +118,6 @@
rotation<n,C>::inv() const
{
typename rotation::invert res(-alpha_, dir_);
-
return res;
}
Index: mln/core/macros.hh
--- mln/core/macros.hh (revision 1198)
+++ mln/core/macros.hh (working copy)
@@ -160,9 +160,6 @@
# define mln_value(T) typename T::value
# define mln_value_(T) T::value
-/// Shortcut to the kind of values for an image with type \c I.
-# define mln_value_kind(I) typename mln::value::props< mln_value(I) >::kind
-
/// Shortcut to test if the values of an image with type \c I are lowly quantifized.
# define mln_is_value_lowq(I) mln_is_lowq( mln_value(I) )
Index: mln/core/point.hh
--- mln/core/point.hh (revision 1198)
+++ mln/core/point.hh (working copy)
@@ -48,6 +48,20 @@
template <typename M, typename C> struct dpoint_;
+ namespace internal
+ {
+
+ template <typename M, typename C>
+ struct point_to_
+ {
+ typedef metal::vec<M::dim, C> metal_vec;
+ typedef h_vec<M::dim, C> h_vec;
+ };
+
+ } // end of namespace mln::internal
+
+
+
/*! \brief Generic point class.
*
* Parameters are \c n the dimension of the space and \c C the
@@ -107,10 +121,10 @@
typedef metal::vec<M::dim, C> vec_t;
/// Hook to coordinates.
- operator metal::vec<M::dim, C>() const;
+ operator typename internal::point_to_<M, C>::metal_vec () const;
/// Hook to homogene coordinate.
- operator h_vec<M::dim, C>() const;
+ operator typename internal::point_to_<M, C>::h_vec () const;
protected:
metal::vec<M::dim, C> coord_;
@@ -172,13 +186,13 @@
}
template <typename M, typename C>
- point_<M,C>::operator metal::vec<M::dim, C>() const
+ point_<M,C>::operator typename internal::point_to_<M, C>::metal_vec ()
const
{
return coord_;
}
template <typename M, typename C>
- point_<M,C>::operator h_vec<M::dim, C>() const
+ point_<M,C>::operator typename internal::point_to_<M, C>::h_vec () const
{
return coord_;
}
Index: mln/core/image2d_b.hh
--- mln/core/image2d_b.hh (revision 1198)
+++ mln/core/image2d_b.hh (working copy)
@@ -208,6 +208,25 @@
void init_(tag::image_t, mln::image2d_b<T>& target, const J& model);
+ namespace trait
+ {
+
+ template <typename T>
+ struct image_< image2d_b<T> > : default_image_< image2d_b<T>
>
+ {
+ typedef trait::access::random access;
+ typedef trait::space::two_d space;
+ typedef trait::size::regular size;
+ typedef trait::support::aligned support;
+
+ typedef trait::border::stored border;
+ typedef trait::data::linear data;
+ typedef trait::io::read_write io;
+ typedef trait::speed::fastest speed;
+ };
+
+ } // end of namespace mln::trait
+
# ifndef MLN_INCLUDE_ONLY
Index: mln/core/sub_image.hh
--- mln/core/sub_image.hh (revision 1198)
+++ mln/core/sub_image.hh (working copy)
@@ -95,6 +95,26 @@
void init_(tag::image_t, sub_image<I,S>& target, const J& model);
+ namespace trait
+ {
+
+ template <typename I, typename S>
+ struct image_< sub_image<I,S> > : default_image_morpher_<
sub_image<I,S> >
+ {
+ private:
+ typedef mln_trait_image_data(I) I_data_;
+ typedef mlc_equal(I_data_, trait::data::linear) I_data_are_linear_;
+ public:
+
+ typedef trait::border::none border; // no more accessible border
+
+ typedef mlc_if( I_data_are_linear_,
+ trait::data::stored, // if linear then just stored
+ I_data_ ) data; // otherwise like I
+ };
+
+ } // end of namespace mln::trait
+
# ifndef MLN_INCLUDE_ONLY
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 1198)
+++ mln/core/concept/image.hh (working copy)
@@ -37,6 +37,7 @@
# include <mln/core/trait/all.hh> // FIXME: Move out of core!
# include <mln/trait/concrete.hh> // FIXME: Should be in all.hh!
+# include <mln/trait/images.hh>
# include <mln/metal/is_a.hh>
# include <mln/tag/init.hh>
Index: mln/metal/mat.hh
--- mln/metal/mat.hh (revision 1198)
+++ mln/metal/mat.hh (working copy)
@@ -75,16 +75,42 @@
T data_[n][m];
};
+ }
+
+
+ namespace trait
+ {
+
+ template <typename L, typename R>
+ struct mult;
+
+
+ template <unsigned n, unsigned o, typename T,
+ unsigned m, typename U>
+ struct mult< metal::mat<n,o,T>, metal::mat<o,m,U> >
+ {
+ typedef metal::mat< n, m, mlc_bin_arith(T,U) > ret;
+ };
+
+ template <unsigned n, unsigned m, typename T,
+ typename U>
+ struct mult< metal::mat<n,m,T>, U >
+ {
+ typedef metal::mat< n, m, mlc_bin_arith(T,U) > ret;
+ };
+
+ }
+
+
+ namespace metal
+ {
+
// eq
template <unsigned n, unsigned m, typename T, typename U>
bool
operator=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
- template <unsigned n, unsigned m, typename T, typename U>
- bool
- operator!=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
-
// +
template <unsigned n, unsigned m, typename T, typename U>
@@ -103,40 +129,46 @@
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- operator-(mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
+ operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs);
template <unsigned n, unsigned m, typename T>
mat<n,m,T>
operator-(const mat<n,m,T>& lhs);
- // *
-
- template <unsigned n, unsigned m, unsigned o, typename T, typename U>
- mat<n,m,T>&
- operator*=(mat<n,o,T>& lhs, mat<o,m,U>& rhs);
+ // Operator *.
- template <unsigned n, unsigned m, unsigned o, typename T, typename U>
+ template <unsigned n, unsigned o, typename T,
+ unsigned m, typename U>
mat<n,m,mlc_bin_arith(T,U)>
operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
+ template <unsigned n, unsigned m, typename T,
+ typename U>
+ mat<n,m,mlc_bin_arith(T,U)>
+ operator*(const mat<n,m,T>& lhs, const U& rhs);
+
+ // *+
+ template <unsigned n, unsigned m, unsigned o, typename T, typename U>
+ mat<n,m,T>&
+ operator*=(mat<n,o,T>& lhs, const mat<o,m,U>& rhs);
+
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,T>&
operator*=(mat<n,m,T>& lhs, const U& rhs);
+ // Operator /.
+
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- operator*(const U& scalar, mat<n,m,T>& lhs);
+ operator/(const mat<n,m,T>& lhs, const U& scalar);
- // /
+ // /
template <unsigned n, unsigned m, typename T, typename U>
- mat<n,m,T>
+ mat<n,m,T>&
operator/=(mat<n,m,T>& lhs, const U& scalar);
- template <unsigned n, unsigned m, typename T, typename U>
- mat<n,m,mlc_bin_arith(T,U)>
- operator/(mat<n,m,T>& lhs, const U& scalar);
-
// <<
template <unsigned n, unsigned m, typename T>
@@ -218,6 +250,7 @@
return n * m;
}
+
// eq
template <unsigned n, unsigned m, typename T, typename U>
@@ -231,14 +264,7 @@
return true;
}
- template <unsigned n, unsigned m, typename T, typename U>
- bool
- operator!=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
- {
- return not (lhs = rhs);
- }
-
- // +
+ // +
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,T>&
@@ -249,9 +275,12 @@
lhs(i, j) += rhs(i, j);
return lhs;
}
+
+ // Operator +.
+
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- operator+(mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
+ operator+(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
{
mat<n,m,mlc_bin_arith(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
@@ -260,7 +289,7 @@
return tmp;
}
- // -
+ // -
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,T>&
@@ -271,9 +300,12 @@
lhs(i, j) -= rhs(i, j);
return lhs;
}
+
+ // Operators -.
+
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- operator-(mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
+ operator-(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs)
{
mat<n,m,mlc_bin_arith(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
@@ -284,12 +316,12 @@
template <unsigned n, unsigned m, typename T>
mat<n,m,T>
- operator-(const mat<n,m,T>& lhs)
+ operator-(const mat<n,m,T>& rhs)
{
mat<n,m,T> tmp;
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; i < m; ++i)
- tmp(i, j) = - lhs(i, j);
+ tmp(i, j) = - rhs(i, j);
return tmp;
}
@@ -297,9 +329,9 @@
template <unsigned n, unsigned m, unsigned o, typename T, typename U>
mat<n,m,T>&
- operator*=(mat<n,o,T>& lhs, mat<o,m,U>& rhs)
+ operator*=(mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
{
- lhs = lhs * rhs;
+ lhs = lhs * rhs; // FIXME: OK?
return lhs;
}
@@ -315,12 +347,10 @@
// Operators *.
- namespace internal
- {
-
- template <unsigned n, unsigned m, unsigned o, typename T, typename U>
+ template <unsigned n, unsigned o, typename T,
+ unsigned m, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- multiply_(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
+ operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs)
{
mat<n,m,mlc_bin_arith(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
@@ -336,7 +366,7 @@
template <unsigned n, unsigned m, typename T,
typename U>
mat<n,m,mlc_bin_arith(T,U)>
- multiply_(mat<n,m,T>& lhs, const U& rhs)
+ operator*(const mat<n,m,T>& lhs, const U& rhs)
{
mat<n,m,mlc_bin_arith(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
@@ -345,20 +375,10 @@
return tmp;
}
- } // end of namespace mln::metal::internal
-
- template <unsigned n, unsigned m, typename T,
- typename U>
- mat<n,m,mlc_bin_arith(T,U)>
- operator*(mat<n,m,T>& lhs, const U& rhs)
- {
- return internal::multiply_(lhs, rhs);
- }
-
// /
template <unsigned n, unsigned m, typename T, typename U>
- mat<n,m,T>
+ mat<n,m,T>&
operator/=(mat<n,m,T>& lhs, const U& scalar)
{
for (unsigned i = 0; i < n; ++i)
@@ -367,9 +387,11 @@
return lhs;
}
+ // Operator /.
+
template <unsigned n, unsigned m, typename T, typename U>
mat<n,m,mlc_bin_arith(T,U)>
- operator/(mat<n,m,T>& lhs, const U& scalar)
+ operator/(const mat<n,m,T>& lhs, const U& scalar)
{
mat<n,m,mlc_bin_arith(T,U)> tmp;
for (unsigned i = 0; i < n; ++i)
Index: mln/metal/bool.hh
--- mln/metal/bool.hh (revision 1198)
+++ mln/metal/bool.hh (working copy)
@@ -55,6 +55,7 @@
{
typedef true_ type;
static const bool value = true;
+ enum { to_bool = true };
};
template <>
@@ -62,6 +63,7 @@
{
typedef false_ type;
static const bool value = false;
+ enum { to_bool = false };
};
Index: mln/metal/if.hh
--- mln/metal/if.hh (revision 1198)
+++ mln/metal/if.hh (working copy)
@@ -71,7 +71,7 @@
* FIXME: Doc!
*/
template <typename Cond, typename Then, typename Else>
- struct if_ : internal::helper_if_< Cond::value, Then, Else >
+ struct if_ : internal::helper_if_< Cond::to_bool, Then, Else >
{
// ret is inherited.
};
Index: mln/metal/binary_arith_trait.hh
--- mln/metal/binary_arith_trait.hh (revision 1198)
+++ mln/metal/binary_arith_trait.hh (working copy)
@@ -43,6 +43,12 @@
struct binary_arith_trait;
+ template <typename T>
+ struct binary_arith_trait< T, T >
+ {
+ typedef T ret;
+ };
+
template <>
struct binary_arith_trait<int, float>
{
Index: mln/morpho/min.hh
--- mln/morpho/min.hh (revision 1198)
+++ mln/morpho/min.hh (working copy)
@@ -60,7 +60,7 @@
{
template <typename I, typename J, typename O>
- void min_(value::binary_kind, // binary => morphology on sets
+ void min_(trait::kind::logic, // binary => morphology on sets
const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
{
@@ -78,7 +78,7 @@
// in place
template <typename I, typename J>
- void min_inplace_(value::binary_kind, // binary => morphology on sets
+ void min_inplace_(trait::kind::logic, // binary => morphology on sets
Image<I>& lhs, const Image<J>& rhs)
{
return logical::and_inplace(lhs, rhs);
@@ -101,14 +101,14 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::min_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+ impl::min_(mln_value_kind(mln_value(I))(), exact(lhs), exact(rhs), output);
}
template <typename I, typename J>
void min_inplace(Image<I>& lhs, const Image<J>& rhs)
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
- impl::min_inplace_(mln_value_kind(I)(), exact(lhs), exact(rhs));
+ impl::min_inplace_(mln_value_kind(mln_value(I))(), exact(lhs), exact(rhs));
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/morpho/plus.hh
--- mln/morpho/plus.hh (revision 1198)
+++ mln/morpho/plus.hh (working copy)
@@ -60,7 +60,7 @@
{
template <typename I, typename J, typename O>
- void plus_(value::binary_kind, // binary => morphology on sets
+ void plus_(trait::kind::logic, // binary => morphology on sets
const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
{
@@ -85,7 +85,7 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::plus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+ impl::plus_(mln_value_kind(mln_value(I))(), exact(lhs), exact(rhs), output);
}
template <typename I, typename J>
Index: mln/morpho/minus.hh
--- mln/morpho/minus.hh (revision 1198)
+++ mln/morpho/minus.hh (working copy)
@@ -60,7 +60,7 @@
{
template <typename I, typename J, typename O>
- void minus_(value::binary_kind, // binary => morphology on sets
+ void minus_(trait::kind::logic, // binary => morphology on sets
const Image<I>& lhs, const Image<J>& rhs,
Image<O>& output)
{
@@ -85,7 +85,7 @@
{
mln_precondition(exact(rhs).domain() = exact(lhs).domain());
mln_precondition(exact(output).domain() = exact(lhs).domain());
- impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output);
+ impl::minus_(mln_value_kind(mln_value(I))(), exact(lhs), exact(rhs), output);
}
template <typename I, typename J>
Index: mln/morpho/complementation.hh
--- mln/morpho/complementation.hh (revision 1198)
+++ mln/morpho/complementation.hh (working copy)
@@ -61,7 +61,7 @@
{
template <typename I, typename O>
- void complementation_(value::binary_kind, // binary => morphology on sets
+ void complementation_(trait::kind::logic, // binary => morphology on sets
const Image<I>& input,
Image<O>& output)
{
@@ -85,7 +85,7 @@
void complementation(const Image<I>& input, Image<O>& output)
{
mln_precondition(exact(output).domain() = exact(input).domain());
- impl::complementation_(mln_value_kind(I)(), exact(input), output);
+ impl::complementation_(mln_value_kind(mln_value(I))(), exact(input), output);
}
template <typename I>
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 1198)
+++ mln/morpho/dilation.hh (working copy)
@@ -112,7 +112,7 @@
// Stage 2: dispatch w.r.t. the value kind.
template <typename I, typename W, typename O>
- void dilation_wrt_value(value::binary_kind, // binary => morphology on sets
+ void dilation_wrt_value(trait::kind::logic, // binary => morphology on sets
const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
return impl::dilation_on_set(exact(input), exact(win), output);
@@ -134,7 +134,7 @@
template <typename I, typename W, typename O>
void dilation_wrt_win(const Image<I>& input, const Window<W>&
win, Image<O>& output)
{
- dilation_wrt_value(mln_value_kind(I)(), exact(input), exact(win), output);
+ dilation_wrt_value(mln_value_kind(mln_value(I))(), exact(input), exact(win), output);
// |
// --> call stage 2: dispatch w.r.t. the value kind
}
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 1198)
+++ mln/morpho/erosion.hh (working copy)
@@ -115,7 +115,7 @@
// Stage 2: dispatch w.r.t. the value kind.
template <typename I, typename W, typename O>
- void erosion_wrt_value(value::binary_kind, // binary => morphology on sets
+ void erosion_wrt_value(trait::kind::logic, // binary => morphology on sets
const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
return impl::erosion_on_set(exact(input), exact(win), output);
@@ -137,7 +137,7 @@
template <typename I, typename W, typename O>
void erosion_wrt_win(const Image<I>& input, const Window<W>&
win, Image<O>& output)
{
- erosion_wrt_value(mln_value_kind(I)(), exact(input), exact(win), output);
+ erosion_wrt_value(mln_value_kind(mln_value(I))(), exact(input), exact(win), output);
// |
// --> call stage 2: dispatch w.r.t. the value kind
}
Index: mln/morpho/hit_or_miss.hh
--- mln/morpho/hit_or_miss.hh (revision 1198)
+++ mln/morpho/hit_or_miss.hh (working copy)
@@ -115,7 +115,7 @@
// On sets.
template <typename I, typename Wh, typename Wm, typename O>
- void hit_or_miss_(value::binary_kind, // binary => morphology on sets
+ void hit_or_miss_(trait::kind::logic, // binary => morphology on sets
const Image<I>& input,
const Window<Wh>& win_hit, const Window<Wm>& win_miss,
Image<O>& output)
@@ -190,7 +190,7 @@
Image<O>& output)
{
impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output);
- impl::hit_or_miss_(mln_value_kind(I)(), input, win_hit, win_miss, output);
+ impl::hit_or_miss_(mln_value_kind(mln_value(I))(), input, win_hit, win_miss,
output);
}
template <typename I, typename Wh, typename Wm, typename O>
Index: mln/value/int_u_sat.hh
--- mln/value/int_u_sat.hh (revision 1198)
+++ mln/value/int_u_sat.hh (working copy)
@@ -102,7 +102,7 @@
static const int_u_sat<n> min() { return 0; }
static const int_u_sat<n> max() { return card_ - 1; }
static const unsigned nbits = n;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
Index: mln/value/props.hh
--- mln/value/props.hh (revision 1198)
+++ mln/value/props.hh (working copy)
@@ -39,7 +39,8 @@
# include <cfloat>
# include <mln/core/macros.hh>
-# include <mln/value/kind.hh>
+# include <mln/trait/kind.hh>
+
# include <mln/metal/bool.hh>
# include <mln/metal/vec.hh>
# include <mln/metal/mat.hh>
@@ -57,9 +58,11 @@
/// Get the number of values for value type \c T.
# define mln_card_(T) mln::value::props< T >::card_
+# define mln_value_card_(T) mln::value::props< T >::card_ // Better than the above
name.
+
/// Get the kind of value type \c T.
-# define mln_kind(T) typename mln::value::props< T >::kind
+# define mln_value_kind(T) typename mln::value::props< T >::kind
/// Test is the value type \c T is low quantized.
@@ -84,7 +87,7 @@
template <typename T>
struct props
{
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
};
@@ -116,7 +119,7 @@
static const bool min() { return false; }
static const bool max() { return true; }
static const std::size_t card_ = 2;
- typedef binary_kind kind;
+ typedef trait::kind::binary kind;
};
@@ -128,7 +131,7 @@
static const unsigned char min() { return 0; }
static const unsigned char max() { return 255; }
static const std::size_t card_ = 256;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
@@ -138,7 +141,7 @@
static const signed char min() { return -128; }
static const signed char max() { return 127; }
static const std::size_t card_ = 256;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
@@ -148,7 +151,7 @@
static const unsigned short min() { return 0; }
static const unsigned short max() { return 65535; }
static const std::size_t card_ = 65536;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
@@ -158,7 +161,7 @@
static const signed short min() { return -32768; }
static const signed short max() { return 32767; }
static const std::size_t card_ = 65536;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
@@ -167,7 +170,7 @@
{
static const unsigned int min() { return 0; }
static const unsigned int max() { return UINT_MAX; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef float sum;
};
@@ -177,7 +180,7 @@
{
static const signed int min() { return INT_MIN; }
static const signed int max() { return INT_MAX; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef float sum;
};
@@ -187,7 +190,7 @@
{
static const unsigned long int min() { return 0; }
static const unsigned long int max() { return ULONG_MAX; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef float sum;
};
@@ -197,7 +200,7 @@
{
static const signed long int min() { return LONG_MIN; }
static const signed long int max() { return LONG_MAX; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef float sum;
};
@@ -211,7 +214,7 @@
static const float min() { return FLT_MIN; }
static const float max() { return FLT_MAX; }
static const float epsilon() { return 0.00001f; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef float sum;
};
@@ -222,7 +225,7 @@
static const double min() { return DBL_MIN; }
static const double max() { return DBL_MAX; }
static const double epsilon() { return 0.0000001; }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = 0;
typedef double sum;
};
@@ -234,7 +237,7 @@
{
static const metal::vec<n,T> min() { return make::vec<n>(mln_min(T)); }
static const metal::vec<n,T> max() { return make::vec<n>(mln_max(T)); }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = n * mln_card_(T);
typedef mlc_bin_arith(float,T) sum;
};
@@ -244,7 +247,7 @@
{
static const metal::mat<n,m,T> min() { return make::mat<n,m>(mln_min(T)); }
static const metal::mat<n,m,T> max() { return make::mat<n,m>(mln_max(T)); }
- typedef data_kind kind;
+ typedef trait::kind::data kind;
static const std::size_t card_ = n * m * mln_card_(T);
typedef mlc_bin_arith(float,T) sum;
};
Index: mln/value/rgb.hh
--- mln/value/rgb.hh (revision 1198)
+++ mln/value/rgb.hh (working copy)
@@ -133,7 +133,7 @@
static const std::size_t card_ = metal::pow<2, nbits>::value;
static const rgb<n> max() { rgb<n> c(props< int_u<n>
>::max); return c; }
static const rgb<n> min() { const rgb<n> c(props< int_u<n>
>::min()); return c; }
- typedef color_kind kind;
+ typedef trait::kind::color kind;
typedef float_x3_t sum;
typedef uchar_x3_t interop;
};
Index: mln/value/rgb8_non_templated.hh
--- mln/value/rgb8_non_templated.hh (revision 1198)
+++ mln/value/rgb8_non_templated.hh (working copy)
@@ -106,7 +106,7 @@
{
static const unsigned nbits = 24;
static const std::size_t card_ = metal::pow<2, nbits>::value;
- typedef color_kind kind;
+ typedef trait::kind::color kind;
typedef float_x3_t sum;
typedef uchar_x3_t interop;
};
Index: mln/value/int_s.hh
--- mln/value/int_s.hh (revision 1198)
+++ mln/value/int_s.hh (working copy)
@@ -105,7 +105,7 @@
static const int_s<n> max() { return metal::pow<2, n-1>::value - 1; }
static const int_s<n> min() { return - max(); }
static const unsigned nbits = n;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
};
Index: mln/value/int_u.hh
--- mln/value/int_u.hh (revision 1198)
+++ mln/value/int_u.hh (working copy)
@@ -101,7 +101,7 @@
static const int_u<n> min() { return 0; }
static const int_u<n> max() { return card_ - 1; }
static const unsigned nbits = n;
- typedef data_kind kind;
+ typedef trait::kind::data kind;
typedef float sum;
typedef int interop;
};
Index: mln/value/label.hh
--- mln/value/label.hh (revision 1198)
+++ mln/value/label.hh (working copy)
@@ -129,7 +129,7 @@
static const label<n> min; // = 0
static const label<n> max; // = card_ - 1
static const unsigned nbits = n;
- typedef label_kind kind;
+ typedef trait::kind::label kind;
};