
* mln/core/image/vmorph/thru_image.hh, * mln/fun/component/blue.hh, * mln/fun/component/green.hh, * mln/fun/component/red.hh, * mln/fun/component/rgb.hh, * mln/fun/param.hh, * mln/fun/spe/unary.hh, * mln/fun/unary.hh, * mln/trait/functions.hh, * mln/trait/next/solve.hh, * mln/trait/next/solve_binary.hh, * mln/trait/next/solve_proxy.hh, * mln/trait/next/solve_unary.hh: New. * headers.mk, * tests/unit_test/unit-tests.mk: Regen. --- milena/ChangeLog | 22 ++ milena/headers.mk | 13 + milena/mln/core/image/vmorph/thru_image.hh | 319 ++++++++++++++++++++++++++ milena/mln/fun/component/blue.hh | 81 +++++++ milena/mln/fun/component/green.hh | 81 +++++++ milena/mln/fun/component/red.hh | 81 +++++++ milena/mln/fun/component/rgb.hh | 37 +++ milena/mln/fun/param.hh | 86 +++++++ milena/mln/fun/spe/unary.hh | 334 ++++++++++++++++++++++++++++ milena/mln/fun/unary.hh | 175 +++++++++++++++ milena/mln/trait/functions.hh | 251 +++++++++++++++++++++ milena/mln/trait/next/solve.hh | 146 ++++++++++++ milena/mln/trait/next/solve_binary.hh | 300 +++++++++++++++++++++++++ milena/mln/trait/next/solve_proxy.hh | 98 ++++++++ milena/mln/trait/next/solve_unary.hh | 170 ++++++++++++++ milena/tests/unit_test/unit-tests.mk | 26 +++ 16 files changed, 2220 insertions(+), 0 deletions(-) create mode 100644 milena/mln/core/image/vmorph/thru_image.hh create mode 100644 milena/mln/fun/component/blue.hh create mode 100644 milena/mln/fun/component/green.hh create mode 100644 milena/mln/fun/component/red.hh create mode 100644 milena/mln/fun/component/rgb.hh create mode 100644 milena/mln/fun/param.hh create mode 100644 milena/mln/fun/spe/unary.hh create mode 100644 milena/mln/fun/unary.hh create mode 100644 milena/mln/trait/functions.hh create mode 100644 milena/mln/trait/next/solve.hh create mode 100644 milena/mln/trait/next/solve_binary.hh create mode 100644 milena/mln/trait/next/solve_proxy.hh create mode 100644 milena/mln/trait/next/solve_unary.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 894d261..6ce0fe2 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,25 @@ +2012-10-08 Roland Levillain <roland@lrde.epita.fr> + + Revive headers required by the RGB component functors. + + * mln/core/image/vmorph/thru_image.hh, + * mln/fun/component/blue.hh, + * mln/fun/component/green.hh, + * mln/fun/component/red.hh, + * mln/fun/component/rgb.hh, + * mln/fun/param.hh, + * mln/fun/spe/unary.hh, + * mln/fun/unary.hh, + * mln/trait/functions.hh, + * mln/trait/next/solve.hh, + * mln/trait/next/solve_binary.hh, + * mln/trait/next/solve_proxy.hh, + * mln/trait/next/solve_unary.hh: + New. + * headers.mk, + * tests/unit_test/unit-tests.mk: + Regen. + 2012-10-05 Roland Levillain <roland@lrde.epita.fr> Provide typedefs mln::value::int_s24 and mln::value::int_u24. diff --git a/milena/headers.mk b/milena/headers.mk index 20f2f35..dbd26e9 100644 --- a/milena/headers.mk +++ b/milena/headers.mk @@ -313,6 +313,7 @@ mln/core/image/vertex_image.hh \ mln/core/image/vmorph/all.hh \ mln/core/image/vmorph/cast_image.hh \ mln/core/image/vmorph/fun_image.hh \ +mln/core/image/vmorph/thru_image.hh \ mln/core/image/vmorph/violent_cast_image.hh \ mln/core/internal/box_impl.hh \ mln/core/internal/check/image_all.hh \ @@ -507,6 +508,10 @@ mln/extension/fill.hh \ mln/fun/all.hh \ mln/fun/c.hh \ mln/fun/cast.hh \ +mln/fun/component/blue.hh \ +mln/fun/component/green.hh \ +mln/fun/component/red.hh \ +mln/fun/component/rgb.hh \ mln/fun/essential.hh \ mln/fun/i2v/all.hh \ mln/fun/i2v/all_to.hh \ @@ -537,8 +542,11 @@ mln/fun/p2v/elifs.hh \ mln/fun/p2v/essential.hh \ mln/fun/p2v/iota.hh \ mln/fun/p2v/ternary.hh \ +mln/fun/param.hh \ +mln/fun/spe/unary.hh \ mln/fun/stat/all.hh \ mln/fun/stat/mahalanobis.hh \ +mln/fun/unary.hh \ mln/fun/v2b/all.hh \ mln/fun/v2b/essential.hh \ mln/fun/v2b/lnot.hh \ @@ -1063,11 +1071,16 @@ mln/trait/ch_function_value.hh \ mln/trait/ch_value.hh \ mln/trait/concrete.hh \ mln/trait/essential.hh \ +mln/trait/functions.hh \ mln/trait/image/print.hh \ mln/trait/image/props.hh \ mln/trait/image_from_grid.hh \ mln/trait/images.hh \ mln/trait/neighborhood.hh \ +mln/trait/next/solve.hh \ +mln/trait/next/solve_binary.hh \ +mln/trait/next/solve_proxy.hh \ +mln/trait/next/solve_unary.hh \ mln/trait/op/all.hh \ mln/trait/op/and.hh \ mln/trait/op/decl.hh \ diff --git a/milena/mln/core/image/vmorph/thru_image.hh b/milena/mln/core/image/vmorph/thru_image.hh new file mode 100644 index 0000000..e829b27 --- /dev/null +++ b/milena/mln/core/image/vmorph/thru_image.hh @@ -0,0 +1,319 @@ +// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development +// Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_CORE_IMAGE_VMORPH_THRU_IMAGE_HH +# define MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH + +/// \file +/// +/// \brief Definition of a morpher that morph image values through a function. +/// +/// \todo Debug constness of thru_image + +# include <mln/core/internal/image_value_morpher.hh> +# include <mln/core/concept/meta_function.hh> +# include <mln/metal/bexpr.hh> +# include <mln/trait/functions.hh> + + +namespace mln +{ + + // Forward declaration. + template <typename I, typename F> class thru_image; + + namespace internal + { + template <typename I, typename F> class thru_image_write; + template <typename I, typename F> class thru_image_read; + + /// Find correct implementation + template <typename I, typename F> + struct thru_find_impl + { + typedef thru_image_write<I, F> write; + typedef thru_image_read<I, F> read; + typedef mlc_if(mlc_and(mln_trait_fun_is_assignable(F), + mlc_and(mlc_not(mlc_is_const(I)), + mlc_equal(mln_trait_image_pw_io(I), + trait::image::pw_io::read_write))), + write, read) ret; + }; + + /// Data structure for \c mln::thru_image<I>. + template <typename I, typename F> + struct data< thru_image<I, F> > + { + data(I& ima, const F& f); + + I ima_; + F f_; + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename I, typename F> + struct image_< thru_image<I, F> > : image_< typename mln::internal::thru_find_impl<I, F>::ret > // Same as I except... + { + // ...these changes. + typedef trait::image::category::value_morpher category; + typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest. + typedef trait::image::value_access::computed value_access; + }; + + template <typename I, typename F> + struct image_< mln::internal::thru_image_write<I, F> > : image_< I > // Same as I except... + { + typedef trait::image::vw_io::read_write vw_io; + }; + + template <typename I, typename F> + struct image_< mln::internal::thru_image_read<I, F> > : image_< I > // Same as I except... + { + typedef trait::image::vw_io::read vw_io; + }; + + } // end of namespace mln::trait + + + + // FIXME: Doc! + + namespace internal + { + + template <typename I, typename F> + class thru_image_read : public internal::image_value_morpher< I, typename F::result, thru_image<I,F> > + { + public: + + /// Skeleton. + typedef thru_image<tag::image_<I>, F> skeleton; + + /// Point_Site associated type. + typedef mln_psite(I) psite; + + /// Value associated type. + typedef mln_result(F) value; + + /// Return type of read-only access. + typedef value rvalue; + typedef value lvalue; // Workaround for write operator() + + rvalue operator()(const mln_psite(I)& p) const; + rvalue operator()(const mln_psite(I)& p); + + }; + + // Inheritance from read ?! + template <typename I, typename F> + class thru_image_write : public thru_image_read<I,F> + { + public: + + /// Type returned by the read-write pixel value operator. +// typedef typename F::template lresult<typename F::argument>::ret lvalue; + typedef typename F::lresult lvalue; + + using thru_image_read<I,F>::operator(); + lvalue operator()(const mln_psite(I)& p); + + }; + } + + /// Morph image values through a function. + /// + /// \ingroup modimagevaluemorpher + // + template <typename I, typename F> + class thru_image : public internal::thru_find_impl<I, F>::ret + { + public: + + thru_image(); + thru_image(I& ima); + thru_image(I& ima, const F& f); + + void init_(I& ima, const F& f); + + /// Const promotion via conversion. + operator thru_image<const I, F>() const; + }; + + template <typename I, typename F> + thru_image<I, F> thru(const mln::Function<F>& f, + Image<I>& ima); + + template <typename I, typename F> + const thru_image<const I, F> thru(const mln::Function<F>& f, + const Image<I>& ima); + + template <typename I, typename M> + thru_image<I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, Image<I>& ima); + + template <typename I, typename M> + const thru_image<const I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, const Image<I>& ima); + +# ifndef MLN_INCLUDE_ONLY + + // internal::data< thru_image<I,S> > + + namespace internal + { + + template <typename I, typename F> + inline + data< thru_image<I, F> >::data(I& ima, const F& f) + : ima_(ima), + f_(f) + { + } + + } // end of namespace mln::internal + + // thru_image<I> + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image() + { + } + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image(I& ima, const F& f) + { + mln_precondition(ima.is_valid()); + init_(ima, f); + } + + template <typename I, typename F> + inline + thru_image<I, F>::thru_image(I& ima) + { + mln_precondition(ima.is_valid()); + init_(ima, F()); + } + + template <typename I, typename F> + inline + void + thru_image<I, F>::init_(I& ima, const F& f) + { + mln_precondition(! this->is_valid()); + mln_precondition(ima.is_valid()); + this->data_ = new internal::data< thru_image<I, F> >(ima, f); + } + + template <typename I, typename F> + inline + thru_image<I, F>::operator thru_image<const I, F>() const + { + thru_image<const I, F> tmp(this->data_->ima_, this->data_->f_); + return tmp; + } + + namespace internal + { + + template <typename I, typename F> + inline + typename thru_image_read<I, F>::rvalue + thru_image_read<I, F>::operator()(const mln_psite(I)& p) const + { + mln_precondition(this->is_valid()); + return this->data_->f_(this->data_->ima_(p)); + } + + template <typename I, typename F> + inline + typename thru_image_read<I, F>::rvalue + thru_image_read<I, F>::operator()(const mln_psite(I)& p) + { + mln_precondition(this->is_valid()); + return this->data_->f_(this->data_->ima_(p)); + } + + template <typename I, typename F> + inline + typename thru_image_write<I, F>::lvalue + thru_image_write<I, F>::operator()(const mln_psite(I)& p) + { + mln_precondition(this->is_valid()); + return this->data_->f_(this->data_->ima_(p)); + } + + } + + // thru + template <typename I, typename F> + thru_image<I, F> thru(const mln::Function<F>& f, + Image<I>& ima) + { + thru_image<I, F> tmp(exact(ima), exact(f)); + return tmp; + } + + template <typename I, typename F> + thru_image<const I, F> thru(const mln::Function<F>& f, + const Image<I>& ima) + { + thru_image<const I, F> tmp(exact(ima), exact(f)); + return tmp; + } + + template <typename I, typename M> + thru_image<I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, Image<I>& ima) + { + typedef mln_fun_with(M, mln_value(I)) F; + thru_image<I, F> tmp(exact(ima), F(exact(f).state())); + + return tmp; + } + + template <typename I, typename M> + thru_image<const I, mln_fun_with(M, mln_value(I))> + thru(const mln::Meta_Function<M>& f, const Image<I>& ima) + { + typedef mln_fun_with(M, mln_value(I)) F; + thru_image<const I, F> tmp(exact(ima), F(exact(f).state())); + + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_IMAGE_VMORPH_THRU_IMAGE_HH diff --git a/milena/mln/fun/component/blue.hh b/milena/mln/fun/component/blue.hh new file mode 100644 index 0000000..3796be1 --- /dev/null +++ b/milena/mln/fun/component/blue.hh @@ -0,0 +1,81 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_COMPONENT_BLUE_HH +# define MLN_FUN_COMPONENT_BLUE_HH + +/// \file +/// +/// Meta function to retrieve/modify the blue component. + +# include <mln/fun/unary.hh> +# include <mln/value/rgb.hh> + +namespace mln +{ + + namespace fun + { + + struct blue : unary<blue> {}; + + } // end of namespace mln::fun + +# ifndef MLN_INCLUDE_ONLY + + namespace trait + { + + namespace next + { + + template <unsigned n> + struct set_precise_unary_<mln::fun::blue, mln::value::rgb<n> > + { + typedef set_precise_unary_ ret; + typedef mln::value::rgb<n> argument; + typedef typename argument::blue_t result; + typedef argument& lvalue; + + static result read(const argument& x) + { + return x.blue(); + } + + static void write(lvalue l, const result& r) + { + l.blue() = r; + } + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_FUN_COMPONENT_BLUE_HH diff --git a/milena/mln/fun/component/green.hh b/milena/mln/fun/component/green.hh new file mode 100644 index 0000000..63c5f9e --- /dev/null +++ b/milena/mln/fun/component/green.hh @@ -0,0 +1,81 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_COMPONENT_GREEN_HH +# define MLN_FUN_COMPONENT_GREEN_HH + +/// \file +/// +/// Meta function to retrieve/modify the green component. + +# include <mln/fun/unary.hh> +# include <mln/value/rgb.hh> + +namespace mln +{ + + namespace fun + { + + struct green : unary<green> {}; + + } // end of namespace mln::fun + +# ifndef MLN_INCLUDE_ONLY + + namespace trait + { + + namespace next + { + + template <unsigned n> + struct set_precise_unary_<mln::fun::green, mln::value::rgb<n> > + { + typedef set_precise_unary_ ret; + typedef mln::value::rgb<n> argument; + typedef typename argument::green_t result; + typedef argument& lvalue; + + static result read(const argument& x) + { + return x.green(); + } + + static void write(lvalue l, const result& r) + { + l.green() = r; + } + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_FUN_COMPONENT_GREEN_HH diff --git a/milena/mln/fun/component/red.hh b/milena/mln/fun/component/red.hh new file mode 100644 index 0000000..3b40bc4 --- /dev/null +++ b/milena/mln/fun/component/red.hh @@ -0,0 +1,81 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_COMPONENT_RED_HH +# define MLN_FUN_COMPONENT_RED_HH + +/// \file +/// +/// Meta function to retrieve/modify the red component. + +# include <mln/fun/unary.hh> +# include <mln/value/rgb.hh> + +namespace mln +{ + + namespace fun + { + + struct red : unary<red> {}; + + } // end of namespace mln::fun + +# ifndef MLN_INCLUDE_ONLY + + namespace trait + { + + namespace next + { + + template <unsigned n> + struct set_precise_unary_<mln::fun::red, mln::value::rgb<n> > + { + typedef set_precise_unary_ ret; + typedef mln::value::rgb<n> argument; + typedef typename argument::red_t result; + typedef argument& lvalue; + + static result read(const argument& x) + { + return x.red(); + } + + static void write(lvalue l, const result& r) + { + l.red() = r; + } + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + +#endif // ! MLN_FUN_COMPONENT_RED_HH diff --git a/milena/mln/fun/component/rgb.hh b/milena/mln/fun/component/rgb.hh new file mode 100644 index 0000000..2a365d1 --- /dev/null +++ b/milena/mln/fun/component/rgb.hh @@ -0,0 +1,37 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_COMPONENT_RGB_HH +# define MLN_FUN_COMPONENT_RGB_HH + +/// \file +/// +/// Meta functions to retrieve/modify rgb components. + +# include <mln/fun/component/red.hh> +# include <mln/fun/component/green.hh> +# include <mln/fun/component/blue.hh> + +#endif // ! MLN_FUN_COMPONENT_RGB_HH diff --git a/milena/mln/fun/param.hh b/milena/mln/fun/param.hh new file mode 100644 index 0000000..edeab7d --- /dev/null +++ b/milena/mln/fun/param.hh @@ -0,0 +1,86 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_PARAM_HH +# define MLN_FUN_PARAM_HH + +namespace mln +{ + + namespace fun + { + + template <typename T> + struct stored + { + typedef T value; + + const T& to_value() const + { + return t_; + } + + T& to_value() + { + return t_; + } + + operator const T& () const + { + return to_value(); + } + + operator T& () + { + return to_value(); + } + + stored& operator = (const T& t) + { + t_ = t; + return *this; + } + + protected: + T t_; + }; + + template <> + struct stored<void> + { + }; + + template <typename F> + struct parameter + { + typedef void param; + typedef void storage; + }; + + } // end of namespace mln::fun + +} // end of namespace mln + +#endif // ! MLN_FUN_PARAM_HH diff --git a/milena/mln/fun/spe/unary.hh b/milena/mln/fun/spe/unary.hh new file mode 100644 index 0000000..47d7f41 --- /dev/null +++ b/milena/mln/fun/spe/unary.hh @@ -0,0 +1,334 @@ +// Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development +// Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_SPE_UNARY_HH +# define MLN_FUN_SPE_UNARY_HH + +# include <mln/core/concept/function.hh> +# include <mln/trait/next/solve.hh> +# include <mln/trait/functions.hh> + +namespace mln +{ + + namespace fun + { + + namespace spe + { + + // Wrapper for bijective functions + template <typename Fun, typename T> + struct lwrapper + { + typedef typename Fun::result result; + typedef typename Fun::argument argument; + typedef typename Fun::lvalue lvalue; + typedef lwrapper lresult; + + lwrapper(const Fun& f, T& x) + : x_(&x), f_(&f) + { + } + + result to_result() const + { + return (*f_)(*const_cast<const T*>(x_)); + }; + + operator result() const + { + return to_result(); + }; + + const result& operator = (const result& r) const + { + argument x(*x_); + f_->set(x, r); + *x_ = x; + + return r; + } + + private: + T *x_; + const Fun *f_; + }; + + template <typename Fun> + struct lwrapper<Fun, typename Fun::argument> + { + typedef typename Fun::result result; + typedef typename Fun::argument argument; + typedef typename Fun::lvalue lvalue; + typedef lwrapper lresult; + + lwrapper(const Fun& f, argument& x) + : x_(&x), f_(&f) + { + } + + result to_result() const + { + return (*f_)(*const_cast<const argument*>(x_)); + }; + + operator result() const + { + return to_result(); + }; + + const result& operator = (const result& r) const + { + f_->set(*x_, r); + + return r; + } + + private: + argument *x_; + const Fun *f_; + }; + + template <typename Fun, typename Any, typename T> + struct lwrapper<Fun, lwrapper<Any, T> > + { + typedef typename Fun::result result; + typedef typename Fun::argument argument; + typedef typename Fun::lvalue lvalue; + typedef lwrapper lresult; + + lwrapper(const Fun& f, const lwrapper<Any, T>& m) + : m_(m), f_(&f) + { + } + + result to_result() const + { + return (*f_)(m_.to_result()); + }; + + operator result() const + { + return to_result(); + }; + + const result& operator = (const result& r) const + { + argument m(m_); + f_->set(m, r); + m_ = m; + + return r; + } + + private: + const lwrapper<Any, T> m_; + const Fun *f_; + }; + + template <typename Fun, typename T> + struct unary; + + namespace impl + { + + template <bool param, bool set, typename Fun, typename T> + struct unary_impl; + + template <typename Fun, typename T> + struct unary_impl<false, false, Fun, T> : Function_v2v< unary<Fun, T> > + { + typedef Fun flag; + typedef mln_trait_nunary(Fun, T) def; + + typedef typename def::argument argument; + typedef typename def::result result; + + result operator () (const argument& value) const + { + return def::read(value); + } + + template <typename U> + void init(const U& value) + { + (void) value; + }; + + }; + + template <typename Fun, typename T> + struct unary_impl<false, true, Fun, T> : unary_impl<false, false, Fun, T> + { + typedef unary_impl<false, false, Fun, T> super; + typedef typename super::def::lvalue lvalue; + + template <typename U> + struct lresult_with + { + typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret; + }; + + typedef typename lresult_with<typename super::argument>::ret lresult; + + void set(lvalue l, const typename super::result& r) const + { + super::def::write(l, r); + } + + using super::operator (); + + lresult apply_rw(typename super::argument& value) const + { + return lresult(exact(*this), value); + } + + template <typename U> + typename lresult_with<U>::ret apply_rw(U& value) const + { + return typename lresult_with<U>::ret(exact(*this), value); + } + + lresult operator () (typename super::argument& value) const + { + return apply_rw(value); + } + }; + + template <typename Fun, typename T> + struct unary_impl<true, false, Fun, T> : Function_v2v< unary<Fun, T> > + { + typedef Fun flag; + typedef mln_trait_nunary(Fun, T) def; + + typedef typename def::argument argument; + typedef typename def::result result; + + typedef mln_trait_fun_param(unary_impl) param; + typedef mln_trait_fun_storage(unary_impl) storage; + + result operator () (const argument& value) const + { + return def::read(this->state_, value); + } + + template <typename U> + void init(const U& value) + { + state_ = mln::trait::function::internal::introspect::has_storage_t<def, void>::compute(value); + }; + + stored<storage>& state() + { + return state_; + } + + const stored<storage>& state() const + { + return state_; + } + + protected: + stored<storage> state_; + }; + + template <typename Fun, typename T> + struct unary_impl<true, true, Fun, T> : unary_impl<true, false, Fun, T> + { + typedef unary_impl<true, false, Fun, T> super; + typedef typename super::def::lvalue lvalue; + + template <typename U> + struct lresult_with + { + typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret; + }; + + typedef typename lresult_with<typename super::argument>::ret lresult; + + void set(lvalue l, const typename super::result& r) const + { + super::def::write(this->state(), l, r); + } + + using super::operator (); + + lresult apply_rw(typename super::argument& value) const + { + return lresult(exact(*this), value); + } + + template <typename U> + typename lresult_with<U>::ret apply_rw(U& value) const + { + return typename lresult_with<U>::ret(exact(*this), value); + } + + lresult operator () (typename super::argument& value) const + { + return apply_rw(value); + } + }; + + } // end of namespace mln::fun::spe::impl + + template <typename Fun, typename T> + struct unary + : impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(mln_trait_nunary(Fun, T)), mln_trait_fun_is_parametrable(Fun))::value, + mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value, Fun, T> + { + typedef mln_trait_nunary(Fun, T) def; + typedef impl::unary_impl<mlc_or(mln_trait_fun_is_parametrable(def), mln_trait_fun_is_parametrable(Fun))::value, + mln_trait_fun_is_assignable_(def)::value, + Fun, + T> + super; + + unary() {} + + template <typename U> + unary(const U& param) + { + this->init(param); + } + + using super::operator(); + }; + + } // end of namespace mln::fun::spe + + } // end of namespace mln::fun + +} // end of namespace mln + +template <typename F, typename T> +std::ostream& operator << (std::ostream& o, const mln::fun::spe::lwrapper<F, T>& m) +{ + return o << m.to_result(); +} + +#endif // ! MLN_FUN_SPE_UNARY_HH diff --git a/milena/mln/fun/unary.hh b/milena/mln/fun/unary.hh new file mode 100644 index 0000000..1e1ee2b --- /dev/null +++ b/milena/mln/fun/unary.hh @@ -0,0 +1,175 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_UNARY_HH +# define MLN_FUN_UNARY_HH + +# include <mln/core/concept/meta_function.hh> +# include <mln/fun/spe/unary.hh> +# include <mln/trait/next/solve.hh> + + +namespace mln +{ + + namespace fun + { + + // Forward declarations, for composition with unary::operator()(Fun) + struct compose; + + namespace internal + { + + template <typename U> + struct unary_with {}; + + } + + template <typename F, typename E = F> + struct unary: mln::Meta_Function_v2v< E > + { + typedef F flag; + typedef mln_trait_fun_param(flag) param; + typedef mln_trait_fun_storage(flag) storage; + + template <typename T> + struct with { + typedef mln_trait_nunary(internal::unary_with<F>, T) def; + typedef typename def::ret ret; + }; + + template <typename T> + typename with<T>::ret::result operator()(const T& v) const + { + return with<T>::def::call(exact(*this), v); + } + + template <typename T> + typename with<T>::ret::template lresult_with<T>::ret operator()(T& v) const + { + // See the commentary in next method. + typedef typename with<T>::ret fun_t; + fun_t f(state()); + return f.apply_rw(v); + } + + template <typename T, typename R> + void set(T& v, const R& r) const + { + // Decomposing "with<T>::ret(state()).set(v, r)" into 3 lines + // helps g++-3.3! + typedef typename with<T>::ret fun_t; + fun_t f(state()); + f.set(v, r); + } + + template <typename U> + void init(const U& value) + { + state_ = mln::trait::function::internal::introspect::has_storage_t<flag, void>::compute(value); + }; + + unary() + { + } + + template <typename U> + unary(const U& param) + { + this->init(param); + } + + stored<storage>& state() + { + return state_; + } + + const stored<storage>& state() const + { + return state_; + } + + protected: + stored<storage> state_; + }; + + } // end of namespace mln::fun + + namespace trait + { + + namespace next + { + + // Any type + template <typename F, typename T> + struct set_unary_< mln::fun::internal::unary_with<F>, mln::Object, T> + { + struct ret_t + { + typedef mln::fun::spe::unary<F, T> ret; + + static typename ret::result call(const F& f, const T& v) + { + return ret(f.state())(v); + } + }; + + typedef ret_t ret; + }; + + // Meta Function + template <typename F, typename G> + struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function, G> + { + // FIXME: Workaround for cyclic references (unary -> unary_with -> compose -> unary) + template <typename T> + struct identity + { + typedef T ret; + }; + + struct ret_t + { + typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret ret; + + static typename ret::result call(const F& f, const G& g) + { + return ret()(f, g); + } + + }; + + typedef ret_t ret; + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +} // end of namespace mln + +#endif // ! MLN_FUN_UNARY_HH diff --git a/milena/mln/trait/functions.hh b/milena/mln/trait/functions.hh new file mode 100644 index 0000000..01b8330 --- /dev/null +++ b/milena/mln/trait/functions.hh @@ -0,0 +1,251 @@ +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_FUNCTIONS_HH +# define MLN_TRAIT_FUNCTIONS_HH + +# include <mln/metal/bexpr.hh> +# include <mln/metal/if.hh> +# include <mln/fun/param.hh> +# include <mln/trait/next/solve.hh> + +# define mln_trait_fun_is_assignable(Fun) typename mln::trait::function::is_assignable< Fun >::ret +# define mln_trait_fun_is_assignable_(Fun) mln::trait::function::is_assignable< Fun >::ret +# define mln_trait_fun_is_assignable__1comma(A, B) typename mln::trait::function::is_assignable< A, B >::ret +# define mln_trait_fun_is_assignable__1comma_(A, B) mln::trait::function::is_assignable< A, B >::ret + +# define mln_trait_fun_is_parametrable(Fun) typename mln::trait::function::is_parametrable< Fun >::ret +# define mln_trait_fun_is_parametrable_(Fun) mln::trait::function::is_parametrable< Fun >::ret + +# define mln_trait_fun_lvalue(Fun) typename mln::trait::function::get_lvalue< Fun >::ret +# define mln_trait_fun_param(Fun) typename mln::trait::function::get_param< Fun >::ret +# define mln_trait_fun_storage(Fun) typename mln::trait::function::get_storage< Fun >::ret + +namespace mln +{ + + namespace trait + { + + namespace function + { + + namespace internal + { + + namespace introspect + { + + template <typename T> + struct except_void_t + { + typedef void ret; + }; + + template <> + struct except_void_t<void>; + + // Lvalue solver + + template <typename T, typename V> + struct has_lvalue_t + { + typedef metal::false_ ret; + typedef void type; + }; + + template <typename T> + struct has_lvalue_t<T, typename except_void_t<typename T::lvalue>::ret> + { + typedef metal::true_ ret; + typedef typename T::lvalue type; + }; + + // Parameter solver + template <typename T, typename V> + struct param_solver; + + template <typename T, typename V> + struct param_flag_solver + { + typedef typename mln::fun::parameter<T> ret; + }; + + template <typename T> + struct param_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::param>::ret> + { + typedef mln::fun::parameter<typename T::flag> ret; + }; + + template <typename T, typename V> + struct param_def_solver + { + typedef typename param_flag_solver<T, V>::ret ret; + }; + + template <typename T> + struct param_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::param>::ret> + { + typedef mln::fun::parameter<typename T::def> ret; + }; + + template <typename T, typename V> + struct param_solver : param_def_solver<T, V> + { + }; + + template <typename T> + struct param_solver<T, typename except_void_t<typename T::param>::ret> + { + typedef T ret; + }; + + template <typename T, typename V> + struct has_param_t + { + typedef metal::false_ ret; + typedef void type; + }; + + template <typename T> + struct has_param_t<T, typename except_void_t<typename param_solver<T,void>::ret::param>::ret> + { + typedef metal::true_ ret; + typedef typename param_solver<T,void>::ret::param type; + }; + + template <typename T, typename V> + struct storage_solver; + + template <typename T, typename V> + struct storage_flag_solver + { + typedef typename mln::fun::parameter<T> ret; + }; + + template <typename T> + struct storage_flag_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::flag>::storage>::ret> + { + typedef mln::fun::parameter<typename T::flag> ret; + }; + + template <typename T, typename V> + struct storage_def_solver + { + typedef typename storage_flag_solver<T, V>::ret ret; + }; + + template <typename T> + struct storage_def_solver<T, typename except_void_t<typename mln::fun::parameter<typename T::def>::storage>::ret> + { + typedef mln::fun::parameter<typename T::def> ret; + }; + + template <typename T, typename V> + struct storage_solver : storage_def_solver<T, V> + { + }; + + template <typename T> + struct storage_solver<T, typename except_void_t<typename T::storage>::ret> + { + typedef T ret; + }; + + template <typename T, typename V> + struct has_storage_t + { + typedef has_param_t<T, V> has_param; + + typedef metal::false_ ret; + typedef typename has_param::type type; + + template <typename U> + static inline + const U& compute(const U& t) + { + return t; + } + + }; + + template <typename T> + struct has_storage_t<T, typename except_void_t<typename param_solver<T,void>::ret::storage>::ret> + { + typedef metal::true_ ret; + typedef typename param_solver<T,void>::ret def; + + typedef typename def::storage type; + + template <typename U> + static inline + type compute(const U& p) + { + return def::compute(p); + } + + }; + + } // end of namespace mln::trait::fun::internal::introspect + + } // end of namespace mln::trait::fun::internal + + template <typename F> + struct is_assignable + { + typedef typename internal::introspect::has_lvalue_t<F, void>::ret ret; + }; + + template <typename F> + struct is_parametrable + { + typedef typename internal::introspect::has_param_t<F, void>::ret ret; + }; + + template <typename F> + struct get_lvalue + { + typedef typename internal::introspect::has_lvalue_t<F, void>::type ret; + }; + + template <typename F> + struct get_param + { + typedef typename internal::introspect::has_param_t<F, void>::type ret; + }; + + template <typename F> + struct get_storage + { + typedef typename internal::introspect::has_storage_t<F, void>::type ret; + }; + + } // end of namespace mln::trait::fun + + } // end of namespace mln::trait + +} // end of namespace mln + +#endif // ! MLN_TRAIT_FUNCTIONS_HH diff --git a/milena/mln/trait/next/solve.hh b/milena/mln/trait/next/solve.hh new file mode 100644 index 0000000..747bdaa --- /dev/null +++ b/milena/mln/trait/next/solve.hh @@ -0,0 +1,146 @@ +// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_NEXT_SOLVE_HH +# define MLN_TRAIT_NEXT_SOLVE_HH + +/// \file +/// +/// FIXME + +# include <mln/core/category.hh> +# include <mln/metal/equal.hh> +# include <mln/metal/if.hh> +# include <mln/metal/ret.hh> +# include <mln/trait/solve.hh> + + +// FIXME: Just for the record (use it...) + +# ifndef MLN_DEBUG_TRAITS +# endif // ! MLN_DEBUG_TRAITS + + +# define mln_trait_nunary(Name, T) typename mln::trait::next::solve_unary< Name, T >::ret +# define mln_trait_nunary_(Name, T) mln::trait::next::solve_unary< Name, T >::ret + +# define mln_trait_nbinary(Name, T1, T2) typename mln::trait::next::solve_binary< Name, T1, T2 >::ret +# define mln_trait_nbinary_(Name, T1, T2) mln::trait::next::solve_binary< Name, T1, T2 >::ret + + + +namespace mln +{ + + namespace trait + { + + namespace next + { + + // Unary case. + + + template < typename Name, + typename T > + struct set_precise_unary_ + { + typedef undefined ret; + }; + + + template < typename Name, + template <class> class Category_T, typename T > + struct set_unary_ + { + typedef undefined ret; + }; + + template < typename Name, + typename T > + struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance. + { + typedef not_found ret; + }; + + + + + // Binary case. + + + template < typename Name, + typename L, + typename R > + struct set_precise_binary_ + { + typedef undefined ret; + }; + + + template < typename Name, + template <class> class Category_L, typename L, + template <class> class Category_R, typename R > + struct set_binary_ + { + typedef undefined ret; + }; + + template < typename Name, + typename L, + template <class> class Category_R, typename R > + struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker. + { + typedef not_found ret; + }; + + template < typename Name, + template <class> class Category_L, typename L, + typename R > + struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker. + { + typedef not_found ret; + }; + + template < typename Name, + typename L, + typename R > + struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker. + { + typedef not_found ret; + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +} // end of namespace mln + + +# include <mln/trait/next/solve_unary.hh> +# include <mln/trait/next/solve_binary.hh> +# include <mln/trait/next/solve_proxy.hh> + +#endif // ! MLN_TRAIT_NEXT_SOLVE_HH diff --git a/milena/mln/trait/next/solve_binary.hh b/milena/mln/trait/next/solve_binary.hh new file mode 100644 index 0000000..0eccf26 --- /dev/null +++ b/milena/mln/trait/next/solve_binary.hh @@ -0,0 +1,300 @@ +// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_NEXT_SOLVE_BINARY_HH +# define MLN_TRAIT_NEXT_SOLVE_BINARY_HH + +/// \file +/// +/// FIXME + +# include <mln/core/category.hh> +# include <mln/core/routine/exact.hh> +# include <mln/metal/equal.hh> +# include <mln/metal/if.hh> +# include <mln/metal/ret.hh> +# include <mln/trait/next/solve.hh> + + +// FIXME: Just for the record (use it...) + +# ifndef MLN_DEBUG_TRAITS +# endif // ! MLN_DEBUG_TRAITS + + + +namespace mln +{ + + namespace trait + { + + namespace next + { + + namespace internal + { + + + template < typename Name, + typename Category_L, typename L, + typename Category_R, typename R > + struct trait_set_binary_; + + template < typename Name, + template <class> class Category_L, typename _l, typename L, + template <class> class Category_R, typename _r, typename R > + struct trait_set_binary_< Name, + Category_L<_l>, L, + Category_R<_r>, R > + { + typedef typename mln::trait::next::set_binary_<Name, + Category_L, L, + Category_R, R>::ret ret; + }; + + + // triplet_ret_ + + template < unsigned i_L_, unsigned i_R_, typename ret_ > + struct triplet_ + { + typedef ret_ ret; + }; + + + // merge_triplets_ + + template < typename L_trp, typename R_trp > + struct merge_triplets_; + + template < unsigned L_i_L, unsigned L_i_R, typename L_ret, + unsigned R_i_L, unsigned R_i_R, typename R_ret > + struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>, + triplet_<R_i_L, R_i_R, R_ret> > + { + typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L; + typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R; + typedef metal::or_<take_L, take_R> ok; + typedef typename metal::if_< metal::and_<ok, take_L>, + triplet_<L_i_L, L_i_R, L_ret>, + typename metal::if_< metal::and_<ok, take_R>, + triplet_<R_i_L, R_i_R, R_ret>, + triplet_<0,0, not_found> >::ret >::ret ret; + }; + + template < unsigned i_L, unsigned i_R, typename LR_ret > + struct merge_triplets_< triplet_<i_L, i_R, LR_ret>, + triplet_<i_L, i_R, LR_ret> > + { + typedef triplet_<i_L, i_R, LR_ret> ret; + }; + + + template < unsigned L_i_L, unsigned L_i_R, unsigned L_i_max, + unsigned R_i_L, unsigned R_i_R, unsigned R_i_max > + // L_i_max and R_i_max differ + struct helper_merge_triplets_same_ret_ + { + // The winning couple between L_* and R_* is the one which + // maximum index is the smallest; for instance, with: + // left branch giving L_i_L = 5 and L_i_R = 1 so L_i_max = 5 + // right branch giving L_i_L = 3 and L_i_R = 4 so R_i_max = 4 + // the right branch wins. + enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L), + i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) }; + }; + + template < unsigned L_i_L, unsigned L_i_R, unsigned i_max, + unsigned R_i_L, unsigned R_i_R > + // L_i_max is equal to R_i_max + struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max, + R_i_L, R_i_R, i_max > + { + // The winning couple is the one with the minimum index. + enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R), + R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R), + i_L = (L_i_min < R_i_min ? L_i_L : R_i_L), + i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) }; + }; + + + template < unsigned L_i_L, unsigned L_i_R, typename LR_ret, + unsigned R_i_L, unsigned R_i_R > + struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>, + triplet_<R_i_L, R_i_R, LR_ret> > + { + typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L : L_i_R), + R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper; + typedef triplet_<helper::i_L, helper::i_R, LR_ret> ret; + }; + + template < unsigned L_i_L, unsigned L_i_R, typename L_ret > + struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>, + triplet_< 0, 0, not_found> > + { + typedef triplet_<L_i_L, L_i_R, L_ret> ret; + }; + + template < unsigned R_i_L, unsigned R_i_R, typename R_ret > + struct merge_triplets_< triplet_< 0, 0, not_found>, + triplet_<R_i_L, R_i_R, R_ret> > + { + typedef triplet_<R_i_L, R_i_R, R_ret> ret; + }; + + template <> // To disambiguate. + struct merge_triplets_< triplet_<0, 0, not_found>, + triplet_<0, 0, not_found> > + { + typedef triplet_<0u,0u, not_found> ret; + }; + + + + // Fwd decl. + template < typename Name, + unsigned i_L, typename Category_L, typename L, + unsigned i_R, typename Category_R, typename R > + struct get_binary_; + + + template < typename user_ret, /* != not_found and != undefined */ + typename Name, + unsigned i_L, typename Category_L, typename L, + unsigned i_R, typename Category_R, typename R > + struct helper_get_binary_ + { + typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined 'ret' so we return it. + }; + + template < typename Name, + unsigned i_L, typename Category_L, typename L, + unsigned i_R, typename Category_R, typename R > + struct helper_get_binary_< /* user_ret == */ not_found, + Name, i_L, Category_L, L, i_R, Category_R, R > + { + typedef triplet_< 0, 0, not_found > ret; // End of search due to a blocker; 'ret' is not found. + }; + + + template < typename Name, + unsigned i_L, typename Category_L, typename L, + unsigned i_R, typename Category_R, typename R > + struct helper_get_binary_< /* user_ret == */ undefined, + Name, i_L,Category_L, L, i_R,Category_R, R > + { + // No user definition for 'ret' so treillis construction in a static recursive way. + + // FIXME: We *do* need to handle this search with a priority! + // FIXME: for a result can be found in both branches... + + typedef typename mln::internal::super_category_< Category_L, L >::ret Super_Category_L; + typedef typename mln::internal::super_category_< Category_R, R >::ret Super_Category_R; + + typedef get_binary_< Name, + i_L + 1, Super_Category_L, L, + i_R, Category_R, R > L_branch; + typedef mlc_ret(L_branch) L_trp; + + typedef get_binary_< Name, + i_L, Category_L, L, + i_R + 1, Super_Category_R, R > R_branch; + typedef mlc_ret(R_branch) R_trp; + + typedef typename merge_triplets_< L_trp, R_trp >::ret ret; + }; + + + template < typename Name, + unsigned i_L, typename Category_L, typename L, + unsigned i_R, typename Category_R, typename R > + struct get_binary_ + { + typedef typename trait_set_binary_<Name, Category_L,L, + Category_R,R>::ret user_ret; // First get 'user_ret' + typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L, + i_R,Category_R,R> helper; // Set the helper to make a decision. + typedef mlc_ret(helper) ret; // Return a triplet. + }; + + + template < typename precise_ret, + typename Name, + typename Category_L, typename L, + typename Category_R, typename R > + struct helper_choose_binary_wrt_ /* precise_ret != undefined */ + { + typedef precise_ret ret; // -> A precise ret has been defined so it is it. + }; + + template < typename Name, + typename Category_L, typename L, + typename Category_R, typename R > + struct helper_choose_binary_wrt_< /* precise_ret == */ undefined, + Name, Category_L, L, Category_R, R > + { + typedef typename get_binary_< Name, + 0, Category_L, L, + 0, Category_R, R >::ret triplet; // Browse upwards the category inheritance + typedef mlc_ret(triplet) ret; // to fetch ret from 'get_binary_'s. + }; + + + template < typename Name, + typename Category_L, typename L, + typename Category_R, typename R > + struct helper_solve_binary_ + { + typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined or not (?) */ + typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R> helper; + typedef mlc_ret(helper) ret; + }; + + } // end of namespace mln::trait::internal + + + // FIXME: Postfix solve_binary with a '-'(?) + template < typename Name, + typename L_, + typename R_ > + struct solve_binary + { + typedef mln_exact(L_) L; + typedef mln_exact(R_) R; + typedef typename mln::category<L>::ret Category_L; + typedef typename mln::category<R>::ret Category_R; + typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R > meta_code; + typedef typename meta_code::ret ret; + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_NEXT_SOLVE_BINARY_HH diff --git a/milena/mln/trait/next/solve_proxy.hh b/milena/mln/trait/next/solve_proxy.hh new file mode 100644 index 0000000..c2e2dc1 --- /dev/null +++ b/milena/mln/trait/next/solve_proxy.hh @@ -0,0 +1,98 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_NEXT_SOLVE_PROXY_HH +# define MLN_TRAIT_NEXT_SOLVE_PROXY_HH + +/// \file +/// +/// Proxy support for "next" trait solver. + + +# include <mln/core/concept/object.hh> +# include <mln/core/concept/proxy.hh> +# include <mln/core/concept/proxy.hxx> + +# include <mln/trait/next/solve.hh> + +namespace mln +{ + + namespace trait + { + + namespace next + { + + // Forward declaration + // Needed by mln_trait_nbinary. + template < typename Name, typename L_, typename R_ > + struct solve_binary; + template < typename Name, typename T_ > struct solve_unary; + + + + // Unary ops. + + template < typename Op, typename P > + struct set_unary_< Op, mln::Proxy, P > + { + typedef mlc_unqualif(mln_q_subject(P)) S; + typedef mln_trait_nunary(Op, S) ret; + }; + + // Binary ops. + + template < typename Op, typename L, typename R > + struct set_binary_< Op, mln::Proxy, L, mln::Proxy, R > + { + typedef mln::internal::helper_unprox_binop<L, R> helper; + typedef mln_trait_nbinary(Op, + typename helper::L_ret, + typename helper::R_ret) ret; + }; + + template < typename Op, typename P, typename O > + struct set_binary_< Op, mln::Proxy, P, mln::Object, O > + { + typedef mlc_unqualif(mln_q_subject(P)) S; + typedef mln_trait_nbinary(Op, S, O) ret; + }; + + template < typename Op, typename O, typename P > + struct set_binary_< Op, mln::Object, O, mln::Proxy, P > + { + typedef mlc_unqualif(mln_q_subject(P)) S; + typedef mln_trait_nbinary(Op, O, S) ret; + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_NEXT_SOLVE_PROXY_HH diff --git a/milena/mln/trait/next/solve_unary.hh b/milena/mln/trait/next/solve_unary.hh new file mode 100644 index 0000000..86b1d9a --- /dev/null +++ b/milena/mln/trait/next/solve_unary.hh @@ -0,0 +1,170 @@ +// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_NEXT_SOLVE_UNARY_HH +# define MLN_TRAIT_NEXT_SOLVE_UNARY_HH + +/*! + * \file + * + * \brief FIXME + * + * + */ + +# include <mln/core/category.hh> +# include <mln/core/routine/exact.hh> +# include <mln/metal/equal.hh> +# include <mln/metal/if.hh> +# include <mln/metal/ret.hh> +# include <mln/trait/next/solve.hh> + + +// FIXME: Just for the record (use it...) + +# ifndef MLN_DEBUG_TRAITS +# endif // ! MLN_DEBUG_TRAITS + + + +namespace mln +{ + + namespace trait + { + + namespace next + { + + namespace internal + { + + + template < typename Name, + typename Category, + typename T > + struct trait_set_unary_; + + template < typename Name, + template <class> class Category, typename _, + typename T > + struct trait_set_unary_< Name, Category<_>, T > + { + typedef typename mln::trait::next::set_unary_<Name, Category, T>::ret ret; + }; + + + // Fwd decls. + template < typename Name, + typename Category, typename T > + struct get_unary_; + + + template < typename user_ret, /* != not_found and != undefined */ + typename Name, + typename Category, typename T > + struct helper_get_unary_ + { + typedef user_ret ret; // The user has defined 'ret' so we return it. + }; + + + template < typename Name, + typename Category, typename T > + struct helper_get_unary_< /* user_ret == */ not_found, + Name, Category, T > + { + typedef not_found ret; // End of search due to a blocker; 'ret' is not found. + }; + + + template < typename Name, + typename Category, typename T > + struct helper_get_unary_< /* user_ret == */ undefined, + Name, Category, T > + { + typedef typename mln::internal::super_category_< Category, T >::ret Super_Category; + typedef typename get_unary_<Name, Super_Category, T>::ret ret; // No user ret definition => Recursion. + }; + + + template < typename Name, + typename Category, typename T > + struct get_unary_ + { + typedef typename trait_set_unary_<Name, Category, T>::ret user_ret; // First get 'user_ret' + typedef helper_get_unary_<user_ret, Name, Category, T> helper; // Set the helper to make a decision. + typedef mlc_ret(helper) ret; // Return. + }; + + + template < typename precise_ret, + typename Name, + typename Category, typename T > + struct helper_choose_unary_wrt_ /* precise_ret != undefined */ + { + typedef precise_ret ret; // -> A precise ret has been defined so it is it. + }; + + template < typename Name, + typename Category, typename T > + struct helper_choose_unary_wrt_< /* precise_ret == */ undefined, + Name, Category, T > + { + typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the category inheritance + // to fetch a ret from 'set_unary_'s. + }; + + template < typename Name, + typename Category, typename T > + struct helper_solve_unary_ + { + typedef typename set_precise_unary_<Name, T>::ret precise_ret; + typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */ + Name, Category, T> helper; + typedef mlc_ret(helper) ret; + }; + + } // end of namespace mln::trait::next::internal + + + template < typename Name, + typename T_ > + struct solve_unary + { + typedef mln_exact(T_) T; + typedef typename mln::category<T>::ret Category; + typedef internal::helper_solve_unary_< Name, Category, T > meta_code; + typedef typename meta_code::ret ret; + }; + + } // end of namespace mln::trait::next + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_NEXT_SOLVE_UNARY_HH diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk index 2d2864e..4fc2dad 100644 --- a/milena/tests/unit_test/unit-tests.mk +++ b/milena/tests/unit_test/unit-tests.mk @@ -378,6 +378,7 @@ mln_core_image_vertex_image \ mln_core_image_vmorph_all \ mln_core_image_vmorph_cast_image \ mln_core_image_vmorph_fun_image \ +mln_core_image_vmorph_thru_image \ mln_core_image_vmorph_violent_cast_image \ mln_core_internal_box_impl \ mln_core_internal_check_image_all \ @@ -563,6 +564,10 @@ mln_extension_fill \ mln_fun_all \ mln_fun_c \ mln_fun_cast \ +mln_fun_component_blue \ +mln_fun_component_green \ +mln_fun_component_red \ +mln_fun_component_rgb \ mln_fun_essential \ mln_fun_i2v_all \ mln_fun_i2v_all_to \ @@ -593,8 +598,11 @@ mln_fun_p2v_elifs \ mln_fun_p2v_essential \ mln_fun_p2v_iota \ mln_fun_p2v_ternary \ +mln_fun_param \ +mln_fun_spe_unary \ mln_fun_stat_all \ mln_fun_stat_mahalanobis \ +mln_fun_unary \ mln_fun_v2b_all \ mln_fun_v2b_essential \ mln_fun_v2b_lnot \ @@ -1105,11 +1113,16 @@ mln_trait_ch_function_value \ mln_trait_ch_value \ mln_trait_concrete \ mln_trait_essential \ +mln_trait_functions \ mln_trait_image_print \ mln_trait_image_props \ mln_trait_image_from_grid \ mln_trait_images \ mln_trait_neighborhood \ +mln_trait_next_solve \ +mln_trait_next_solve_binary \ +mln_trait_next_solve_proxy \ +mln_trait_next_solve_unary \ mln_trait_op_all \ mln_trait_op_and \ mln_trait_op_decl \ @@ -1629,6 +1642,7 @@ mln_core_image_vertex_image_SOURCES = mln_core_image_vertex_image.cc mln_core_image_vmorph_all_SOURCES = mln_core_image_vmorph_all.cc mln_core_image_vmorph_cast_image_SOURCES = mln_core_image_vmorph_cast_image.cc mln_core_image_vmorph_fun_image_SOURCES = mln_core_image_vmorph_fun_image.cc +mln_core_image_vmorph_thru_image_SOURCES = mln_core_image_vmorph_thru_image.cc mln_core_image_vmorph_violent_cast_image_SOURCES = mln_core_image_vmorph_violent_cast_image.cc mln_core_internal_box_impl_SOURCES = mln_core_internal_box_impl.cc mln_core_internal_check_image_all_SOURCES = mln_core_internal_check_image_all.cc @@ -1814,6 +1828,10 @@ mln_extension_fill_SOURCES = mln_extension_fill.cc mln_fun_all_SOURCES = mln_fun_all.cc mln_fun_c_SOURCES = mln_fun_c.cc mln_fun_cast_SOURCES = mln_fun_cast.cc +mln_fun_component_blue_SOURCES = mln_fun_component_blue.cc +mln_fun_component_green_SOURCES = mln_fun_component_green.cc +mln_fun_component_red_SOURCES = mln_fun_component_red.cc +mln_fun_component_rgb_SOURCES = mln_fun_component_rgb.cc mln_fun_essential_SOURCES = mln_fun_essential.cc mln_fun_i2v_all_SOURCES = mln_fun_i2v_all.cc mln_fun_i2v_all_to_SOURCES = mln_fun_i2v_all_to.cc @@ -1844,8 +1862,11 @@ mln_fun_p2v_elifs_SOURCES = mln_fun_p2v_elifs.cc mln_fun_p2v_essential_SOURCES = mln_fun_p2v_essential.cc mln_fun_p2v_iota_SOURCES = mln_fun_p2v_iota.cc mln_fun_p2v_ternary_SOURCES = mln_fun_p2v_ternary.cc +mln_fun_param_SOURCES = mln_fun_param.cc +mln_fun_spe_unary_SOURCES = mln_fun_spe_unary.cc mln_fun_stat_all_SOURCES = mln_fun_stat_all.cc mln_fun_stat_mahalanobis_SOURCES = mln_fun_stat_mahalanobis.cc +mln_fun_unary_SOURCES = mln_fun_unary.cc mln_fun_v2b_all_SOURCES = mln_fun_v2b_all.cc mln_fun_v2b_essential_SOURCES = mln_fun_v2b_essential.cc mln_fun_v2b_lnot_SOURCES = mln_fun_v2b_lnot.cc @@ -2356,11 +2377,16 @@ mln_trait_ch_function_value_SOURCES = mln_trait_ch_function_value.cc mln_trait_ch_value_SOURCES = mln_trait_ch_value.cc mln_trait_concrete_SOURCES = mln_trait_concrete.cc mln_trait_essential_SOURCES = mln_trait_essential.cc +mln_trait_functions_SOURCES = mln_trait_functions.cc mln_trait_image_print_SOURCES = mln_trait_image_print.cc mln_trait_image_props_SOURCES = mln_trait_image_props.cc mln_trait_image_from_grid_SOURCES = mln_trait_image_from_grid.cc mln_trait_images_SOURCES = mln_trait_images.cc mln_trait_neighborhood_SOURCES = mln_trait_neighborhood.cc +mln_trait_next_solve_SOURCES = mln_trait_next_solve.cc +mln_trait_next_solve_binary_SOURCES = mln_trait_next_solve_binary.cc +mln_trait_next_solve_proxy_SOURCES = mln_trait_next_solve_proxy.cc +mln_trait_next_solve_unary_SOURCES = mln_trait_next_solve_unary.cc mln_trait_op_all_SOURCES = mln_trait_op_all.cc mln_trait_op_and_SOURCES = mln_trait_op_and.cc mln_trait_op_decl_SOURCES = mln_trait_op_decl.cc -- 1.7.2.5