
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add a label type and labeling. * tests/labeling.cc: New. * tests/label.cc: New. * mln/fun/to_enc.hh: New. * mln/level/to_enc.hh: New. * mln/level/labeling.hh: New. * mln/value/label.hh: New. * img/tiny.pgm: New. * tests/README: Fix missing CR. * doc/Doxyfile.in: Update. * mln/core/trait/is_lowq.hh: Remove. * mln/core/trait/all.hh: Update. * mln/core/macros.hh: Update. * mln/value/set.hh: Update. * mln/core/concept/value.hh (++, --): New. * mln/level/fill.hh (memset): Force cast. * mln/value/lut_vec.hh: Fix warning. * mln/value/props.hh (card, mln_card): Rename as... (card_, mln_card_): ...these. (convert_): New. * mln/value/int_s.hh (+=, -=): New. * mln/value/int_u.hh: Likewise. * mln/value/internal/iterable_set.hh: Use convert_. * mln/value/internal/encoding.hh: Factor names. * mln/value/internal/value_like.hh (to_enc): New. doc/Doxyfile.in | 1 img/tiny.pgm | 4 mln/core/concept/value.hh | 22 +++ mln/core/macros.hh | 2 mln/core/trait/all.hh | 1 mln/fun/to_enc.hh | 71 +++++++++++ mln/level/fill.hh | 2 mln/level/labeling.hh | 175 +++++++++++++++++++++++++++ mln/level/to_enc.hh | 74 +++++++++++ mln/level/transform.hh | 2 mln/value/int_s.hh | 36 ++++- mln/value/int_u.hh | 35 ++++- mln/value/internal/encoding.hh | 32 ++--- mln/value/internal/iterable_set.hh | 8 - mln/value/internal/value_like.hh | 10 + mln/value/label.hh | 236 +++++++++++++++++++++++++++++++++++++ mln/value/lut_vec.hh | 3 mln/value/props.hh | 49 +++++-- mln/value/set.hh | 23 +-- tests/label.cc | 49 +++++++ tests/labeling.cc | 78 ++++++++++++ 21 files changed, 850 insertions(+), 63 deletions(-) Index: tests/labeling.cc --- tests/labeling.cc (revision 0) +++ tests/labeling.cc (revision 0) @@ -0,0 +1,78 @@ +// 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/labeling.cc + * + * \brief Tests on mln::level::labeling. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/neighb2d.hh> + +#include <mln/value/int_u8.hh> +#include <mln/value/label.hh> + +#include <mln/pw/value.hh> +#include <mln/pw/cst.hh> +#include <mln/fun/ops.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> + +#include <mln/level/fill.hh> +#include <mln/level/labeling.hh> +#include <mln/level/to_enc.hh> + + + +int main() +{ + using namespace mln; + using value::int_u8; + using value::label; + + image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm"); + + image2d_b<bool> bin(lena.domain()); + level::fill(bin, pw::value(lena) > pw::cst(127)); + + { + image2d_b<int_u8> lab(lena.domain()); + level::labeling(bin, c4(), lab); + io::save_pgm(lab, "lab.pgm"); + } + + { + image2d_b< label<8> > lab(lena.domain()); + level::labeling(bin, c4(), lab); + + image2d_b< int_u8 > out(lena.domain()); + level::to_enc(lab, out); + io::save_pgm(out, "out.pgm"); + } + +} Index: tests/label.cc --- tests/label.cc (revision 0) +++ tests/label.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/label.cc + * + * \brief Tests on mln::value::label. + */ + +#include <mln/value/int_u8.hh> +#include <mln/value/label.hh> + + + +int main() +{ + using namespace mln; + using value::int_u8; + using value::label; + + int_u8 i = 51; + label<8> l = 50; + ++l; + mln_assertion(l = l); + mln_assertion(i = l.to_enc()); +} Index: tests/README Index: doc/Doxyfile.in --- doc/Doxyfile.in (revision 1038) +++ doc/Doxyfile.in (working copy) @@ -1054,6 +1054,7 @@ "mln_viter(T)=typename T::viter" \ "mln_fwd_viter(T)=typename T::fwd_viter" \ "mln_bkd_viter(T)=typename T::bkd_viter" \ + "mln_enc(T)=typename T::enc" \ "mln_value(T)=typename T::value" \ "mln_qlf_value(T)=typename T::qlf_value" \ "mln_vset(T)=typename T::vset" \ Index: mln/core/macros.hh --- mln/core/macros.hh (revision 1038) +++ mln/core/macros.hh (working copy) @@ -152,7 +152,7 @@ # 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) typename mln::trait::is_lowq< mln_value(I) >::ret +# define mln_is_value_lowq(I) mln_is_lowq( mln_value(I) ) /// Shortcut to access the type of value set (vset) associated to T. # define mln_vset(T) typename T::vset Index: mln/core/trait/all.hh --- mln/core/trait/all.hh (revision 1038) +++ mln/core/trait/all.hh (working copy) @@ -45,7 +45,6 @@ # include <mln/core/trait/is_fast.hh> -# include <mln/core/trait/is_lowq.hh> # include <mln/core/trait/pixter.hh> Index: mln/core/concept/value.hh --- mln/core/concept/value.hh (revision 1038) +++ mln/core/concept/value.hh (working copy) @@ -51,6 +51,12 @@ typedef equiv; // equivalent type */ + /// Pre-incrementation. + E& operator++(); + + /// Pre-decrementation. + E& operator--(); + protected: Value(); }; @@ -65,6 +71,22 @@ typedef mln_equiv(E) equiv; } + template <typename E> + E& + Value<E>::operator++() + { + exact(this)->operator+=(E::one); + return exact(*this); + } + + template <typename E> + E& + Value<E>::operator--() + { + exact(this)->operator-=(E::one); + return exact(*this); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/fun/to_enc.hh --- mln/fun/to_enc.hh (revision 0) +++ mln/fun/to_enc.hh (revision 0) @@ -0,0 +1,71 @@ +// 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_FUN_TO_ENC_HH +# define MLN_FUN_TO_ENC_HH + +/*! \file mln/fun/to_enc.hh + * + * \brief FIXME. + */ + +# include <mln/core/concept/function.hh> + + +namespace mln +{ + + namespace fun + { + + // FIXME: Doc! + + template <typename V> + struct to_enc : public Function_v2v< to_enc<V> > + { + typedef typename V::enc result; + result operator()(const V& v) const; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename V> + typename V::enc + to_enc<V>::operator()(const V& v) const + { + return v.to_enc(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_TO_ENC_HH Index: mln/level/fill.hh --- mln/level/fill.hh (revision 1038) +++ mln/level/fill.hh (working copy) @@ -146,7 +146,7 @@ if (sizeof(mln_value(I)) = 1) { std::memset((void*)(ima.buffer()), - value, + *(const int*)(& value), // violent cast sizeof(mln_value(I)) * ima.ncells()); } else Index: mln/level/to_enc.hh --- mln/level/to_enc.hh (revision 0) +++ mln/level/to_enc.hh (revision 0) @@ -0,0 +1,74 @@ +// 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_LEVEL_TO_ENC_HH +# define MLN_LEVEL_TO_ENC_HH + +/*! \file mln/level/to_enc.hh + * + * \brief Transform with fun::to_enc the contents of an image into + * another one. + */ + +# include <mln/level/transform.hh> +# include <mln/fun/to_enc.hh> + + +namespace mln +{ + + namespace level + { + + /*! Set the \p output image with the encoding values of the image \p input pixels. + * + * \param[in] input The input image. + * \param[out] output The result image. + * + * \pre \p output.domain >= \p input.domain + */ + template <typename I, typename O> + void to_enc(const Image<I>& input, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename O> + void to_enc(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(output).domain() >= exact(input).domain()); + level::transform(input, fun::to_enc< mln_value(I) >(), output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::level + +} // end of namespace mln + + +#endif // ! MLN_LEVEL_TO_ENC_HH Index: mln/level/transform.hh --- mln/level/transform.hh (revision 1038) +++ mln/level/transform.hh (working copy) @@ -80,6 +80,7 @@ output(p) = f( input(p) ); } + template <typename I, typename F, typename O> void transform(metal::true_, // low quantization const Image<I>& input_, const Function_v2v<F>& f_, Image<O>& output_) @@ -94,6 +95,7 @@ output(p) = lut(input(p)); } + // template <typename I, typename F, typename O> // void transform(metal::true_, // low quantization // const Fast_Image<I>& input_, const Function_v2v<F>& f_, Image<O>& output_) Index: mln/level/labeling.hh --- mln/level/labeling.hh (revision 0) +++ mln/level/labeling.hh (revision 0) @@ -0,0 +1,175 @@ +// 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_LEVEL_LABELING_HH +# define MLN_LEVEL_LABELING_HH + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/value/props.hh> +# include <mln/level/fill.hh> + + + +namespace mln +{ + + namespace level + { + + template <typename I, typename N, typename O> + void labeling(const Image<I>& input, const Neighborhood<N>& nbh, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename N, typename O> + struct component_labeling + { + typedef mln_point(I) point; + typedef mln_value(I) value; + + // in: + const I& input; + const N& nbh; + + // out: + O& output; + + // aux: + mln_ch_value(I, point) parent; + mln_ch_value(I, bool) deja_vu; + mln_value(O) current_l; + + component_labeling(const I& input_, const N& nbh_, O& output_) + : // in + input(input_), + nbh(nbh_), + // out + output(output_), + // aux + parent(input.domain()), + deja_vu(input.domain()) + { + } + + void run() + { + // init + { + level::fill(deja_vu, false); + current_l = 0; + level::fill(output, 0); + } + + // first pass + { + mln_bkd_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + if (input(p)) + { + parent(p) = p; + for_all(n) + if (input.has(n) && input(n) && deja_vu(n)) + { + point r = find_root(n); + if (r != p) + parent(r) = p; + } + deja_vu(p) = true; + } + } + + // second pass + { + mln_fwd_piter(I) p(input.domain()); + for_all(p) + if (input(p)) + if (parent(p) = p) + output(p) = ++current_l; + else + output(p) = output(parent(p)); + } + + } + + point find_root(const point& x) + { + if (parent(x) = x) + return x; + else + return parent(x) = find_root(parent(x)); + } + + }; // end of component_labeling + + + + template <typename I, typename N, typename O> + void labeling(value::binary_kind, + const Image<I>& input, const Neighborhood<N>& nbh, Image<O>& output) + { + impl::component_labeling<I,N,O> f(exact(input), exact(nbh), exact(output)); + f.run(); + } + + /* + template <typename K, typename I, typename N, typename O> + void labeling(K, + const Image<I>& input, const Neighborhood<N>& nbh, Image<O>& output) + { + impl::flat_labeling<I,N,O> f(exact(input), exact(nbh), exact(output)); + f.run(); + } + */ + + + } // end of namespace mln::level::impl + + + // facade + + template <typename I, typename N, typename O> + void labeling(const Image<I>& input, const Neighborhood<N>& nbh, Image<O>& output) + { + mln_assertion(exact(output).domain() = exact(input).domain()); + impl::labeling(mln_value_kind(I)(), + exact(input), exact(nbh), exact(output)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::level + +} // end of namespace mln + + +#endif // ! MLN_LEVEL_LABELING_HH Index: mln/value/lut_vec.hh --- mln/value/lut_vec.hh (revision 1038) +++ mln/value/lut_vec.hh (working copy) @@ -131,8 +131,7 @@ T lut_vec<S,T>::operator()(const mln_value(S)& val) const { - unsigned i = vset_.index_of(val); - mln_precondition(i < n_); + mln_precondition(vset_.index_of(val) < n_); return vec_[vset_.index_of(val)]; } Index: mln/value/props.hh --- mln/value/props.hh (revision 1038) +++ mln/value/props.hh (working copy) @@ -38,6 +38,7 @@ # include <mln/core/macros.hh> # include <mln/value/kind.hh> +# include <mln/metal/bool.hh> /// Get the minimum value of type \c T. @@ -49,13 +50,17 @@ /// Get the number of values for value type \c T. -# define mln_card(T) mln::value::props< T >::card +# define mln_card_(T) mln::value::props< T >::card_ /// Get the kind of value type \c T. # define mln_kind(T) typename mln::value::props< T >::kind +/// Test is the value type \c T is low quantized. +# define mln_is_lowq(T) typename metal::bool_<( mln_card_(T) != 0 )>::type + + namespace mln @@ -72,9 +77,27 @@ struct props { typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; + }; + + + namespace internal + { + + template <typename T> + struct convert_ + { + static T value_at_index(std::size_t i) + { + return mln_min(T) + i; + } + static std::size_t index_of_value(const T& v) + { + return v - mln_min(T); + } }; + } // end of namespace mln::value::internal // bool @@ -84,7 +107,7 @@ { static const bool min = false; static const bool max = true; - static const std::size_t card = 2; + static const std::size_t card_ = 2; typedef binary_kind kind; }; @@ -96,7 +119,7 @@ { static const unsigned char min = 0; static const unsigned char max = 255; - static const std::size_t card = 256; + static const std::size_t card_ = 256; typedef data_kind kind; }; @@ -105,7 +128,7 @@ { static const signed char min = -128; static const signed char max = 127; - static const std::size_t card = 256; + static const std::size_t card_ = 256; typedef data_kind kind; }; @@ -114,7 +137,7 @@ { static const unsigned short min = 0; static const unsigned short max = 65535; - static const std::size_t card = 65536; + static const std::size_t card_ = 65536; typedef data_kind kind; }; @@ -123,7 +146,7 @@ { static const signed short min = -32768; static const signed short max = 32767; - static const std::size_t card = 655356; + static const std::size_t card_ = 655356; typedef data_kind kind; }; @@ -133,7 +156,7 @@ static const unsigned int min = 0; static const unsigned int max = UINT_MAX; typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; template <> @@ -142,7 +165,7 @@ static const signed int min = INT_MIN; static const signed int max = INT_MAX; typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; template <> @@ -151,7 +174,7 @@ static const unsigned long int min = 0; static const unsigned long int max = ULONG_MAX; typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; template <> @@ -160,7 +183,7 @@ static const signed long int min = LONG_MIN; static const signed long int max = LONG_MAX; typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; @@ -172,7 +195,7 @@ static const float min() { return FLT_MIN; } static const float max() { return FLT_MAX; } typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; template <> @@ -181,7 +204,7 @@ static const double min() { return DBL_MIN; } static const double max() { return DBL_MAX; } typedef data_kind kind; - static const std::size_t card = 0; + static const std::size_t card_ = 0; }; } // end of namespace mln::value Index: mln/value/set.hh --- mln/value/set.hh (revision 1038) +++ mln/value/set.hh (working copy) @@ -34,7 +34,7 @@ */ # include <mln/value/internal/iterable_set.hh> -# include <mln/core/trait/is_lowq.hh> +# include <mln/value/props.hh> namespace mln @@ -43,26 +43,17 @@ namespace value { - - // Fwd decl. - template <typename T> struct set; - - namespace internal { - template <typename T, typename lowq = metal::false_ > - struct run_set_selector_ // no inheritance + template <typename T, typename E, typename is_lowq = metal::false_> + struct set_selector_ // no inheritance {}; - template <typename T> - struct run_set_selector_< T, metal::true_ > // lowq so iterable + template <typename T, typename E> + struct set_selector_< T, E, metal::true_ > // lowq so iterable : - public iterable_set< T, mln::value::set<T> > - {}; - - template <typename T> - struct set_selector_ : public run_set_selector_< T, mln_is_lowq(T) > + public iterable_set< T, E > {}; } // end of namespace mln::value::internal @@ -74,7 +65,7 @@ * This is the exhaustive set of values obtainable from type \c T. */ template <typename T> - struct set : public internal::set_selector_<T> + struct set : public internal::set_selector_< T, set<T>, mln_is_lowq(T) > { /// Return a singleton. static const set<T>& the(); Index: mln/value/int_s.hh --- mln/value/int_s.hh (revision 1038) +++ mln/value/int_s.hh (working copy) @@ -37,7 +37,6 @@ # include <mln/value/internal/value_like.hh> # include <mln/value/internal/encoding.hh> # include <mln/value/props.hh> -# include <mln/value/set.hh> # include <mln/debug/format.hh> @@ -54,11 +53,11 @@ */ template <unsigned n> struct int_s - : public internal::value_like_< typename internal::encoding_int_s_<n>::ret, + : public internal::value_like_< typename internal::encoding_signed_<n>::ret, int_s<n> > { protected: - typedef internal::value_like_< typename internal::encoding_int_s_<n>::ret, + typedef internal::value_like_< typename internal::encoding_signed_<n>::ret, int_s<n> > super; public: @@ -80,6 +79,12 @@ /// Unit value. static const int_s<n> one; + + /// Self addition. + int_s<n>& operator+=(int i); + + /// Self subtraction. + int_s<n>& operator-=(int i); }; @@ -89,7 +94,7 @@ { static const int_s<n> max; // = 2^(n-1) - 1 static const int_s<n> min; // = - max - static const std::size_t card = metal::pow<2, n>::value; + static const std::size_t card_ = metal::pow<2, n>::value; static const unsigned nbits = n; typedef data_kind kind; }; @@ -128,12 +133,33 @@ } template <unsigned n> - int_s<n> int_s<n>::operator-() const + int_s<n> + int_s<n>::operator-() const { return - this->v_; } template <unsigned n> + int_s<n>& + int_s<n>::operator+=(int i) + { + mln_precondition(long(this->v_) + i >= mln_min(enc)); + mln_precondition(long(this->v_) + i <= mln_max(enc)); + this->v_ += i; + return *this; + } + + template <unsigned n> + int_s<n>& + int_s<n>::operator-=(int i) + { + mln_precondition(long(this->v_) - i >= mln_min(enc)); + mln_precondition(long(this->v_) - i <= mln_max(enc)); + this->v_ -= i; + return *this; + } + + template <unsigned n> const int_s<n> int_s<n>::zero = 0; template <unsigned n> Index: mln/value/int_u.hh --- mln/value/int_u.hh (revision 1038) +++ mln/value/int_u.hh (working copy) @@ -37,7 +37,6 @@ # include <mln/value/internal/value_like.hh> # include <mln/value/internal/encoding.hh> # include <mln/value/props.hh> -# include <mln/value/set.hh> # include <mln/debug/format.hh> @@ -54,11 +53,11 @@ */ template <unsigned n> struct int_u - : public internal::value_like_< typename internal::encoding_int_u_<n>::ret, + : public internal::value_like_< typename internal::encoding_unsigned_<n>::ret, int_u<n> > { protected: - typedef internal::value_like_< typename internal::encoding_int_u_<n>::ret, + typedef internal::value_like_< typename internal::encoding_unsigned_<n>::ret, int_u<n> > super; public: @@ -77,6 +76,12 @@ /// Unit value. static const int_u<n> one; + + /// Self addition. + int_u<n>& operator+=(int i); + + /// Self subtraction. + int_u<n>& operator-=(int i); }; @@ -89,9 +94,9 @@ template <unsigned n> struct props< int_u<n> > { - static const std::size_t card = metal::pow<2, n>::value; + static const std::size_t card_ = metal::pow<2, n>::value; static const int_u<n> min; // = 0 - static const int_u<n> max; // = card - 1 + static const int_u<n> max; // = card_ - 1 static const unsigned nbits = n; typedef data_kind kind; }; @@ -125,6 +130,26 @@ } template <unsigned n> + int_u<n>& + int_u<n>::operator+=(int i) + { + mln_precondition(long(this->v_) + i >= 0); + mln_precondition(long(this->v_) + i <= mln_max(enc)); + this->v_ += i; + return *this; + } + + template <unsigned n> + int_u<n>& + int_u<n>::operator-=(int i) + { + mln_precondition(long(this->v_) - i >= 0); + mln_precondition(long(this->v_) - i <= mln_max(enc)); + this->v_ -= i; + return *this; + } + + template <unsigned n> const int_u<n> int_u<n>::zero = 0; template <unsigned n> Index: mln/value/internal/iterable_set.hh --- mln/value/internal/iterable_set.hh (revision 1038) +++ mln/value/internal/iterable_set.hh (working copy) @@ -96,21 +96,23 @@ iterable_set<T,E>::operator[](std::size_t i) const { mln_precondition(i < nvalues()); - return mln_min(T) + i; + return mln::value::internal::convert_<T>::value_at_index(i); + // FIXME: Was: mln_min(T) + i; } template <typename T, typename E> std::size_t iterable_set<T,E>::index_of(const T& v) const { - return v - mln_min(T); + return mln::value::internal::convert_<T>::index_of_value(v); + // FIXME: Was: v - mln_min(T); } template <typename T, typename E> std::size_t iterable_set<T,E>::nvalues() const { - return mln_card(T); + return mln_card_(T); } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/internal/encoding.hh --- mln/value/internal/encoding.hh (revision 1038) +++ mln/value/internal/encoding.hh (working copy) @@ -43,36 +43,36 @@ namespace internal { - template <unsigned n> struct encoding_int_u_; + template <unsigned n> struct encoding_unsigned_; - template <> struct encoding_int_u_<8> { typedef unsigned char ret; }; - template <> struct encoding_int_u_<16> { typedef unsigned short ret; }; - template <> struct encoding_int_u_<32> { typedef unsigned int ret; }; // FIXME!!! - template <> struct encoding_int_u_<64> { typedef unsigned long ret; }; // FIXME!!! + template <> struct encoding_unsigned_<8> { typedef unsigned char ret; }; + template <> struct encoding_unsigned_<16> { typedef unsigned short ret; }; + template <> struct encoding_unsigned_<32> { typedef unsigned int ret; }; // FIXME!!! + template <> struct encoding_unsigned_<64> { typedef unsigned long ret; }; // FIXME!!! - template <> struct encoding_int_u_<99> { typedef void ret; }; // stopper + template <> struct encoding_unsigned_<99> { typedef void ret; }; // stopper template <unsigned n> - struct encoding_int_u_ + struct encoding_unsigned_ { - typedef typename encoding_int_u_<n+1>::ret ret; + typedef typename encoding_unsigned_<n+1>::ret ret; }; - template <unsigned n> struct encoding_int_s_; + template <unsigned n> struct encoding_signed_; - template <> struct encoding_int_s_<8> { typedef signed char ret; }; - template <> struct encoding_int_s_<16> { typedef signed short ret; }; - template <> struct encoding_int_s_<32> { typedef signed int ret; }; // FIXME!!! - template <> struct encoding_int_s_<64> { typedef signed long ret; }; // FIXME!!! + template <> struct encoding_signed_<8> { typedef signed char ret; }; + template <> struct encoding_signed_<16> { typedef signed short ret; }; + template <> struct encoding_signed_<32> { typedef signed int ret; }; // FIXME!!! + template <> struct encoding_signed_<64> { typedef signed long ret; }; // FIXME!!! - template <> struct encoding_int_s_<99> { typedef void ret; }; // stopper + template <> struct encoding_signed_<99> { typedef void ret; }; // stopper template <unsigned n> - struct encoding_int_s_ + struct encoding_signed_ { - typedef typename encoding_int_s_<n+1>::ret ret; + typedef typename encoding_signed_<n+1>::ret ret; }; Index: mln/value/internal/value_like.hh --- mln/value/internal/value_like.hh (revision 1038) +++ mln/value/internal/value_like.hh (working copy) @@ -70,6 +70,9 @@ /// Explicit convertion towards equivalent type. V to_equiv() const; + /// Explicit convertion towards encoding type. + V to_enc() const; + /// Assignment from equivalent type. E& operator=(const V& v); @@ -112,6 +115,13 @@ } template <typename V, typename E> + V + value_like_<V, E>::to_enc() const + { + return v_; + } + + template <typename V, typename E> E& value_like_<V, E>::operator=(const V& v) { Index: mln/value/label.hh --- mln/value/label.hh (revision 0) +++ mln/value/label.hh (revision 0) @@ -0,0 +1,236 @@ +// 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_VALUE_LABEL_HH +# define MLN_VALUE_LABEL_HH + +/*! \file mln/value/label.hh + * + * \brief Define a generic class for labels. + */ + +# include <mln/metal/math.hh> +# include <mln/value/internal/value_like.hh> +# include <mln/value/internal/encoding.hh> +# include <mln/value/props.hh> + + +namespace mln +{ + + namespace value + { + + + + /*! \brief Label value class. + * + * The parameter \c n is the number of encoding bits. + */ + template <unsigned n> + struct label + { + public: + + /// Encoding associated type. + typedef typename internal::encoding_unsigned_<n>::ret enc; + + /// Constructor without argument. + label(); + + /// Constructor from an (unsigned) integer. + label(unsigned i); + + /// Assignment from an (unsigned) integer. + label<n>& operator=(unsigned i); + + /// Self increment. + label<n>& operator++(); + + /// Self decrement. + label<n>& operator--(); + + /// Convertion to unsigned. + const enc& to_enc() const; + + /// Unit value. + static const label<n> one; + + protected: + + enc v_; + }; + + + namespace internal + { + + template <unsigned n> + struct convert_< label<n> > + { + static label<n> value_at_index(std::size_t i) + { + return i; + } + static std::size_t index_of_value(const label<n>& v) + { + return v.to_enc(); + } + }; + + } // end of mln::value::internal + + + + // Safety. + template <> struct label<0>; + template <> struct label<1>; + + + /// Equality comparison. + template <unsigned n> + bool operator=(const label<n>& lhs, const label<n>& rhs); + + /// Ordering comparison. + template <unsigned n> + bool operator<(const label<n>& lhs, const label<n>& rhs); + + + + + template <unsigned n> + struct props< label<n> > + { + static const std::size_t card_ = metal::pow<2, n>::value; + static const label<n> min; // = 0 + static const label<n> max; // = card_ - 1 + static const unsigned nbits = n; + typedef label_kind kind; + }; + + + + + + + + /*! \brief Print a label \p l into the output stream \p ostr. + * + * \param[in,out] ostr An output stream. + * \param[in] l A label. + * + * \return The modified output stream \p ostr. + */ + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const label<n>& l); + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n> + label<n>::label() + { + } + + template <unsigned n> + label<n>::label(unsigned i) + { + mln_precondition(i <= mln_max(enc)); + v_ = enc(i); + } + + template <unsigned n> + label<n>& + label<n>::operator=(unsigned i) + { + mln_precondition(i <= mln_max(enc)); + v_ = enc(i); + return *this; + } + + template <unsigned n> + label<n>& + label<n>::operator++() + { + mln_precondition(v_ < mln_max(enc)); + ++v_; + return *this; + } + + template <unsigned n> + label<n>& + label<n>::operator--() + { + mln_precondition(v_ != 0); + --v_; + return *this; + } + + template <unsigned n> + const label<n> label<n>::one = 1; + + template <unsigned n> + const mln_enc(label<n>)& + label<n>::to_enc() const + { + return v_; + } + + template <unsigned n> + bool operator=(const label<n>& lhs, const label<n>& rhs) + { + return lhs.to_enc() = rhs.to_enc(); + } + + template <unsigned n> + bool operator<(const label<n>& lhs, const label<n>& rhs) + { + return lhs.to_enc() < rhs.to_enc(); + } + + template <unsigned n> + const label<n> + props< label<n> >::min = 0; + + template <unsigned n> + const label<n> + props< label<n> >::max = metal::pow<2, n>::value - 1; + + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const label<n>& i) + { + return ostr << i.to_enc(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_LABEL_HH Index: img/tiny.pgm --- img/tiny.pgm (revision 0) +++ img/tiny.pgm (revision 0) @@ -0,0 +1,4 @@ +P5 +64 64 +255 +©¥`fijjqy~ ~ynw°×ºqtyyy{{||{~¡¨¡~^chhhpy}zpoÉÒnvyyz{~~^9¤¤^cighpx| {sk~ ¬Ö¿vrxy{\3/£¥~\chghox|~|~~~~~|ulzÂÙpxy{Z2.3£¦¢}[bgfgowz}~}zzzy}~~~{uny£ÕÎpy}Y0332¢£|Ybgfgowz|}~}|~~~ztnw½Ý®otX/171- ¥¢~X`ggipx{}~¥¯®¤{}}|ysmuÑ×T./54/-¥¢¤ }T\bdhovy{|~¡©°¶¼¾¦wyyupju²á¥0.521//©ex ¤|QYacfkruy{|wyz©±·»ÀĶmprmhsµY*24102-¡zUy ¦zP[ccekqtxyxou{¤²¸½ÀÁÅÆ¦ohifr~~R+120257Q`Vz ¦yR[bdekquy{xnrwx{¢´¸·¿ÉÎÒÚ¦_bbqsXc+04013@YjXYy¦xS\bdekrvyyoousvª²ÂÍÌËÍÓÖV[ov<f{6/4131<]YZZx¥yR[cceksv{soqsv~ ÁÈÇÇÉÌÏÓÏPjw6C|F*53124OZ[Zx£zRYadekru jmpsz®¾¾¾ÃÊËÌÍÎÔÓvax9+Rb-26331>|¢ZZWv£{PW_bejm~gnqv |¯¶¶¸ÀÄÅÇÉÊÍÏ×·cx8*g¼Î½D.65344l[][u¥yNVacdilemrz}~{ª«¯³º¼½ÀÄÇÉÉÌÎÒp<z½ÑÖÙ_-4013W`b`w§¡|QZceflndksy{~{ £¬²´µ²·¿ÂľÇÊÌÅÄÎÍÎØd/2.09ccbz©¥~S[cedim¥fhnvy{¢««®«¯³µ»¼·ºÃÂÂù¿ÉÌËËÒÑS00/6ecbcz¬¨RZbccfp±nipv{§§§«®¬±µ³¸»¹µµ²º½ÆÉÉÇÊÃо<0/1Pa`ay¬§S[bbcds³}imv¤¨¨©¦¦¬±µ²¯«·ÀÅÆÆÇÊÁ©º/1.:u`_`{ «§T\bacasµmp £§¨¨¥¥®¹ÁÃÂÃÈÊÌ©\-11Zaad~ «¨QZaab_u¿§z{¡±¾Â¾ÁÅÉÌϹ8/3<|ccg¢¬©PYacc_o°}uy {h[m^ZDB±¿ÃÂÁÅÈË»qlh,0/Rgdg¡«¨QYaccad¸·r~ucOG_VT@:v¨»À½¿ÁÅ» ri£f1018s¡ iff ª¨RX`bbc_Á~}}z~zhOA4KKTFO·µµ·¾¼qx£¬g/511K¤¢ jgcz «© PW`aaeey¾ª|{|}wXNÈ@=KXx®½´±¯¶½«^dy¡\.35/5d££¢¡jg`u¬ªPU`abgle¬·u{~uZDM:H>36Jl¶±®°½Á¾{QlS*482/Bx¥£¢¡ hf_t¬ªQWbdchpi¦§qvyvQ>1@DDO,?t¯´¦ª©ºÆÈÊ?Q?/7:0/Z¢¡¡¡ge`s¬ªTYdfdmupq|oK:;45=LK;|¦ ¯¯£¢±ÁÈÍÒJ8E4:807tfc^r«U[dgfmtt{ }{O=4?95:?Cs²ª¬¤¡©³ÁÇÌÓÀb0rN6<51J¡ec_r¬TYeffltqh`BD6?37A:\¨²® ¬±»ÁÆÍ¸`+f[;<33e¡ee_p®UZeediyn[cKGI8:72=K´¯¢wl`¤³¿¸lT0\f<92<wcaYl¯¬TXcc_~|KGQU<>3B32{®ÀP>BTSz¯ÀyMD<0Wm>41Ib^Sg°®U\dcU§|E?CI_5690/T»nFMc«os¶©Qfi0.VsC21ae_Qe±±[bm^fIPDDWmD,1,7³©~v¦|¹^;3T{B0:v¦³bYK_²³Zal{\<FeDB\lL-..a¦©r²ÂkK3O>/E¤º¾½XRD[±±YawjLEc[2:XX\7+D¯dk¦«ªÈ£}R7I:.X¤Á¾ÁNJ@Y¯¯Ybrl\PKcI10:8lM)etBs ¯¨£É¢~L7B@3m½ÂÃÇÊLI;U¬¬Vj{`bRSkP3,DQxR:7Fo£¨£|É¢y?;<J;²ÂÃËÎÌOI8Q®YjrW\OUiT3/KcM4nN/OmÆi2>6{WJÁÂÊÎÎÏOJ?]¬¯\aiTWPPfh;<7O3S§o,6Xoyp¯ M0@4oebÄÈÎÏÐÏLJFpª¯X]nKOJMdtNW9Uyy~84:`r~©°t75G7`qz·ÆÎÎÐÑÑGEDr«°WcoRP>GRboKNnF199^qµ¿®U/:I8R}½ÌÐÏÐÒÒ=@Dq¡±^ijGC?WXTd]¦xP44<9Th~{{y91=I:IÄÐÐÐÒÔÔ8<Ft¡°±ihjF8Eh^^[|l613;;J]v}w{V/1=J@FÍÒÒÓÔÓÑ56Gq°²XmWN9Jug`oA545;<DNgt v505=NDHÔÕÖÕÑÏÏ11Rt®°WcPD9CntljnQ164369:@Og{M/67@RGIØÖÕÓÑÑÑ/0Ov¯TWFD;=bWuyy^63:54269=<Dcy¡¦¡~9595EVLM~ªÙÓÕÓͼ0,Am¬pa?B;5nZ^uqK2@6423::BOduW;74GXPT{}~¹ÖÑÑÇO:O99Vª¬kQ2A=DXigjkovB>842288Bl~¨¿½\0FUNXztopsuv½ÐÐÉD;NjHFª¬vD)JJSC\`Yr~eX<86468?@iz«»ÃËÅEJGW {oenkºÒÍIHUVjF¬¡}41?EC@IHOnjkD8969;PCiz¨²ºÃÍÒ??Yx{ÊÔ¶WQ]c\TJ¯¯i,558I4@JR`{{a[39398_Ie¢«³¾ÉÒÔm0\ ~§ÔÒU`had6E°°d/3.BL3:AYYuyYe55<eMg§±»ÇÐÙ²2a¬Ê×Âq]jc`f, E°±Y1./QD514IZu{`:;55OuTl £¹ÅÎÔÓUg }ÐÓÕ¢bcl`ea(~K¯®Z..7A?607?R|j`SOJ7:ezUs ©µÂÌÒÙ p }ÑÔÈ ffcabZ&rS¯°^.386:63:ESoeW8;?4GruX~¥°¾ÈÐÖ±»Ó´tc^[c^]$g\¯f2428<72:LPLPj;1.4Yxca¡«¹ÅÏÔÎbq£Ód\U`_^R#a¦e«°b5.58;8/4KmTP?0,+EmoMu§³ÁÌÒ×STQQ^·ÈsMT\^_]@Fl¬t¬²]2234:;016Yw^2,)4]qO]¢®¼ÈÐרbdU?-x¹ÃGGX^UdV<[}«¬³X0232;@8:>DdR/*,H\OU{ ¨´ÃÍÔÁigbUFÁN@R_N[hPAGm¤ ¬µH/587?FQ?BJfM-+1DQfz¥°½ÈÑÐx^gfgzWKP`ONlcE<7V¬µ<<B@]JFGTO.1Kfs{¢¬·ÂÍÓYiruoggZZPKepR:91M·¯«´:1:BBODUSL?BRBDarx}¡¨³¿ÉÒ«[cs{w|oZUQ]y`:9Q \ No newline at end of file