1060: Add morphology plus and minus.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add morphology plus and minus. * tests/erosion.cc: Rename as... * tests/morpho_erosion.cc: ...this. * mln/geom/pmin_pmax.hh: Fix. * mln/morpho/plus.hh: New. * mln/morpho/minus.hh: New. * mln/logical: New. * mln/logical/and.hh: New. * mln/logical/and_not.hh: New. * mln/logical/or.hh: New. * mln/morpho/includes.hh, * mln/morpho/gradient.hh, * mln/morpho/contrast.hh, * mln/morpho/top_hat.hh: Update. mln/geom/pmin_pmax.hh | 4 - mln/logical/and.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ mln/logical/and_not.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ mln/logical/or.hh | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ mln/morpho/contrast.hh | 4 - mln/morpho/gradient.hh | 6 +- mln/morpho/includes.hh | 5 - mln/morpho/minus.hh | 111 +++++++++++++++++++++++++++++++++++++++++ mln/morpho/plus.hh | 108 ++++++++++++++++++++++++++++++++++++++++ mln/morpho/top_hat.hh | 6 +- tests/morpho_erosion.cc | 2 11 files changed, 613 insertions(+), 14 deletions(-) Index: tests/morpho_erosion.cc --- tests/morpho_erosion.cc (revision 1059) +++ tests/morpho_erosion.cc (working copy) @@ -25,7 +25,7 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/*! \file tests/erosion.cc +/*! \file tests/morpho_erosion.cc * * \brief Test on mln::morpho::erosion. */ Index: mln/geom/pmin_pmax.hh --- mln/geom/pmin_pmax.hh (revision 1059) +++ mln/geom/pmin_pmax.hh (working copy) @@ -108,7 +108,7 @@ { typedef mln_point(I) P; std::pair<P, P> tmp; - pmin_pmax(p, tmp.first, tmp.second); // calls the previous version + pmin_pmax(p, tmp.first, tmp.second); // Calls the previous version. return tmp; } @@ -156,7 +156,7 @@ mln_precondition(exact(s).npoints() != 0); typedef mln_point(S) P; std::pair<P, P> tmp; - pmin_pmax(p_, tmp.first, tmp.second); // calls the previous version + pmin_pmax(s, tmp.first, tmp.second); // Calls the previous version. return tmp; } Index: mln/morpho/plus.hh --- mln/morpho/plus.hh (revision 0) +++ mln/morpho/plus.hh (revision 0) @@ -0,0 +1,108 @@ +// 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_MORPHO_PLUS_HH +# define MLN_MORPHO_PLUS_HH + +# include <mln/level/compare.hh> +# include <mln/logical/or.hh> +# include <mln/arith/plus.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological plus: either a "logical or" (if morpho on sets) + * or an "arithmetical plus" (if morpho on functions). + */ + template <typename I, typename J, typename O> + void plus(const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output); + + /*! Morphological plus, inplace version: either a "logical or" (if + * morpho on sets) or an "arithmetical plus" (if morpho on + * functions). + */ + template <typename I, typename J> + void plus_inplace(Image<I>& lhs, const Image<J>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename J, typename O> + void plus_(value::binary_kind, // binary => morphology on sets + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return logical::or_(lhs, rhs, output); + } + + template <typename K, typename I, typename J, typename O> + void plus_(K, // otherwise => morphology on functions + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return arith::plus(lhs, rhs, output); + } + + } // end of namespace mln::morpho::impl + + + // Facades. + + template <typename I, typename J, typename O> + void plus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + + impl::plus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output); + + mln_postcondition(output <= lhs); + } + + template <typename I, typename J> + void plus_inplace(Image<I>& lhs, const Image<J>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + morpho::plus(lhs, rhs, lhs); // Calls the previous version. + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_PLUS_HH Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 1059) +++ mln/morpho/includes.hh (working copy) @@ -40,9 +40,6 @@ # include <mln/accu/min.hh> # include <mln/accu/max.hh> -# include <mln/arith/plus.hh> -# include <mln/arith/minus.hh> - # include <mln/level/compare.hh> # include <mln/level/fill.hh> @@ -54,6 +51,8 @@ # include <mln/morpho/dilation.hh> # include <mln/morpho/erosion.hh> +# include <mln/morpho/minus.hh> +# include <mln/morpho/plus.hh> #endif // ! MLN_MORPHO_INCLUDES_HH Index: mln/morpho/minus.hh --- mln/morpho/minus.hh (revision 0) +++ mln/morpho/minus.hh (revision 0) @@ -0,0 +1,111 @@ +// 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_MORPHO_MINUS_HH +# define MLN_MORPHO_MINUS_HH + +# include <mln/level/compare.hh> +# include <mln/logical/and_not.hh> +# include <mln/arith/minus.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological minus: either a logical "and not" (if morpho on + * sets) or an arithmetical minus (if morpho on functions). + */ + template <typename I, typename J, typename O> + void minus(const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output); + + /*! Morphological minus, inplace version: either a logical "and + * not" (if morpho on sets) or an arithmetical minus (if morpho + * on functions). + */ + template <typename I, typename J> + void minus_inplace(Image<I>& lhs, const Image<J>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename J, typename O> + void minus_(value::binary_kind, // binary => morphology on sets + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return logical::and_not(lhs, rhs, output); + } + + template <typename K, typename I, typename J, typename O> + void minus_(K, // otherwise => morphology on functions + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return arith::minus(lhs, rhs, output); + } + + } // end of namespace mln::morpho::impl + + + // Facades. + + template <typename I, typename J, typename O> + void minus(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + mln_precondition(rhs <= lhs); + + impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output); + + mln_postcondition(output <= lhs); + } + + template <typename I, typename J> + void minus_inplace(Image<I>& lhs, const Image<J>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(rhs <= lhs); + + morpho::minus(lhs, rhs, lhs); // Calls the previous version. + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_MINUS_HH Index: mln/morpho/gradient.hh --- mln/morpho/gradient.hh (revision 1059) +++ mln/morpho/gradient.hh (working copy) @@ -86,7 +86,7 @@ dilation(input, win, output); // output = dilation O temp(input.domain()); erosion(input, win, temp); // temp = erosion - arith::minus_inplace(output, temp); // now output = dilation - erosion + morpho::minus_inplace(output, temp); // now output = dilation - erosion mln_postcondition(test::positive(output)); } @@ -104,7 +104,7 @@ O temp(input.domain()); erosion(input, win, temp); // temp = erosion - arith::minus(input, temp, output); // output = input - erosion + morpho::minus(input, temp, output); // output = input - erosion mln_postcondition(test::positive(output)); } @@ -121,7 +121,7 @@ mln_precondition(! win.is_empty()); dilation(input, win, output); // output = dilation - arith::minus_inplace(output, input); // now output = dilation - input + morpho::minus_inplace(output, input); // now output = dilation - input mln_postcondition(test::positive(output)); } Index: mln/morpho/contrast.hh --- mln/morpho/contrast.hh (revision 1059) +++ mln/morpho/contrast.hh (working copy) @@ -66,10 +66,10 @@ mln_precondition(! win.is_empty()); top_hat_white(input, win, output); // output = wth - arith::plus_inplace(output, input); // now output = wth + input + morpho::plus_inplace(output, input); // now output = wth + input O temp(input.domain()); top_hat_black(input, win, temp); // temp = bth - arith::minus_inplace(output, temp); // now output = wth + input - bth + morpho::minus_inplace(output, temp); // now output = wth + input - bth } # endif // ! MLN_INCLUDE_ONLY Index: mln/morpho/top_hat.hh --- mln/morpho/top_hat.hh (revision 1059) +++ mln/morpho/top_hat.hh (working copy) @@ -89,7 +89,7 @@ O temp(input.domain()); opening(input, win, temp); // temp = opening - arith::minus(input, temp, output); // output = input - opening + morpho::minus(input, temp, output); // output = input - opening mln_postcondition(test::positive(output)); } @@ -105,7 +105,7 @@ mln_precondition(! win.is_empty()); closing(input, win, output); // output = closing - arith::minus_inplace(output, input); // now output = closing - input + morpho::minus_inplace(output, input); // now output = closing - input mln_postcondition(test::positive(output)); } @@ -123,7 +123,7 @@ closing(input, win, output); // output = closing O temp(input.domain()); opening(input, win, temp); // temp = opening - arith::minus_inplace(output, temp); // now output = closing - opening + morpho::minus_inplace(output, temp); // now output = closing - opening mln_postcondition(test::positive(output)); } Index: mln/logical/and.hh --- mln/logical/and.hh (revision 0) +++ mln/logical/and.hh (revision 0) @@ -0,0 +1,127 @@ +// 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_LOGICAL_AND_HH +# define MLN_LOGICAL_AND_HH + +/*! \file mln/logical/and.hh + * + * \brief Point-wise "logical and" between binary images. + * + * \todo Add static assertion and save one iterator in in-place version. + */ + +# include <mln/core/concept/image.hh> + + +namespace mln +{ + + namespace logical + { + + /*! Point-wise "logical and" between images \p lhs and \p rhs. + * + * \param[in] lhs First operand image. + * \param[in] rhs Second operand image. + * \param[out] output The result image. + * + * \pre \p output.domain = \p lhs.domain = \p rhs.domain + */ + template <typename L, typename R, typename O> + void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + + + /*! Point-wise in-place "logical and" of image \p rhs in image \p lhs. + * + * \param[in] lhs First operand image. + * \param[in,out] rhs Second operand image. + * + * This addition performs: \n + * for all p of rhs.domain \n + * lhs(p) = lhs(p) and rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void and_inplace(Image<L>& lhs, const Image<R>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename L, typename R, typename O> + void and__(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) + { + const L& lhs = exact(lhs_); + const R& rhs = exact(rhs_); + O& output = exact(output_); + mln_piter(L) p(lhs.domain()); + for_all(p) + output(p) = lhs(p) && rhs(p); + } + + template <typename L, typename R, typename O> + void and__(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output) + { + mln_pixter(const L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + mln_pixter(O) op(exact(output)); + for_all_3(lp, rp, op) + op.val() = lp.val() && rp.val(); + } + + } // end of namespace mln::logical::impl + + + // Facades. + + template <typename L, typename R, typename O> + void and_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::and__(exact(lhs), exact(rhs), exact(output)); + } + + template <typename L, typename R> + void and_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::and__(exact(lhs), exact(rhs), exact(lhs)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::logical + +} // end of namespace mln + + +#endif // ! MLN_LOGICAL_AND_HH Index: mln/logical/and_not.hh --- mln/logical/and_not.hh (revision 0) +++ mln/logical/and_not.hh (revision 0) @@ -0,0 +1,127 @@ +// 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_LOGICAL_AND_NOT_HH +# define MLN_LOGICAL_AND_NOT_HH + +/*! \file mln/logical/and_not.hh + * + * \brief Point-wise logical "and not" between binary images. + * + * \todo Add static assertion and save one iterator in in-place version. + */ + +# include <mln/core/concept/image.hh> + + +namespace mln +{ + + namespace logical + { + + /*! Point-wise logical "and not" between images \p lhs and \p rhs. + * + * \param[in] lhs First operand image. + * \param[in] rhs Second operand image. + * \param[out] output The result image. + * + * \pre \p output.domain = \p lhs.domain = \p rhs.domain + */ + template <typename L, typename R, typename O> + void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + + + /*! Point-wise in-place logical "and not" of image \p rhs in image \p lhs. + * + * \param[in] lhs First operand image. + * \param[in,out] rhs Second operand image. + * + * This addition performs: \n + * for all p of rhs.domain \n + * lhs(p) = lhs(p) and not rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void and_not_inplace(Image<L>& lhs, const Image<R>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename L, typename R, typename O> + void and_not_(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) + { + const L& lhs = exact(lhs_); + const R& rhs = exact(rhs_); + O& output = exact(output_); + mln_piter(L) p(lhs.domain()); + for_all(p) + output(p) = lhs(p) && ! rhs(p); + } + + template <typename L, typename R, typename O> + void and_not_(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output) + { + mln_pixter(const L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + mln_pixter(O) op(exact(output)); + for_all_3(lp, rp, op) + op.val() = lp.val() && ! rp.val(); + } + + } // end of namespace mln::logical::impl + + + // Facades. + + template <typename L, typename R, typename O> + void and_not(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::and_not_(exact(lhs), exact(rhs), exact(output)); + } + + template <typename L, typename R> + void and_not_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::and_not_(exact(lhs), exact(rhs), exact(lhs)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::logical + +} // end of namespace mln + + +#endif // ! MLN_LOGICAL_AND_NOT_HH Index: mln/logical/or.hh --- mln/logical/or.hh (revision 0) +++ mln/logical/or.hh (revision 0) @@ -0,0 +1,127 @@ +// 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_LOGICAL_OR_HH +# define MLN_LOGICAL_OR_HH + +/*! \file mln/logical/or.hh + * + * \brief Point-wise "logical or" between binary images. + * + * \todo Add static assertion and save one iterator in in-place version. + */ + +# include <mln/core/concept/image.hh> + + +namespace mln +{ + + namespace logical + { + + /*! Point-wise "logical or" between images \p lhs and \p rhs. + * + * \param[in] lhs First operand image. + * \param[in] rhs Second operand image. + * \param[out] output The result image. + * + * \pre \p output.domain = \p lhs.domain = \p rhs.domain + */ + template <typename L, typename R, typename O> + void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + + + /*! Point-wise in-place "logical or" of image \p rhs in image \p lhs. + * + * \param[in] lhs First operand image. + * \param[in,out] rhs Second operand image. + * + * This addition performs: \n + * for all p of rhs.domain \n + * lhs(p) = lhs(p) or rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void or_inplace(Image<L>& lhs, const Image<R>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename L, typename R, typename O> + void or__(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) + { + const L& lhs = exact(lhs_); + const R& rhs = exact(rhs_); + O& output = exact(output_); + mln_piter(L) p(lhs.domain()); + for_all(p) + output(p) = lhs(p) || rhs(p); + } + + template <typename L, typename R, typename O> + void or__(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output) + { + mln_pixter(const L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + mln_pixter(O) op(exact(output)); + for_all_3(lp, rp, op) + op.val() = lp.val() || rp.val(); + } + + } // end of namespace mln::logical::impl + + + // Facades. + + template <typename L, typename R, typename O> + void or_(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::or__(exact(lhs), exact(rhs), exact(output)); + } + + template <typename L, typename R> + void or_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::or__(exact(lhs), exact(rhs), exact(lhs)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::logical + +} // end of namespace mln + + +#endif // ! MLN_LOGICAL_OR_HH
participants (1)
-
Thierry Geraud