Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
proto-1.0 117: Introduce Metalic abstractions for unary and binary functions
by Roland Levillain 06 Apr '05
by Roland Levillain 06 Apr '05
06 Apr '05
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0/metalic
ChangeLog | 7
mlc/fun.hh | 410 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
mlc/makefile.src | 3
3 files changed, 419 insertions(+), 1 deletion(-)
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Introduce Metalic abstractions for unary and binary functions.
* mlc/fun.hh: New file.
* mlc/makefile.src (MLC_DEP): Add fun.hh.
Index: mlc/fun.hh
--- mlc/fun.hh (revision 0)
+++ mlc/fun.hh (revision 0)
@@ -0,0 +1,410 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_FUN_HH
+# define METALIC_FUN_HH
+
+# include <mlc/any.hh>
+
+namespace mlc
+{
+
+ // Fwd decl.
+ template <typename T>
+ struct function_traits;
+
+
+ /*---------------.
+ | Abstractions. |
+ `---------------*/
+
+ namespace abstract {
+
+ template <typename E>
+ class unary_function : public mlc::any__best_memory<E>
+ {
+ public:
+ typedef E exact_type;
+ typedef typename function_traits<exact_type>::argument_type
+ argument_type;
+ typedef typename function_traits<exact_type>::result_type
+ result_type;
+
+ public:
+ result_type
+ operator()(const argument_type& arg) const
+ {
+ // Check for "exact_type::impl_op_paren".
+ typedef
+ result_type (exact_type::*fun_type)(const argument_type&) const;
+ static fun_type fun_adr = &exact_type::impl_op_paren;
+ assert(fun_adr != 0);
+
+ return this->exact().impl_op_paren(arg);
+ }
+ };
+
+ // FIXME: Add meta_unary_function.
+
+ template <typename E>
+ class binary_function : public mlc::any__best_memory<E>
+ {
+ public:
+ typedef E exact_type;
+ typedef typename function_traits<exact_type>::argument1_type
+ argument1_type;
+ typedef typename function_traits<exact_type>::argument2_type
+ argument2_type;
+ typedef typename function_traits<exact_type>::result_type
+ result_type;
+
+ public:
+ result_type
+ operator()(const argument1_type& arg1, const argument2_type& arg2) const
+ {
+ // Check for "exact_type::impl_op_paren".
+ typedef
+ result_type (exact_type::*fun_type)(const argument1_type&,
+ const argument2_type&) const;
+ static fun_type fun_adr = &exact_type::impl_op_paren;
+ assert(fun_adr != 0);
+
+ return this->exact().impl_op_paren(arg1, arg2);
+ }
+ };
+
+ // FIXME: Add meta_binary_function.
+
+ } // end of namespace abstract
+
+
+ enum function_type
+ {
+ unknown_function_tag = 0,
+ // C-like functions.
+ classic_unary_function_tag,
+ classic_unary_function_ptr_tag,
+ classic_binary_function_tag,
+ classic_binary_function_ptr_tag,
+ // Functions deriving from the std namespace.
+ std_unary_function_tag,
+ std_binary_function_tag,
+ // Functions deriving from the oln namespace.
+ oln_unary_function_tag,
+ oln_binary_function_tag,
+ oln_meta_unary_function_tag
+ };
+
+ struct fun_info_helper
+ {
+ template <function_type t>
+ struct case_ { char dummy[t]; };
+
+ // C-like functions.
+
+ template <typename A, typename R>
+ static case_<classic_unary_function_tag> on(R (**)(A));
+
+ template <typename A, typename R>
+ static case_<classic_unary_function_ptr_tag> on(R (*)(A));
+
+ template <typename A1, typename A2, typename R>
+ static case_<classic_binary_function_tag> on(R (**)(A1, A2));
+
+ template <typename A1, typename A2, typename R>
+ static case_<classic_binary_function_ptr_tag> on(R (*)(A1, A2));
+
+ // Functions deriving from the std namespace.
+
+ template <typename A, typename R>
+ static case_<std_unary_function_tag>
+ on(const std::unary_function<A, R>*);
+
+ template <typename A1, typename A2, typename R>
+ static case_<std_binary_function_tag>
+ on(const std::binary_function<A1, A2, R>*);
+
+ // Functions deriving from the oln namespace.
+ // FIXME: To do.
+
+ static case_<unknown_function_tag> on(...);
+ };
+
+
+ /*--------------------------------.
+ | Helpers for classic functions. |
+ `--------------------------------*/
+
+ template <typename A>
+ struct get_result;
+
+ template <typename A, typename R>
+ struct get_result <R (*)(A)> { typedef R ret; };
+
+ template <typename A1, typename A2, typename R>
+ struct get_result <R (*)(A1,A2)> { typedef R ret; };
+
+
+ template <typename A>
+ struct get_argument;
+
+ template <typename A, typename R>
+ struct get_argument <R (*)(A)> { typedef A ret; };
+
+
+ template <typename A>
+ struct get_argument1;
+
+ template <typename A1, typename A2, typename R>
+ struct get_argument1 <R (*)(A1, A2)> { typedef A1 ret; };
+
+
+ template <typename A>
+ struct get_argument2;
+
+ template <typename A1, typename A2, typename R>
+ struct get_argument2 <R (*)(A1, A2)> { typedef A2 ret; };
+
+
+ /*-----------------------.
+ | Function information. |
+ `-----------------------*/
+
+ // Create a static pointer on type T.
+ template <typename T>
+ struct make
+ {
+ static T* ptr();
+ };
+
+
+ // Information on result type and argument type(s).
+ template <typename F, typename T, unsigned>
+ struct fun_info;
+
+ // R (*)(A).
+ template <typename F, typename T>
+ struct fun_info <F, T, classic_unary_function_tag>
+ {
+ typedef typename get_argument<F>::ret argument_type;
+ typedef typename get_result<F>::ret result_type;
+ };
+
+ // R (**)(A).
+ template <typename F, typename T>
+ struct fun_info <F, T, classic_unary_function_ptr_tag>
+ {
+ typedef typename get_argument<F*>::ret argument_type;
+ typedef typename get_result<F*>::ret result_type;
+ };
+
+ // R (*)(A1, A2).
+ template <typename F, typename T>
+ struct fun_info <F, T, classic_binary_function_tag>
+ {
+ typedef typename get_argument1<F>::ret argument1_type;
+ typedef typename get_argument2<F>::ret argument2_type;
+ typedef typename get_result<F>::ret result_type;
+ };
+
+ // R (**)(A1, A2).
+ template <typename F, typename T>
+ struct fun_info <F, T, classic_binary_function_ptr_tag>
+ {
+ typedef typename get_argument1<F*>::ret argument1_type;
+ typedef typename get_argument2<F*>::ret argument2_type;
+ typedef typename get_result<F*>::ret result_type;
+ };
+
+ // std::unary_function<A, R>
+ template <typename F, typename T>
+ struct fun_info <F, T, std_unary_function_tag>
+ {
+ typedef typename F::argument_type argument_type;
+ typedef typename F::result_type result_type;
+ };
+
+ // std::binary_function<A1, A2, R>
+ template <typename F, typename T>
+ struct fun_info <F, T, std_binary_function_tag>
+ {
+ typedef typename F::first_argument_type argument1_type;
+ typedef typename F::second_argument_type argument2_type;
+ typedef typename F::result_type result_type;
+ };
+
+ // FIXME: To be re-enabled later.
+# if 0
+ // oln::unary_function<E>
+ template <typename F, typename T>
+ struct fun_info <F, T, oln_unary_function_tag>
+ {
+ typedef oln_result_type(F) result_type;
+ };
+
+ // oln::binary_function<E>
+ template <typename F, typename T>
+ struct fun_info <F, T, oln_binary_function_tag>
+ {
+ typedef oln_result_type(F) result_type;
+ };
+
+ // oln::meta_unary_function<E>
+ template <typename F, typename T>
+ struct fun_info <F, T, oln_meta_unary_function_tag>
+ {
+ typedef oln_result_type_from(F,T) result_type;
+ };
+# endif
+
+
+ /*-------------------------------------.
+ | Unary functions, with their traits. |
+ `-------------------------------------*/
+
+ // Fwd decl.
+ template <typename F>
+ class unary_function;
+
+ template <typename F>
+ struct function_traits< unary_function <F> >
+ {
+ static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+ typedef typename fun_info<F, void, case_id>::argument_type argument_type;
+ typedef typename fun_info<F, void, case_id>::result_type result_type;
+ };
+
+ template <typename F>
+ class unary_function :
+ public mlc::abstract::unary_function< unary_function<F> >
+ {
+ public:
+ typedef unary_function<F> self_type;
+ typedef abstract::unary_function< unary_function<F> > super_type;
+
+ typedef typename function_traits<self_type>::argument_type argument_type;
+ typedef typename function_traits<self_type>::result_type result_type;
+
+ public:
+ unary_function(F f) : super_type(), f_(f)
+ {
+ }
+
+ result_type
+ impl_op_paren (const argument_type& arg) const
+ {
+ return f_(arg);
+ }
+
+ private:
+ F f_;
+ };
+
+ template <typename F>
+ unary_function<F>
+ make_unary_fun(F f)
+ {
+ return unary_function<F> (f);
+ }
+
+
+ /*--------------------------------------.
+ | Binary functions, with their traits. |
+ `--------------------------------------*/
+
+ // Fwd decl.
+ template <typename F>
+ class binary_function;
+
+ template <typename F>
+ struct function_traits< binary_function <F> >
+ {
+ static const int case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+ typedef typename fun_info<F, void, case_id>::argument1_type argument1_type;
+ typedef typename fun_info<F, void, case_id>::argument2_type argument2_type;
+ typedef typename fun_info<F, void, case_id>::result_type result_type;
+ };
+
+ template <typename F>
+ class binary_function :
+ public mlc::abstract::binary_function< binary_function<F> >
+ {
+ public:
+ typedef binary_function<F> self_type;
+ typedef abstract::binary_function< binary_function<F> > super_type;
+
+ typedef typename function_traits<self_type>::argument1_type argument1_type;
+ typedef typename function_traits<self_type>::argument2_type argument2_type;
+ typedef typename function_traits<self_type>::result_type result_type;
+
+ public:
+ binary_function(F f) : super_type(), f_(f)
+ {
+ }
+
+ result_type
+ impl_op_paren (const argument1_type& arg1,
+ const argument1_type& arg2) const
+ {
+ return f_(arg1, arg2);
+ }
+
+ private:
+ F f_;
+ };
+
+ template <typename F>
+ binary_function<F>
+ make_binary_fun(F f)
+ {
+ return binary_function<F> (f);
+ }
+
+
+ /*------------------------------------------.
+ | Meta-unary functions, with their traits. |
+ `------------------------------------------*/
+
+ // FIXME: To be re-enabled later.
+# if 0
+ template <typename F>
+ struct meta_fun_info
+ {
+ template <typename T>
+ struct with
+ {
+ static const case_id = sizeof(fun_info_helper::on(make<F>::ptr()));
+ typedef typename fun_info_result_type<F, T, case_id>::ret result_type;
+ };
+ };
+#endif
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_FUN_HH
Index: mlc/makefile.src
--- mlc/makefile.src (revision 116)
+++ mlc/makefile.src (working copy)
@@ -1,4 +1,4 @@
-##
+## -*- Makefile -*-
## List of headers in metalic
## Include this file to have access to their name.
##
@@ -20,6 +20,7 @@
cmp.hh \
config/system.hh \
contract.hh \
+ fun.hh \
if.hh \
is_a.hh \
math.hh \
1
0
2005-04-06 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* mlc/bool.hh: Make clear that ::ret is not ::val.
* mlc/properties.hh: Likewise.
* mlc/if.hh: Likewise.
* mlc/value.hh: Likewise.
* tests/main/tests/is_a1: Likewise.
Index: tests/main/tests/is_a1
===================================================================
--- tests/main/tests/is_a1 (revision 115)
+++ tests/main/tests/is_a1 (working copy)
@@ -13,21 +13,21 @@
template <class T>
void foo()
{
- is_false<mlc_is_a(int, bool)::ret>::ensure();
- is_true<mlc_is_a(B, A)::ret>::ensure();
- is_true<mlc_is_a(C, A)::ret>::ensure();
- is_false<mlc_is_a(A, B)::ret>::ensure();
+ is_false<mlc_is_a(int, bool)::val>::ensure();
+ is_true<mlc_is_a(B, A)::val>::ensure();
+ is_true<mlc_is_a(C, A)::val>::ensure();
+ is_false<mlc_is_a(A, B)::val>::ensure();
}
int main()
{
- is_false<mlc_is_a_(int, bool)::ret>::ensure();
- is_true<mlc_is_a_(B, A)::ret>::ensure();
- is_true<mlc_is_a_(C, A)::ret>::ensure();
- is_false<mlc_is_a_(A, B)::ret>::ensure();
+ is_false<mlc_is_a_(int, bool)::val>::ensure();
+ is_true<mlc_is_a_(B, A)::val>::ensure();
+ is_true<mlc_is_a_(C, A)::val>::ensure();
+ is_false<mlc_is_a_(A, B)::val>::ensure();
- is_true<mlc_is_a_(T_B<int>, T_A)::ret>::ensure();
- is_false<mlc_is_a_(T_A<int>, T_B)::ret>::ensure();
+ is_true<mlc_is_a_(T_B<int>, T_A)::val>::ensure();
+ is_false<mlc_is_a_(T_A<int>, T_B)::val>::ensure();
foo<int>();
}
Index: mlc/bool.hh
===================================================================
--- mlc/bool.hh (revision 115)
+++ mlc/bool.hh (working copy)
@@ -34,30 +34,62 @@
namespace mlc
{
+ struct Boolean_value
+ {
+ };
- /// Specialization of mlc::value for T = bool and v = true; it provides ::ensure().
+ /// Specializations of mlc::value for T = bool; when v = true, ensure() is provided.
+
template <>
- struct value <bool, true>
+ struct value <bool, true> : public Boolean_value
{
+ static const bool b = true;
+ static const bool val = true;
static void ensure() {}
- static const bool ret = true;
- private:
- value();
+ protected:
+ value() {}
};
+ template <>
+ struct value <bool, false> : public Boolean_value
+ {
+ static const bool b = false;
+ static const bool val = false;
+ protected:
+ value() {}
+ };
+
/// Typedefs of true_type and false_type.
typedef value<bool, true> true_type;
typedef value<bool, false> false_type;
- /// Class is_true<b> (provided for bkd compability).
- template <bool b>
- struct is_true : public value<bool, b>
+ /// Classes is_true<b> and is_false<b> (provided for bkd compability).
+
+ template <bool b> struct is_true {};
+ template <> struct is_true <true> { static void ensure() {} };
+
+ template <bool b> struct is_false {};
+ template <> struct is_false <false> { static void ensure() {} };
+
+
+
+ /// Logical unary not of a Boolean type
+
+ template <typename T>
+ struct not_ : public value<bool, !T::b>
{
+ // FIXME: static assert here and below s.a. ~not_() { mlc_is_a(not_<T>, Boolean_value); }
};
+ /// Logical binary operators between a couple of Boolean types
+ template <typename L, typename R> struct and_ : public value <bool, (L::b && R::b)> {};
+ template <typename L, typename R> struct or_ : public value <bool, (L::b || R::b)> {};
+ template <typename L, typename R> struct nand_ : public value <bool, (L::b && !R::b)> {};
+ template <typename L, typename R> struct xor_ : public value <bool, ((L::b && !R::b) || (!L::b && R::b))> {};
+
} // end of namespace mlc
Index: mlc/properties.hh
===================================================================
--- mlc/properties.hh (revision 115)
+++ mlc/properties.hh (working copy)
@@ -33,6 +33,7 @@
# include <mlc/if.hh>
# include <mlc/cmp.hh>
+# include <mlc/types.hh>
Index: mlc/if.hh
===================================================================
--- mlc/if.hh (revision 115)
+++ mlc/if.hh (working copy)
@@ -38,19 +38,30 @@
namespace mlc
{
- template <typename cond_type, typename then_type, typename else_type>
- struct if_;
-
- template <typename then_type, typename else_type>
- struct if_ <true_type, then_type, else_type>
+ namespace internal
{
- typedef then_type ret;
- };
- template <typename then_type, typename else_type>
- struct if_ <false_type, then_type, else_type>
+ template <bool b, typename then_type, typename else_type>
+ struct if_;
+
+ template <typename then_type, typename else_type>
+ struct if_ <true, then_type, else_type>
+ {
+ typedef then_type ret;
+ };
+
+ template <typename then_type, typename else_type>
+ struct if_ <false, then_type, else_type>
+ {
+ typedef else_type ret;
+ };
+
+ } // end of namespace mlc::internal
+
+
+ template <typename cond_type, typename then_type, typename else_type>
+ struct if_ : public internal::if_ < cond_type::b, then_type, else_type >
{
- typedef else_type ret;
};
Index: mlc/value.hh
===================================================================
--- mlc/value.hh (revision 115)
+++ mlc/value.hh (working copy)
@@ -39,9 +39,9 @@
template <typename T, T v>
struct value
{
- static const T ret = v;
- private:
- value();
+ static const T val = v;
+ value() {}
+ operator T() const { return v; }
};
1
0
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/convert/ng_to_se.hh: Remove.
* oln/convert/nbh_to_se.hh: New.
* oln/core/abstract/internal/image_impl.hh: Add missing inclusion.
* oln/makefile.src: Commit name change for ng_to_se.hh.
* oln/morpho/reconstruction.hh: Factor code.
* oln/morpho/cc_tarjan.hh: Conform to mlc macros.
* oln/arith/min.hh: Conform to image_operator.
* oln/arith/max.hh: Conform to image_operator.
arith/max.hh | 23 -
arith/min.hh | 23 -
convert/nbh_to_se.hh | 22 -
convert/ng_to_se.hh | 88 ----
core/abstract/internal/image_impl.hh | 1
makefile.src | 2
morpho/cc_tarjan.hh | 33 -
morpho/reconstruction.hh | 650 ++++++++++++-----------------------
8 files changed, 282 insertions(+), 560 deletions(-)
Index: oln/convert/ng_to_se.hh
--- oln/convert/ng_to_se.hh (revision 114)
+++ oln/convert/ng_to_se.hh (working copy)
@@ -1,88 +0,0 @@
-// Copyright (C) 2002, 2004, 2005 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-// MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef OLENA_CONVERT_NG_TO_SE_HH
-# define OLENA_CONVERT_NG_TO_SE_HH
-
-# include <oln/basics.hh>
-
-// because of the internal function in this file
-//# include <oln/basics1d.hh>
-# include <oln/basics2d.hh>
-//# include <oln/basics3d.hh>
-//# include <oln/core/1d/neighborhood1d.hh>
-# include <oln/core/2d/neighborhood2d.hh>
-//# include <oln/core/3d/neighborhood3d.hh>
-
-namespace oln {
- namespace convert {
- /*! Convert a neighborhood to a window.
- **
- ** \see ng_to_cse
- */
- template<class N>
- oln_type_of(N, window)
- ng_to_se(const oln::abstract::neighborhood<N>& ng)
- {
- oln_type_of(N, window) output;
-
- for (unsigned i = 0; i < ng.card(); i++)
- output.add(ng[i]);
- return output;
- }
-
- void dpoint_zero(dpoint2d& dp)
- {
- dp.row() = 0;
- dp.col() = 0;
- }
-
- /*! Convert a neighborhood to a window and add the center.
- **
- ** \see ng_to_cs
- */
- template<class N>
- oln_type_of(N, window)
- ng_to_cse(const oln::abstract::neighborhood<N>& ng)
- {
- oln_type_of(N, window) output;
-
- for (unsigned i = 0; i < ng.card(); i++)
- output.add(ng[i]);
-
- oln_type_of(N, dpoint) zero;
- dpoint_zero(zero);
- output.add(zero);
- return output;
- }
-
-
- } // convert
-} // oln
-
-
-#endif // OLENA_CONVERT_NG_TO_SE_HH
Index: oln/convert/nbh_to_se.hh
--- oln/convert/nbh_to_se.hh (revision 114)
+++ oln/convert/nbh_to_se.hh (working copy)
@@ -25,8 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef OLENA_CONVERT_NG_TO_SE_HH
-# define OLENA_CONVERT_NG_TO_SE_HH
+#ifndef OLENA_CONVERT_NBH_TO_SE_HH
+# define OLENA_CONVERT_NBH_TO_SE_HH
# include <oln/basics.hh>
@@ -42,16 +42,16 @@
namespace convert {
/*! Convert a neighborhood to a window.
**
- ** \see ng_to_cse
+ ** \see nbh_to_cse
*/
template<class N>
oln_type_of(N, window)
- ng_to_se(const oln::abstract::neighborhood<N>& ng)
+ nbh_to_se(const oln::abstract::neighborhood<N>& nbh)
{
oln_type_of(N, window) output;
- for (unsigned i = 0; i < ng.card(); i++)
- output.add(ng[i]);
+ for (unsigned i = 0; i < nbh.card(); i++)
+ output.add(nbh[i]);
return output;
}
@@ -63,16 +63,16 @@
/*! Convert a neighborhood to a window and add the center.
**
- ** \see ng_to_cs
+ ** \see nbh_to_cs
*/
template<class N>
oln_type_of(N, window)
- ng_to_cse(const oln::abstract::neighborhood<N>& ng)
+ nbh_to_cse(const oln::abstract::neighborhood<N>& nbh)
{
oln_type_of(N, window) output;
- for (unsigned i = 0; i < ng.card(); i++)
- output.add(ng[i]);
+ for (unsigned i = 0; i < nbh.card(); i++)
+ output.add(nbh[i]);
oln_type_of(N, dpoint) zero;
dpoint_zero(zero);
@@ -85,4 +85,4 @@
} // oln
-#endif // OLENA_CONVERT_NG_TO_SE_HH
+#endif // OLENA_CONVERT_NBH_TO_SE_HH
Index: oln/core/abstract/internal/image_impl.hh
--- oln/core/abstract/internal/image_impl.hh (revision 114)
+++ oln/core/abstract/internal/image_impl.hh (working copy)
@@ -29,6 +29,7 @@
# define PROTO_OLN_CORE_ABSTRACT_INTERNAL_IMAGE_IMPL_HH
# include <mlc/any.hh>
+# include <mlc/types.hh>
# include <oln/core/properties.hh>
Index: oln/makefile.src
--- oln/makefile.src (revision 114)
+++ oln/makefile.src (working copy)
@@ -14,7 +14,7 @@
basics3d.hh \
config/pconf.hh \
config/system.hh \
- convert/ng_to_se.hh \
+ convert/nbh_to_se.hh \
convert/value_to_point.hh \
core/1d/array1d.hh \
core/1d/dpoint1d.hh \
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 114)
+++ oln/morpho/reconstruction.hh (working copy)
@@ -30,15 +30,20 @@
# include <queue>
-# include <mlc/contract.hh>
# include <mlc/cmp.hh>
+# include <mlc/contract.hh>
-# include <oln/convert/ng_to_se.hh>
-# include <oln/morpho/splitse.hh>
-# include <oln/level/compare.hh>
+# include <oln/convert/nbh_to_se.hh>
+
+# include <oln/core/abstract/image_operator.hh>
# include <oln/core/abstract/neighborhood.hh>
# include <oln/core/properties.hh>
-# include <oln/core/abstract/image_operator.hh>
+
+# include <oln/level/compare.hh>
+
+# include <oln/morpho/splitse.hh>
+# include <oln/morpho/stat.hh>
+
# include <oln/utils/clone.hh>
// FIXME: ADD TESTS !!!!
@@ -73,80 +78,35 @@
{
typedef abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> > super_type;
- const N ng;
+ const N nbh;
reconstruction_ret(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2,
- const abstract::neighborhood<N>& ng) :
+ const abstract::neighborhood<N>& nbh) :
super_type(input1.exact(), input2.exact()),
- ng(ng.exact())
+ nbh(nbh.exact())
{}
};
namespace sequential {
- /*!
- ** \brief Perform a geodesic reconstruction dilation.
- **
- ** Compute the reconstruction by dilation of marker with respect
- ** to the mask image using se as structuring element. Soille
- ** p.160. The algorithm used is the one defined as sequential in
- ** Vincent(1993), Morphological grayscale reconstruction in
- ** image analysis: applications and efficient algorithms, itip,
- ** 2(2), 176--201.
- **
- ** \pre Mask must be greater or equal than marker.
- **
- ** \param I1 Exact type of image marker.
- ** \param I2 Exact type of image mask.
- ** \param N Exact type of neighborhood.
- **
- ** \arg marker Image to work on.
- ** \arg mask Image used for geodesic dilation.
- ** \arg Ng Neighborhood to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/opening.hh>
- ** #include <oln/morpho/reconstruction.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::int_u8> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
- ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
- **
- ** oln::save(oln::morpho::sequential::geodesic_reconstruction_dilation(im2,
- ** im1,
- ** oln::neighb_c4()),
- ** IMG_OUT "oln_morpho_sequential_geodesic_reconstruction_dilation.pbm");
- ** return 0;
- ** }
- ** \endcode
- **
- ** \image html lena128_pgm.png
- ** \image latex lena128_pgm.png
- ** =>
- ** \image html oln_morpho_sequential_geodesic_reconstruction_dilation.png
- ** \image latex oln_morpho_sequential_geodesic_reconstruction_dilation.png
- **
- */
namespace impl {
template <typename I, typename N>
- struct reconstruction_dilation_ret : public reconstruction_ret<I, N>
+ struct reconstruction_sequential_ret : public reconstruction_ret<I, N>
{
typedef reconstruction_ret<I, N> super_type;
- reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
- const abstract::non_vectorial_image<I>& input2, //mask
- const abstract::neighborhood<N>& ng)
- : super_type(input1, input2, ng)
- {}
+ virtual const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v)
+ {
+ std::cerr << "oops in " << __func__ << std::endl;
+ return oln_type_of(I, value)();
+ }
void impl_run()
{
@@ -155,139 +115,153 @@
precondition(level::is_greater_or_equal(this->input2, this->input1));
// Conversion of neighborhood into a SE.
- oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
- oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::nbh_to_cse(this->nbh));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::nbh_to_cse(this->nbh));
I output;
output = utils::clone(this->input1);
bool non_stability = true;
oln_type_of(I, fwd_piter) fwd_p(output.size());
- oln_type_of(I, fwd_piter) bkd_p(output.size());
+ oln_type_of(I, bkd_piter) bkd_p(output.size());
while (non_stability)
{
I work;
work = utils::clone(output);
for_all (fwd_p)
- work[fwd_p] = ntg::min(morpho::max(work, fwd_p, se_plus), this->input2[fwd_p].value());
+ work[fwd_p] = this->process(work, fwd_p, se_plus, this->input2[fwd_p].value());
for_all (bkd_p)
- work[bkd_p] = ntg::min(morpho::max(work, bkd_p, se_minus), this->input2[bkd_p].value());
+ work[bkd_p] = this->process(work, bkd_p, se_minus, this->input2[bkd_p].value());
+
non_stability = !(level::is_equal(work, output));
output = work;
}
this->output = output;
}
+
+ protected:
+ reconstruction_sequential_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& nbh)
+ : super_type(input1, input2, nbh)
+ {}
+
+
};
+
+ template <typename I, typename N>
+ struct reconstruction_dilation_ret : public reconstruction_sequential_ret<I, N>
+ {
+ typedef reconstruction_sequential_ret<I, N> super_type;
+
+ reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& nbh)
+
+ : super_type(input1, input2, nbh)
+ {}
+
+ const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v)
+ {
+ return ntg::min(morpho::max(work, p, se), v);
+ }
+
+ };
+
+
+ template <typename I, typename N>
+ struct reconstruction_erosion_ret : public reconstruction_sequential_ret<I, N>
+ {
+ typedef reconstruction_sequential_ret<I, N> super_type;
+
+ reconstruction_erosion_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& nbh)
+
+ : super_type(input1, input2, nbh)
+ {}
+
+ const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v) const
+ {
+ return ntg::max(morpho::min(work, p, se), v);
+ }
+ };
+
}
template<class I, class N>
reconstruction_ret<I, N>
geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I> & marker,
const abstract::non_vectorial_image<I> & mask,
- const abstract::neighborhood<N>& ng)
+ const abstract::neighborhood<N>& nbh)
{
- impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, ng);
+ impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, nbh);
tmp.run();
return tmp;
}
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
+ geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& nbh)
+ {
+ impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, nbh);
+ tmp.run();
+ return tmp;
+ }
+
}// sequential
namespace hybrid {
- namespace internal {
-
- /*!
- ** \brief Check if it exists initialization for dilation.
- **
- ** \arg p Point to consider.
- ** \arg marker Image to work on.
- ** \arg mask Image used as mask.
- ** \arg Ng Neighborhood to use.
- */
- template<class P, class I1, class I2, class E> inline
- static bool
- exist_init_dilation(const abstract::point<P>& p,
- const abstract::non_vectorial_image<I1>& marker,
- const abstract::non_vectorial_image<I2>& mask,
- const abstract::struct_elt<E>& se)
- {
- oln_type_of(E, fwd_witer) dp(se.exact());
- for_all (dp)
- {
- P q = (oln_type_of(E, dpoint))dp + p.exact();
- if (marker.hold(q) && (marker[q] < marker[p.exact()]) &&
- (marker[q] < mask[q]))
- return true;
- }
- return false;
- }
-
- } //internal
-
- /*!
- ** \brief Perform a geodesic reconstruction dilation.
- **
- ** Compute the reconstruction by dilation of marker with
- ** respect to the mask image using se as structuring
- ** element. Soille p.160. The algorithm used is the one defined
- ** as hybrid in Vincent(1993), Morphological grayscale
- ** reconstruction in image analysis: applications and efficient
- ** algorithms, itip, 2(2), 176--201.
- **
- ** \pre Mask must be greater or equal than marker.
- **
- ** \param I1 Exact type of image marker.
- ** \param I2 Exact type of image mask.
- ** \param N Exact type of neighborhood.
- **
- ** \arg marker Image to work on.
- ** \arg mask Image used for geodesic dilation.
- ** \arg Ng Neighborhood to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/opening.hh>
- ** #include <oln/morpho/reconstruction.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::int_u8> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
- ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
- **
- ** oln::save(oln::morpho::hybrid::geodesic_reconstruction_dilation(im2,
- ** im1,
- ** oln::neighb_c4()),
- ** IMG_OUT "oln_morpho_hybrid_geodesic_reconstruction_dilation.pbm");
- ** return 0;
- ** }
- ** \endcode
- **
- ** \image html lena128_pgm.png
- ** \image latex lena128_pgm.png
- ** =>
- ** \image html oln_morpho_hybrid_geodesic_reconstruction_dilation.png
- ** \image latex oln_morpho_hybrid_geodesic_reconstruction_dilation.png
- **
- */
-
namespace impl {
template <typename I, typename N>
- struct reconstruction_dilation_ret : public reconstruction_ret<I, N>
+ struct reconstruction_hybrid_ret : public reconstruction_ret<I, N>
{
typedef reconstruction_ret<I, N> super_type;
- reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
- const abstract::non_vectorial_image<I>& input2, //mask
- const abstract::neighborhood<N>& ng)
+ reconstruction_hybrid_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ const abstract::non_vectorial_image<I>& input2, //mask
+ const abstract::neighborhood<N>& nbh)
- : super_type(input1, input2, ng)
+ : super_type(input1, input2, nbh)
{}
+ virtual const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v) const
+ {
+ std::cerr << "oops in " << __func__ << std::endl;
+ return oln_type_of(I, value)();
+ }
+
+ virtual void loop_body(const oln_type_of(I, point)& p,
+ const oln_type_of(I, point)& q,
+ oln_type_of(I, concrete)& output,
+ std::queue<oln_type_of(I, point) >& fifo)
+ {
+ std::cerr << "oops in " << __func__ << std::endl;
+ }
+
+ virtual bool exist_init(const oln_type_of(I, point)& p,
+ const oln_type_of(I, concrete)& output,
+ const oln_type_of(N, window)& se) const
+ {
+ std::cerr << "oops in " << __func__ << std::endl;
+ return true;
+ }
+
+
void impl_run()
{
mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
@@ -297,22 +271,19 @@
oln_type_of(I, concrete) output;
output = utils::clone(this->input1);
{
- oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
- oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
+ oln_type_of(N, window) se_plus = get_plus_se_p(convert::nbh_to_cse(this->nbh));
+ oln_type_of(N, window) se_minus = get_minus_se_p(convert::nbh_to_cse(this->nbh));
oln_type_of(I, fwd_piter) fwd_p(output.size());
oln_type_of(I, fwd_piter) bkd_p(output.size());
for_all (fwd_p)
- output[fwd_p] = ntg::min(morpho::max(output, fwd_p, se_plus),
- this->input2[fwd_p].value());
+ output[fwd_p] = this->process(output, fwd_p, se_plus, this->input2[fwd_p].value());
std::queue<oln_type_of(I, point) > fifo;
for_all (bkd_p)
{
- output[bkd_p] = ntg::min(morpho::max(output, bkd_p, se_minus),
- this->input2[bkd_p].value());
- if (internal::exist_init_dilation((oln_type_of(I, point))bkd_p, output,
- this->input2, se_minus))
+ output[bkd_p] = this->process(output, bkd_p, se_minus, this->input2[bkd_p].value());
+ if (this->exist_init((oln_type_of(I, point))bkd_p, output, se_minus))
fifo.push(bkd_p);
}
// Propagation Step
@@ -321,22 +292,13 @@
oln_type_of(I, point) p = fifo.front();
fifo.pop();
typedef oln_type_of(N, window) window_type;
- window_type w = convert::ng_to_se(this->ng);
+ window_type w = convert::nbh_to_se(this->nbh);
oln_type_of(window_type, fwd_witer) dp(w);
for_all (dp)
{
oln_type_of(I, point) q = (oln_type_of(window_type, dpoint))dp + p;
- if (output.hold(q))
- {
- if ((output[q] < output[p]) &&
- (this->input2[q] != output[q]))
- {
- output[q] = ntg::min(output[p].value(),
- this->input2[q].value());
- fifo.push(q);
- }
- }
+ this->loop_body(p, q, output, fifo);
}
}
}
@@ -344,294 +306,144 @@
}
};
- }
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I> & marker,
- const abstract::non_vectorial_image<I> & mask,
- const abstract::neighborhood<N>& ng)
- {
- impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, ng);
- tmp.run();
- return tmp;
- }
- }// hybrid
-
-
- namespace sequential {
-
- /*!
- ** \brief Perform a geodesic reconstruction erosion.
- **
- ** Compute the reconstruction by erosion of marker with respect
- ** to the mask image using se as structuring element. Soille
- ** p.160. The algorithm used is the one defined as sequential
- ** in Vincent(1993), Morphological grayscale reconstruction in
- ** image analysis: applications and efficient algorithms, itip,
- ** 2(2), 176--201.
- **
- ** \pre Marker must be greater or equal than mask.
- **
- ** \param I1 Exact type of image marker.
- ** \param I2 Exact type of image mask.
- ** \param N Exact type of neighborhood.
- **
- ** \arg marker Image to work on.
- ** \arg mask Image used for geodesic erosion.
- ** \arg Ng Neighborhood to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/opening.hh>
- ** #include <oln/morpho/reconstruction.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::int_u8> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
- ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
- **
- ** oln::save(oln::morpho::sequential::geodesic_reconstruction_erosion(im1,
- ** im2,
- ** oln::neighb_c4()),
- ** IMG_OUT "oln_morpho_sequential_geodesic_reconstruction_erosion.pbm");
- ** return 0;
- ** }
- ** \endcode
- **
- ** \image html lena128_pgm.png
- ** \image latex lena128_pgm.png
- ** =>
- ** \image html oln_morpho_sequential_geodesic_reconstruction_erosion.png
- ** \image latex oln_morpho_sequential_geodesic_reconstruction_erosion.png
- **
- */
-
-
- namespace impl {
-
template <typename I, typename N>
- struct reconstruction_erosion_ret : public reconstruction_ret<I, N>
+ struct reconstruction_dilation_ret : public reconstruction_hybrid_ret<I, N>
{
- typedef reconstruction_ret<I, N> super_type;
+ typedef reconstruction_hybrid_ret<I, N> super_type;
- reconstruction_erosion_ret(const abstract::non_vectorial_image<I>& input1, //marker
+ reconstruction_dilation_ret(const abstract::non_vectorial_image<I>& input1, //marker
const abstract::non_vectorial_image<I>& input2, //mask
- const abstract::neighborhood<N>& ng)
+ const abstract::neighborhood<N>& nbh)
- : super_type(input1, input2, ng)
+ : super_type(input1, input2, nbh)
{}
- void impl_run()
+ const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v) const
{
- mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
- precondition(this->input1.size() == this->input2.size());
- precondition(level::is_greater_or_equal(this->input2, this->input1));
+ return ntg::min(morpho::max(work, p, se), v);
+ }
- // Conversion of neighborhood into a SE.
- oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
- oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
-
- I output;
- output = utils::clone(this->input1);
- bool non_stability = true;
- oln_type_of(I, fwd_piter) fwd_p(output.size());
- oln_type_of(I, fwd_piter) bkd_p(output.size());
- while (non_stability)
+ virtual void loop_body(const oln_type_of(I, point)& p,
+ const oln_type_of(I, point)& q,
+ oln_type_of(I, concrete)& output,
+ std::queue<oln_type_of(I, point) >& fifo)
+ {
+ if (output.hold(q))
{
- I work;
- work = utils::clone(output);
- for_all (fwd_p)
- work[fwd_p] = ntg::max(morpho::min(work, fwd_p, se_plus),
- this->input2[fwd_p].value());
- for_all (bkd_p)
- work[bkd_p] = ntg::max(morpho::min(work, bkd_p, se_minus),
- this->input2[bkd_p].value());
- non_stability = !(level::is_equal(work, output));
- output = work;
+ if ((output[q] < output[p]) &&
+ (this->input2[q] != output[q]))
+ {
+ output[q] = ntg::min(output[p].value(),
+ this->input2[q].value());
+ fifo.push(q);
+ }
}
- this->output = output;
+
}
- };
- }
- template<class I, class N>
- reconstruction_ret<I, N>
- geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I> & marker,
- const abstract::non_vectorial_image<I> & mask,
- const abstract::neighborhood<N>& ng)
- {
- impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, ng);
- tmp.run();
- return tmp;
- }
+ virtual bool exist_init(const oln_type_of(I, point)& p,
+ const oln_type_of(I, concrete)& marker,
+ const oln_type_of(N, window)& se) const
+ {
+ typedef oln_type_of(N, window) se_type;
+ oln_type_of(se_type, fwd_witer) dp(se);
+ for_all (dp)
+ {
+ oln_type_of(I, point) q = (oln_type_of(se_type, dpoint))dp + p;
+ if (marker.hold(q) && (marker[q] < marker[p]) &&
+ (marker[q] < this->input2[q]))
+ return true;
+ }
+ return false;
+ }
- } // sequential
+ };
- namespace hybrid {
- namespace internal {
- /*!
- ** \brief Check if it exists initialization for erosion.
- **
- ** \arg p Point to consider.
- ** \arg marker Image to work on.
- ** \arg mask Image used as mask.
- ** \arg Ng Neighborhood to use.
- */
- template<class P, class I1, class I2, class E> inline
- static bool
- exist_init_erosion(const abstract::point<P>& p,
- const abstract::non_vectorial_image<I1>& marker,
- const abstract::non_vectorial_image<I2>& mask,
- const abstract::struct_elt<E>& se)
- {
- oln_type_of(E, fwd_witer) dp(se.exact());
- for_all (dp)
- {
- P q = (oln_type_of(E, dpoint))dp + p.exact();
- if (marker.hold(q) && (marker[q] > marker[p.exact()]) &&
- (marker[q] > mask[q]))
- return true;
- }
- return false;
- }
-
- } //internal
-
- /*!
- ** \brief Perform a geodesic reconstruction erosion.
- **
- ** Compute the reconstruction by erosion of marker with respect
- ** to the mask mask image using se as structuring
- ** element. Soille p.160. The algorithm used is the one defined
- ** as hybrid in Vincent(1993), Morphological grayscale
- ** reconstruction in image analysis: applications and efficient
- ** algorithms, itip, 2(2), 176--201.
- **
- ** \pre Marker must be greater or equal than mask.
- **
- ** \param I1 Exact type of image marker.
- ** \param I2 Exact type of image mask.
- ** \param N Exact type of neighborhood.
- **
- ** \arg marker Image to work on.
- ** \arg mask Image used for geodesic erosion.
- ** \arg Ng Neighborhood to use.
- **
- ** \code
- ** #include <oln/basics2d.hh>
- ** #include <oln/morpho/opening.hh>
- ** #include <oln/morpho/reconstruction.hh>
- ** #include <oln/level/compare.hh>
- ** #include <ntg/all.hh>
- ** int main()
- ** {
- ** typedef oln::image2d<ntg::int_u8> im_type;
- **
- ** im_type im1(oln::load(IMG_IN "lena128.pgm"));
- ** im_type im2 = oln::morpho::opening(im1, oln::win_c4p());
- **
- ** oln::save(oln::morpho::hybrid::geodesic_reconstruction_erosion(im1,
- ** im2,
- ** oln::neighb_c4()),
- ** IMG_OUT "oln_morpho_hybrid_geodesic_reconstruction_erosion.pbm");
- ** return 0;
- ** }
- ** \endcode
- **
- ** \image html lena128_pgm.png
- ** \image latex lena128_pgm.png
- ** =>
- ** \image html oln_morpho_hybrid_geodesic_reconstruction_erosion.png
- ** \image latex oln_morpho_hybrid_geodesic_reconstruction_erosion.png
- **
- */
-
- namespace impl {
-
template <typename I, typename N>
- struct reconstruction_erosion_ret : public reconstruction_ret<I, N>
+ struct reconstruction_erosion_ret : public reconstruction_hybrid_ret<I, N>
{
- typedef reconstruction_ret<I, N> super_type;
+ typedef reconstruction_hybrid_ret<I, N> super_type;
reconstruction_erosion_ret(const abstract::non_vectorial_image<I>& input1, //marker
const abstract::non_vectorial_image<I>& input2, //mask
- const abstract::neighborhood<N>& ng)
+ const abstract::neighborhood<N>& nbh)
- : super_type(input1, input2, ng)
+ : super_type(input1, input2, nbh)
{}
- void impl_run()
+ const oln_type_of(I, value) process(const I& work,
+ const oln_type_of(I, point)& p,
+ const oln_type_of(N, window)& se,
+ const oln_type_of(I, value)& v) const
{
- mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
- precondition(this->input1.size() == this->input2.size());
- precondition(level::is_greater_or_equal(this->input2, this->input1));
+ return ntg::max(morpho::min(work, p, se), v);
+ }
- oln_type_of(I, concrete) output;
- output = utils::clone(this->input1);
- {
- oln_type_of(N, window) se_plus = get_plus_se_p(convert::ng_to_cse(this->ng));
- oln_type_of(N, window) se_minus = get_minus_se_p(convert::ng_to_cse(this->ng));
- oln_type_of(I, fwd_piter) fwd_p(output.size());
- oln_type_of(I, fwd_piter) bkd_p(output.size());
+ virtual void loop_body(const oln_type_of(I, point)& p,
+ const oln_type_of(I, point)& q,
+ oln_type_of(I, concrete)& output,
+ std::queue<oln_type_of(I, point) >& fifo)
+ {
+ if (output.hold(q))
+ {
+ if ((output[q] > output[p]) &&
+ (this->input2[q] != output[q]))
+ {
+ output[q] = ntg::max(output[p].value(),
+ this->input2[q].value());
+ fifo.push(q);
+ }
+ }
+ }
- for_all (fwd_p)
- output[fwd_p] = ntg::max(morpho::min(output, fwd_p, se_plus),
- this->input2[fwd_p].value());
- std::queue<oln_type_of(I, point) > fifo;
- for_all (bkd_p)
- {
- output[bkd_p] = ntg::max(morpho::min(output, bkd_p, se_minus),
- this->input2[bkd_p].value());
- if (internal::exist_init_erosion((oln_type_of(I, point))bkd_p, output,
- this->input2, se_minus))
- fifo.push(bkd_p);
- }
- // Propagation Step
- while (!fifo.empty())
- {
- oln_type_of(I, point) p = fifo.front();
- fifo.pop();
- typedef oln_type_of(N, window) window_type;
- window_type w = convert::ng_to_se(this->ng);
- oln_type_of(window_type, fwd_witer) dp(w);
-
- for_all (dp)
- {
- oln_type_of(I, point) q = (oln_type_of(window_type, dpoint))dp + p;
- if (output.hold(q))
- {
- if ((output[q] > output[p]) &&
- (this->input2[q] != output[q]))
- {
- output[q] = ntg::max(output[p].value(),
- this->input2[q].value());
- fifo.push(q);
- }
- }
- }
- }
- }
- this->output = output;
+ virtual bool exist_init(const oln_type_of(I, point)& p,
+ const oln_type_of(I, concrete)& marker,
+ const oln_type_of(N, window)& se) const
+ {
+ typedef oln_type_of(N, window) se_type;
+ oln_type_of(se_type, fwd_witer) dp(se);
+ for_all (dp)
+ {
+ oln_type_of(I, point) q = (oln_type_of(se_type, dpoint))dp + p;
+ if (marker.hold(q) && (marker[q] > marker[p]) &&
+ (marker[q] > this->input2[q]))
+ return true;
+ }
+ return false;
}
+
};
+
+
}
template<class I, class N>
reconstruction_ret<I, N>
+ geodesic_reconstruction_dilation(const abstract::non_vectorial_image<I> & marker,
+ const abstract::non_vectorial_image<I> & mask,
+ const abstract::neighborhood<N>& nbh)
+ {
+ impl::reconstruction_dilation_ret<I, N> tmp(marker, mask, nbh);
+ tmp.run();
+ return tmp;
+ }
+
+ template<class I, class N>
+ reconstruction_ret<I, N>
geodesic_reconstruction_erosion(const abstract::non_vectorial_image<I> & marker,
const abstract::non_vectorial_image<I> & mask,
- const abstract::neighborhood<N>& ng)
+ const abstract::neighborhood<N>& nbh)
{
- impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, ng);
+ impl::reconstruction_erosion_ret<I, N> tmp(marker, mask, nbh);
tmp.run();
return tmp;
}
Index: oln/morpho/cc_tarjan.hh
--- oln/morpho/cc_tarjan.hh (revision 114)
+++ oln/morpho/cc_tarjan.hh (working copy)
@@ -53,7 +53,7 @@
// category
template <typename T, typename I, typename E>
- struct set_category< morpho::cc_tarjan_ret<T,I,E> >
+ struct set_category< morpho::cc_tarjan_ret<T,I,E> >
{ typedef category::image ret; };
// super_type
@@ -61,7 +61,7 @@
struct set_super_type< morpho::cc_tarjan_ret<T,I,E> >
{
typedef abstract::image_unary_operator
- <tmp_mute(I, T), I, morpho::cc_tarjan_ret<T, I, E> >
+ <tmp_mute(I, T), I, morpho::cc_tarjan_ret<T, I, E> >
ret;
};
@@ -69,24 +69,24 @@
namespace morpho {
template <typename T, typename I, typename E>
- struct cc_tarjan_ret
+ struct cc_tarjan_ret
: public abstract::image_unary_operator
<tmp_mute(I, T), I, cc_tarjan_ret<T, I, E> >
{
typedef abstract::image_unary_operator
- <tmp_mute(I, T), I, cc_tarjan_ret<T, I, E> >
+ <tmp_mute(I, T), I, cc_tarjan_ret<T, I, E> >
super_type;
typedef typename super_type::output_type output_type;
const E ng;
-
+
cc_tarjan_ret(const abstract::image<I>& input,
const abstract::neighborhood<E>& ng) :
super_type(input),
ng(ng.exact())
{
}
-
+
};
@@ -123,8 +123,8 @@
}
} // end of misc namespace
-
+
template <typename T, typename I, typename N>
struct generic_cc_tarjan : public cc_tarjan_ret<T, I, N>
{
@@ -143,8 +143,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(N, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
output_type tmp(this->input.size()); // FIXME: trick
this->output = tmp;
@@ -167,20 +166,20 @@
if (this->input[n])
do_union(n, p);
}
- }
+ }
}
void second_pass()
{
oln_type_of(I, fwd_piter) p(this->input.size());
- level::fill(output, 0);
+ level::fill(this->output, 0);
ncomps = 0;
for_all(p)
if (this->input[p])
- {
+ {
oln_type_of(I, point) q = parent[p];
// FIXME: test if ncomps > T::max()
- output[p] = (q == p ? ++ncomps : output[q]);
+ this->output[p] = (q == p ? ++ncomps : this->output[q]);
}
}
@@ -198,16 +197,16 @@
}
return x;
}
-
- void do_union(const oln_type_of(I, point)& n,
+
+ void do_union(const oln_type_of(I, point)& n,
const oln_type_of(I, point)& p)
{
oln_type_of(I, point) r = find_root(n);
if (r != p)
parent[r] = p;
}
-
-
+
+
};
} // end of namespace oln::morpho::impl
Index: oln/arith/min.hh
--- oln/arith/min.hh (revision 114)
+++ oln/arith/min.hh (working copy)
@@ -29,7 +29,8 @@
# define OLENA_ARITH_MIN_HH
# include <oln/basics.hh>
-# include <oln/core/abstract/op.hh>
+# include <oln/core/abstract/image_operator.hh>
+
# include <ntg/all.hh>
namespace oln {
@@ -53,7 +54,7 @@
template <typename I>
struct set_super_type< arith::impl::min_type<I> >
{
- typedef abstract::op<I, arith::impl::min_type<I> > ret;
+ typedef abstract::image_binary_operator<I, I, I, arith::impl::min_type<I> > ret;
};
namespace arith {
@@ -61,27 +62,25 @@
namespace impl {
template <class I>
- struct min_type : public abstract::op<I, min_type<I> >
+ struct min_type : public abstract::image_binary_operator<I, I, I, min_type<I> >
{
- box<const I> input1_;
- box<const I> input2_;
+ typedef abstract::image_binary_operator<I, I, I, min_type<I> > super_type;
min_type(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2) :
- input1_(input1.exact()),
- input2_(input2.exact())
+ super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
- precondition(input1_.size() == input2_.size());
- I output(input1_.size());
- oln_type_of(I, fwd_piter) p(input1_.size());
+ precondition(this->input1.size() == this->input2.size());
+ I output(this->input1.size());
+ oln_type_of(I, fwd_piter) p(this->input1.size());
for_all(p)
- output[p] = ntg::min(input1_[p].value(), input2_[p].value());
+ output[p] = ntg::min(this->input1[p].value(), this->input2[p].value());
- this->image_ = output;
+ this->output = output;
}
};
Index: oln/arith/max.hh
--- oln/arith/max.hh (revision 114)
+++ oln/arith/max.hh (working copy)
@@ -29,7 +29,8 @@
# define OLENA_ARITH_MAX_HH
# include <oln/basics.hh>
-# include <oln/core/abstract/op.hh>
+# include <oln/core/abstract/image_operator.hh>
+
# include <ntg/all.hh>
namespace oln {
@@ -53,7 +54,7 @@
template <typename I>
struct set_super_type< arith::impl::max_type<I> >
{
- typedef abstract::op<I, arith::impl::max_type<I> > ret;
+ typedef abstract::image_binary_operator<I, I, I, arith::impl::max_type<I> > ret;
};
namespace arith {
@@ -61,27 +62,25 @@
namespace impl {
template <class I>
- struct max_type : public abstract::op<I, max_type<I> >
+ struct max_type : public abstract::image_binary_operator<I, I, I, max_type<I> >
{
- box<const I> input1_;
- box<const I> input2_;
+ typedef abstract::image_binary_operator<I, I, I, max_type<I> > super_type;
max_type(const abstract::non_vectorial_image<I>& input1,
const abstract::non_vectorial_image<I>& input2) :
- input1_(input1.exact()),
- input2_(input2.exact())
+ super_type(input1.exact(), input2.exact())
{}
void impl_run()
{
- precondition(input1_.size() == input2_.size());
- I output(input1_.size());
- oln_type_of(I, fwd_piter) p(input1_.size());
+ precondition(this->input1.size() == this->input2.size());
+ I output(this->input1.size());
+ oln_type_of(I, fwd_piter) p(this->input1.size());
for_all(p)
- output[p] = ntg::max(input1_[p].value(), input2_[p].value());
+ output[p] = ntg::max(this->input1[p].value(), this->input2[p].value());
- this->image_ = output;
+ this->output = output;
}
};
1
0
2005-04-06 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* mlc/properties.hh: Replace macro use by real code.
* mlc/cmp.hh (ensure): New method.
Index: mlc/properties.hh
===================================================================
--- mlc/properties.hh (revision 111)
+++ mlc/properties.hh (working copy)
@@ -116,53 +116,53 @@
/// macro to register a property in a props_of<..>:
-# define mlc_register_prop(CATEGORY, TARGET) \
- \
-namespace internal \
-{ \
- \
- template <> \
- struct get_prop < CATEGORY, mlc::no_type, target::TARGET > \
- { \
- typedef props_of<CATEGORY, mlc::default_type>:: TARGET ret; \
- }; \
- \
- template <typename type> \
- struct get_prop < CATEGORY, type, target::TARGET > \
- { \
- typedef get_prop_helper<CATEGORY, type, target::TARGET, \
- mlc_eq(type, mlc::no_type), \
- typename get_props<CATEGORY, type>::user_defined_ \
- > helper_type; \
- typedef typename helper_type::ret ret; \
- }; \
- template <typename type> \
- struct get_prop_helper < CATEGORY, type, target::TARGET, mlc::false_type, \
- mlc::true_type > \
- { \
- typedef typename get_props<CATEGORY, type>:: TARGET prop_type; \
- typedef typename get_prop<CATEGORY, \
- typename get_super_type<type>::ret, \
- target::TARGET>::ret super_prop_type; \
- \
- typedef mlc_if( mlc_eq(prop_type, mlc::unknown_type), \
- super_prop_type, \
- prop_type ) ret; \
- }; \
- template <typename type> \
- struct get_prop_helper < CATEGORY, type, target::TARGET, mlc::false_type, \
- mlc::false_type > \
- { \
- typedef typename get_prop<CATEGORY, \
- typename get_super_type<type>::ret, \
- target::TARGET>::ret ret; \
- }; \
-} \
- \
-template <typename type> \
-struct set_type_of < CATEGORY, type, target::TARGET > \
-{ \
- typedef typename internal::get_prop<CATEGORY, type, target::TARGET>::ret ret; \
+# define mlc_register_prop(CATEGORY, TARGET) \
+ \
+namespace internal \
+{ \
+ \
+ template <> \
+ struct get_prop < CATEGORY, mlc::no_type, target::TARGET > \
+ { \
+ typedef props_of<CATEGORY, mlc::default_type>:: TARGET ret; \
+ }; \
+ \
+ template <typename type> \
+ struct get_prop < CATEGORY, type, target::TARGET > \
+ { \
+ typedef get_prop_helper<CATEGORY, type, target::TARGET, \
+ mlc_eq(type, mlc::no_type), \
+ typename get_props<CATEGORY, type>::user_defined_ \
+ > helper_type; \
+ typedef typename helper_type::ret ret; \
+ }; \
+ template <typename type> \
+ struct get_prop_helper < CATEGORY, type, target::TARGET, mlc::false_type, \
+ mlc::true_type > \
+ { \
+ typedef typename get_props<CATEGORY, type>:: TARGET prop_type; \
+ typedef typename get_prop<CATEGORY, \
+ typename get_super_type<type>::ret, \
+ target::TARGET>::ret super_prop_type; \
+ \
+ typedef typename mlc::if_< typename mlc::eq<prop_type, mlc::unknown_type>::ret, \
+ super_prop_type, \
+ prop_type >::ret ret; \
+ }; \
+ template <typename type> \
+ struct get_prop_helper < CATEGORY, type, target::TARGET, mlc::false_type, \
+ mlc::false_type > \
+ { \
+ typedef typename get_prop<CATEGORY, \
+ typename get_super_type<type>::ret, \
+ target::TARGET>::ret ret; \
+ }; \
+} \
+ \
+template <typename type> \
+struct set_type_of < CATEGORY, type, target::TARGET > \
+{ \
+ typedef typename internal::get_prop<CATEGORY, type, target::TARGET>::ret ret; \
}
@@ -176,21 +176,23 @@
/// macros to declare a property:
-# define mlc_decl_prop_with_default(CATEGORY, NAME, DEFAULT) \
- typedef mlc_if(mlc_eq(type, mlc::default_type), \
- DEFAULT, \
- mlc_if(mlc_eq(type, mlc::no_type), \
- mlc::unknown_type, \
- mlc_internal_retrieve_prop(CATEGORY, type, NAME)) \
- ) NAME
+# define mlc_decl_prop_with_default(CATEGORY, NAME, DEFAULT) \
+ typedef typename mlc::if_<typename mlc::eq<type, mlc::default_type>::ret, \
+ DEFAULT, \
+ typename mlc::if_<typename mlc::eq<type, mlc::no_type>::ret, \
+ mlc::unknown_type, \
+ mlc_internal_retrieve_prop(CATEGORY, type, NAME) \
+ >::ret \
+ >::ret NAME
-# define mlc_decl_prop(CATEGORY, NAME) \
- typedef mlc_if(mlc_eq(type, mlc::default_type), \
- mlc::undefined_type, \
- mlc_if(mlc_eq(type, mlc::no_type), \
- mlc::unknown_type, \
- mlc_internal_retrieve_prop(CATEGORY, type, NAME)) \
- ) NAME
+# define mlc_decl_prop(CATEGORY, NAME) \
+ typedef typename mlc::if_<typename mlc::eq<type, mlc::default_type>::ret, \
+ mlc::undefined_type, \
+ typename mlc::if_<typename mlc::eq<type, mlc::no_type>::ret, \
+ mlc::unknown_type, \
+ mlc_internal_retrieve_prop(CATEGORY, type, NAME) \
+ >::ret \
+ >::ret NAME
Index: mlc/cmp.hh
===================================================================
--- mlc/cmp.hh (revision 111)
+++ mlc/cmp.hh (working copy)
@@ -51,6 +51,7 @@
struct eq <T, T>
{
typedef true_type ret;
+ static void ensure() {}
};
@@ -60,6 +61,7 @@
struct neq
{
typedef true_type ret;
+ static void ensure() {}
};
template <typename T>
1
0
2005-04-05 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/pw/image.hh: Conform to mlc macros.
* oln/core/abstract/image_vectorialness.hh: Likewise.
* oln/core/abstract/point.hh: Likewise.
* oln/core/abstract/size.hh: Likewise.
* oln/basics2d.hh: Likewise.
* oln/morpho/reconstruction.hh: Likewise.
* oln/morpho/dilation.hh: Likewise.
* oln/morpho/stat.hh: Likewise.
* oln/morpho/erosion.hh: Likewise.
Index: oln/core/pw/image.hh
===================================================================
--- oln/core/pw/image.hh (revision 112)
+++ oln/core/pw/image.hh (working copy)
@@ -243,12 +243,7 @@
template <typename F>
bool check(const pw::abstract::function<F>& pred)
{
- // FIXME: ugly syntax
- // FIXME: bool or bin or...
- mlc::is_true<
- mlc::type::eq< oln_pw_value_type(F), bool >::ret
- >::ensure();
-
+ mlc::eq< oln_pw_value_type(F), bool >::ensure();
return oln::check(for_all_p(pred));
}
Index: oln/core/abstract/image_vectorialness.hh
===================================================================
--- oln/core/abstract/image_vectorialness.hh (revision 112)
+++ oln/core/abstract/image_vectorialness.hh (working copy)
@@ -28,12 +28,11 @@
#ifndef OLENA_CORE_ABSTRACT_IMAGE_VECTORIALNESS_HH
# define OLENA_CORE_ABSTRACT_IMAGE_VECTORIALNESS_HH
-# include <mlc/bool.hh>
-
+# include <mlc/switch.hh>
# include <ntg/basics.hh>
-
# include <oln/core/abstract/image.hh>
+
/*! \namespace oln
** \brief oln namespace.
*/
Index: oln/core/abstract/point.hh
===================================================================
--- oln/core/abstract/point.hh (revision 112)
+++ oln/core/abstract/point.hh (working copy)
@@ -43,7 +43,7 @@
-# define oln_point_type_from_2(P1, P2) mlc_if( mlc_eq( P2, oln::any_point ), P1, P2 )
+# define oln_point_type_from_2(P1, P2) typename mlc::if_< typename mlc::eq< P2, oln::any_point >::ret, P1, P2 >::ret
Index: oln/core/abstract/size.hh
===================================================================
--- oln/core/abstract/size.hh (revision 112)
+++ oln/core/abstract/size.hh (working copy)
@@ -39,10 +39,12 @@
}
-# define oln_size_type_from_2(S1, S2) mlc_if( mlc_eq( S2, oln::any_size ), S1, S2 )
+# define oln_size_type_from_2(S1, S2) typename mlc::if_< typename mlc::eq< S2, oln::any_size >::ret, S1, S2 >::ret
+
+
namespace oln {
namespace abstract {
Index: oln/basics2d.hh
===================================================================
--- oln/basics2d.hh (revision 112)
+++ oln/basics2d.hh (working copy)
@@ -31,7 +31,6 @@
# include <oln/basics.hh>
-
# include <oln/core/2d/size2d.hh>
# include <oln/core/2d/point2d.hh>
# include <oln/core/2d/image2d.hh>
Index: oln/morpho/reconstruction.hh
===================================================================
--- oln/morpho/reconstruction.hh (revision 112)
+++ oln/morpho/reconstruction.hh (working copy)
@@ -31,6 +31,8 @@
# include <queue>
# include <mlc/contract.hh>
+# include <mlc/cmp.hh>
+
# include <oln/convert/ng_to_se.hh>
# include <oln/morpho/splitse.hh>
# include <oln/level/compare.hh>
@@ -148,8 +150,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(N, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
precondition(this->input1.size() == this->input2.size());
precondition(level::is_greater_or_equal(this->input2, this->input1));
@@ -289,8 +290,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(N, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
precondition(this->input1.size() == this->input2.size());
precondition(level::is_greater_or_equal(this->input2, this->input1));
@@ -427,8 +427,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(N, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
precondition(this->input1.size() == this->input2.size());
precondition(level::is_greater_or_equal(this->input2, this->input1));
@@ -570,8 +569,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(N, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(N, size)>::ensure();
precondition(this->input1.size() == this->input2.size());
precondition(level::is_greater_or_equal(this->input2, this->input1));
Index: oln/morpho/dilation.hh
===================================================================
--- oln/morpho/dilation.hh (revision 112)
+++ oln/morpho/dilation.hh (working copy)
@@ -33,6 +33,7 @@
# include <oln/core/abstract/image_operator.hh>
# include <mlc/cmp.hh>
+
namespace oln {
namespace morpho {
@@ -169,8 +170,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(S, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(S, size)>::ensure();
output_type tmp(this->input.size()); // FIXME: trick
this->output = tmp;
Index: oln/morpho/stat.hh
===================================================================
--- oln/morpho/stat.hh (revision 112)
+++ oln/morpho/stat.hh (working copy)
@@ -30,7 +30,9 @@
# include <oln/basics.hh>
# include <ntg/bin.hh>
+# include <mlc/cmp.hh>
+
namespace oln {
namespace morpho {
@@ -64,8 +66,7 @@
max(const I& input, const oln_type_of(I, point)& p, const E& se)
{
// FIXME: test dim I == dim
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(E, size)>::ensure();
oln_type_of(E, fwd_witer) dp(se);
dp.start();
@@ -91,8 +92,7 @@
min(const I& input, const oln_type_of(I, point)& p, const E& se)
{
// FIXME: test dim I == dim E
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(E, size)>::ensure();
oln_type_of(E, fwd_witer) dp(se);
dp.start();
@@ -114,8 +114,7 @@
static ntg::bin
max(const I& input, const oln_type_of(I, point)& p, const E& se)
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(E, size)>::ensure();
oln_type_of(E, fwd_witer) dp(se);
for_all (dp)
if (input.hold(p + dp))
@@ -127,8 +126,7 @@
static ntg::bin
min(const I& input, const oln_type_of(I, point)& p, const E& se)
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(E, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(E, size)>::ensure();
oln_type_of(E, fwd_witer) dp(se);
for_all (dp)
if (input.hold(p + dp))
Index: oln/morpho/erosion.hh
===================================================================
--- oln/morpho/erosion.hh (revision 112)
+++ oln/morpho/erosion.hh (working copy)
@@ -160,8 +160,7 @@
void impl_run()
{
- mlc::is_true<mlc::type::eq<oln_type_of(I, size),
- oln_type_of(S, size)>::ret>::ensure();
+ mlc::eq<oln_type_of(I, size), oln_type_of(S, size)>::ensure();
output_type tmp(this->input.size()); // FIXME: trick
this->output = tmp;
1
0
2005-04-05 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
Conform to mlc.
* ntg/core/math.hh: Delete cause redundant with mlc/arith.hh.
* ntg/real/int_s.hh: Update.
* ntg/real/int_u.hh: Likewise.
* ntg/real/behavior.hh: Likewise.
* ntg/core/macros.hh: Likewise.
* ntg/core/pred_succ.hh: Likewise.
* ntg/core/internal/global_ops_traits.hh: Likewise.
Index: ntg/real/int_s.hh
===================================================================
--- ntg/real/int_s.hh (revision 111)
+++ ntg/real/int_s.hh (working copy)
@@ -35,7 +35,7 @@
# include <ntg/real/int_u.hh>
# include <mlc/bool.hh>
-# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
# include <mlc/is_a.hh>
# include <string>
@@ -356,8 +356,8 @@
struct operator_traits<operator_plus, int_s<nbits, B1>, int_s<mbits, B2> >
{
enum { commutative = true,
- need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
- typedef int_s<(unsigned)mlc::maxN<nbits + 1,mbits + 1, 32>::ret,
+ need_check = (mlc::on<unsigned>::max<nbits, mbits>::ret >= 32) };
+ typedef int_s<mlc::on<unsigned>::maxN<nbits + 1,mbits + 1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -371,7 +371,7 @@
{
enum { commutative = true,
need_check = ((mbits >= 31) || (nbits >= 32)) };
- typedef int_s<(unsigned)mlc::maxN<nbits + 1,mbits + 2, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::maxN<nbits + 1,mbits + 2, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -389,7 +389,7 @@
{
enum { commutative = true,
need_check = ((mbits >= 31) || (nbits >= 31)) };
- typedef int_s<(unsigned)mlc::maxN<nbits + 1, mbits + 1, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::maxN<nbits + 1, mbits + 1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -402,7 +402,7 @@
{
enum { commutative = true,
need_check = ((mbits >= 31) || (nbits >= 32)) };
- typedef int_s<(unsigned)mlc::maxN<nbits + 1, mbits + 2, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::maxN<nbits + 1, mbits + 2, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -420,7 +420,7 @@
{
enum { commutative = true,
need_check = (mbits + nbits > 32) };
- typedef int_s<(unsigned)mlc::saturateN<nbits + mbits, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::saturateN<nbits + mbits, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -434,7 +434,7 @@
{
enum { commutative = true,
need_check = (nbits + mbits + 1 > 32)};
- typedef int_s<(unsigned)mlc::saturateN<nbits + mbits+1, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::saturateN<nbits + mbits+1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -471,7 +471,7 @@
{
enum { commutative = false,
need_check = (mbits >= 32) };
- typedef int_s<mlc::saturateN<mbits + 1, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::saturateN<mbits + 1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -498,7 +498,7 @@
{
enum { commutative = false,
need_check = (mbits >= 32) };
- typedef int_s<(unsigned)mlc::saturateN<mbits + 1, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::saturateN<mbits + 1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -528,7 +528,7 @@
struct operator_traits<operator_min, int_s<nbits, B1>, int_s<mbits, B2> >
{
enum { commutative = true };
- typedef int_s<(unsigned) mlc::min<nbits, mbits>::ret,
+ typedef int_s<mlc::on<unsigned>::min<nbits, mbits>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits, force> impl;
};
@@ -543,7 +543,7 @@
struct operator_traits<operator_max, int_s<nbits, B1>, int_s<mbits, B2> >
{
enum { commutative = true };
- typedef int_s<(unsigned) mlc::max<nbits, mbits>::ret,
+ typedef int_s<mlc::on<unsigned>::max<nbits, mbits>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_s<nbits, force> impl;
};
@@ -558,7 +558,7 @@
struct operator_traits<operator_cmp, int_s<nbits, B1>, int_s<mbits, B2> >
{
enum { commutative = true };
- typedef int_s<(unsigned)mlc::maxN<nbits,mbits,32>::ret, unsafe> ret;
+ typedef int_s<mlc::on<unsigned>::maxN<nbits,mbits,32>::ret, unsafe> ret;
typedef int_s<nbits, force> impl;
};
@@ -569,7 +569,7 @@
struct operator_traits<operator_cmp, int_s<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true };
- typedef int_s<(unsigned)mlc::maxN<nbits,mbits+1, 32>::ret, unsafe> ret;
+ typedef int_s<mlc::on<unsigned>::maxN<nbits,mbits+1, 32>::ret, unsafe> ret;
typedef int_s<nbits, force> impl;
};
Index: ntg/real/int_u.hh
===================================================================
--- ntg/real/int_u.hh (revision 111)
+++ ntg/real/int_u.hh (working copy)
@@ -34,7 +34,7 @@
# include <ntg/bin.hh>
# include <mlc/bool.hh>
-# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
# include <mlc/is_a.hh>
# include <string>
@@ -97,7 +97,7 @@
typedef self base_type;
typedef typename C_for_int_u<nbits>::type storage_type;
- typedef int_s<mlc::saturateN<nbits+1, 32>::ret,
+ typedef int_s<mlc::on<unsigned>::saturateN<nbits+1, 32>::ret,
behavior> signed_type;
typedef self unsigned_type;
// FIXME: calculate it more precisely
@@ -279,8 +279,8 @@
struct operator_traits<operator_plus, int_u<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true,
- need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
- typedef int_u<(unsigned) mlc::maxN<nbits + 1, mbits + 1, 32>::ret,
+ need_check = (mlc::on<unsigned>::max<nbits, mbits>::ret >= 32) };
+ typedef int_u<mlc::on<unsigned>::maxN<nbits + 1, mbits + 1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_u<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -296,8 +296,8 @@
struct operator_traits<operator_minus, int_u<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true,
- need_check = ((unsigned) mlc::max<nbits, mbits>::ret >= 32) };
- typedef int_s<(unsigned) mlc::maxN<nbits+1, mbits+1, 32>::ret,
+ need_check = (mlc::on<unsigned>::max<nbits, mbits>::ret >= 32) };
+ typedef int_s<mlc::on<unsigned>::maxN<nbits+1, mbits+1, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_u<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -324,7 +324,7 @@
struct operator_traits<operator_times, int_u<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true, need_check = (nbits + mbits > 32) };
- typedef int_u<(unsigned) mlc::saturateN<nbits + mbits, 32>::ret,
+ typedef int_u<mlc::on<unsigned>::saturateN<nbits + mbits, 32>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_u<nbits,
typename ret_behavior_if<need_check, ret>::ret> impl;
@@ -368,7 +368,7 @@
struct operator_traits<operator_min, int_u<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true };
- typedef int_u<(unsigned) mlc::min<nbits, mbits>::ret,
+ typedef int_u<mlc::on<unsigned>::min<nbits, mbits>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_u<nbits, force> impl;
};
@@ -384,7 +384,7 @@
struct operator_traits<operator_max, int_u<nbits, B1>, int_u<mbits, B2> >
{
enum { commutative = true };
- typedef int_u<(unsigned) mlc::max<nbits, mbits>::ret,
+ typedef int_u<mlc::on<unsigned>::max<nbits, mbits>::ret,
typename deduce_op_behavior<B1, B2>::ret> ret;
typedef int_u<nbits, force> impl;
};
@@ -401,7 +401,7 @@
{
enum { commutative = true };
// FIXME: why unsafe? I think there is a reason.
- typedef int_u<(unsigned) mlc::maxN<nbits, mbits, 32>::ret, unsafe> ret;
+ typedef int_u<mlc::on<unsigned>::maxN<nbits, mbits, 32>::ret, unsafe> ret;
typedef int_u<nbits, force> impl;
};
Index: ntg/real/behavior.hh
===================================================================
--- ntg/real/behavior.hh (revision 111)
+++ ntg/real/behavior.hh (working copy)
@@ -386,7 +386,7 @@
static storage_type
check (const P& rhs)
{
- typedef typename mlc::if_<ntg_is_a(P, decimal)::ret,
+ typedef typename mlc::if_< mlc::value<bool, ntg_is_a(P, decimal)::ret>,
cycle_fmod,
cycle_mod>::ret cycle_op;
Index: ntg/core/macros.hh
===================================================================
--- ntg/core/macros.hh (revision 111)
+++ ntg/core/macros.hh (working copy)
@@ -28,6 +28,11 @@
#ifndef NTG_CORE_MACROS_HH
# define NTG_CORE_MACROS_HH
+# include <mlc/if.hh>
+# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
+
+
/*------.
| casts |
`------*/
@@ -169,18 +174,18 @@
**
** If T is non vectorial, the value returned should not be considered.
*/
-#define ntg_if_vectorial_nb_comp(T) \
- ntg::type_traits<typename mlc::if_<ntg_is_a(T, ntg::vectorial)::ret, \
- T, \
+#define ntg_if_vectorial_nb_comp(T) \
+ ntg::type_traits<typename mlc::if_< mlc::value<bool, ntg_is_a(T, ntg::vectorial)::ret>, \
+ T, \
ntg::vec<42, bool> >::ret>::nb_comp
/*! Same as \a ntg_if_vectorial_nb_comp but without 'typename'
**
** \see ntg_if_vectorial_nb_comp
-*/
-#define ntg_if_vectorial_nb_comp_(T) \
- ntg::type_traits<mlc::if_<ntg_is_a_(T, ntg::vectorial)::ret, \
- T, \
+*/ \
+#define ntg_if_vectorial_nb_comp_(T) \
+ ntg::type_traits<mlc::if_< mlc::value<bool, ntg_is_a_(T, ntg::vectorial)::ret>, \
+ T, \
ntg::vec<42, bool> >::ret>::nb_comp
/*! Compare the number of components.
@@ -193,9 +198,9 @@
*/
#define ntg_compare_nb_comp(A, B) \
mlc::if_< \
- ntg_is_a(A, ntg::non_vectorial)::ret, \
+ mlc::value<bool, ntg_is_a(A, ntg::non_vectorial)::ret>, \
ntg_is_a(B, ntg::non_vectorial), \
- mlc::eq<ntg_if_vectorial_nb_comp(A), \
+ mlc::on<unsigned>::eq<ntg_if_vectorial_nb_comp(A), \
ntg_if_vectorial_nb_comp(B) > >::ret
/*! Same as \a ntg_compare_nb_comp but without 'typename'
@@ -204,9 +209,9 @@
*/
#define ntg_compare_nb_comp_(A, B) \
mlc::if_< \
- ntg_is_a_(A, ntg::non_vectorial)::ret, \
+ mlc::value<bool, ntg_is_a_(A, ntg::non_vectorial)::ret>, \
ntg_is_a_(B, ntg::non_vectorial), \
- mlc::eq<ntg_if_vectorial_nb_comp_(A), \
+ mlc::on<unsigned>::eq<ntg_if_vectorial_nb_comp_(A), \
ntg_if_vectorial_nb_comp_(B) > >::ret
#endif // !NTG_CORE_MACROS_HH
Index: ntg/core/pred_succ.hh
===================================================================
--- ntg/core/pred_succ.hh (revision 111)
+++ ntg/core/pred_succ.hh (working copy)
@@ -29,7 +29,9 @@
# define NTG_CORE_PRED_SUCC_HH
+#include <mlc/if.hh>
#include <mlc/is_a.hh>
+
#include <ntg/real/int_u.hh>
#include <ntg/core/macros.hh>
@@ -45,9 +47,9 @@
typedef int_u<1> bool_with_arith;
typedef T non_vectorial_with_arith;
- typedef typename mlc::if_<ntg_is_a(T, ntg::binary)::ret,
- id_<bool_with_arith>,
- id_<non_vectorial_with_arith> >::ret::ret ret;
+ typedef typename mlc::if_< mlc::value<bool,ntg_is_a(T, ntg::binary)::ret>,
+ id_<bool_with_arith>,
+ id_<non_vectorial_with_arith> >::ret ret;
};
}
Index: ntg/core/math.hh
===================================================================
--- ntg/core/math.hh (revision 111)
+++ ntg/core/math.hh (working copy)
@@ -1,82 +0,0 @@
-// Copyright (C) 2001, 2002, 2003, 2005 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-// MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef NTG_CORE_MATH_HH
-# define NTG_CORE_MATH_HH
-
-# include <mlc/bool.hh>
-
-namespace mlc
-{
-
- namespace internal
- {
-
- // Helper structs for pow2sup below.
-
- template<unsigned N> struct is_pow2 { typedef false_type ret; };
- template<> struct is_pow2<8> { typedef true_type ret; };
- template<> struct is_pow2<16> { typedef true_type ret; };
- template<> struct is_pow2<32> { typedef true_type ret; };
- template<> struct is_pow2<64> { typedef true_type ret; };
-
- template<unsigned N, class> struct find_pow2sup;
- template<unsigned N> struct find_pow2sup<N,true_type> {
- enum { value = N };
- };
- template<unsigned N> struct find_pow2sup<N,false_type> {
- enum { value = find_pow2sup< N+1,
- typename is_pow2<N+1>::ret >::value };
- };
-
- } // end of internal
-
- // Smaller power of 2 greater than N.
-
- template<unsigned N>
- struct pow2sup {
- enum {
- value =
- internal::find_pow2sup< N,
- typename internal::is_pow2<N>::ret >::value
- };
- private:
- typedef typename is_true<N < 32>::ensure_type precondition_type;
- };
-
- // Various tests on N (actually, we tests only oddness.)
-
- template<unsigned N>
- class utest {
- public:
- typedef typename is_true<N/2 == (N+1)/2>::ensure_type is_odd_type;
- static void ensure_odd() { is_odd_type::is_true(); }
- };
-
-} // end of namespace mlc
-
-#endif // METALIC_MATH_HH
Index: ntg/core/internal/global_ops_traits.hh
===================================================================
--- ntg/core/internal/global_ops_traits.hh (revision 111)
+++ ntg/core/internal/global_ops_traits.hh (working copy)
@@ -38,8 +38,9 @@
# include <ntg/core/macros.hh>
# include <ntg/core/type_traits.hh>
-# include <mlc/bool.hh>
+# include <mlc/if.hh>
+
namespace ntg {
namespace internal {
@@ -183,14 +184,15 @@
enum { can_invert = (operator_traits<Op, T2, T1>::commutative
&& is_defined<rev_traits>::ret) };
- typedef typename
- mlc::if_<is_defined<traits>::ret,
- get_order<T1, T2>, typename
- mlc::if_<can_invert,
- get_order_inv<T1, T2>,
- meta_undefined_traits<undefined_traits>
- >::ret
- >::ret deduced_type;
+ typedef
+ typename mlc::if_< mlc::value<bool, (is_defined<traits>::ret)>,
+ get_order<T1, T2>,
+ typename mlc::if_< mlc::value<bool, can_invert>,
+ get_order_inv<T1, T2>,
+ meta_undefined_traits<undefined_traits>
+ >::ret
+ >::ret
+ deduced_type;
typedef typename deduced_type::traits_lhs_type traits_lhs_type;
typedef typename deduced_type::traits_rhs_type traits_rhs_type;
1
0
2005-04-05 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
Cleaning.
* mlc/types.hh: Rewrite and split into...
* mlc/bool.hh: Likewise.
* mlc/if.hh: ... this new file.
* mlc/switch.hh: ... this new file.
* mlc/value.hh: ... this new file.
* mlc/cmp.hh: Rewrite and arithmetics move to...
* mlc/arith.hh: ... this new file.
* mlc/math.hh: Update.
* mlc/properties.hh: Likewise.
* mlc/makefile.src: Likewise.
* mlc/is_a.hh: Likewise.
* mlc/contract.hh: Likewise.
* mlc/array/1d.hh: Likewise.
* mlc/array/2d.hh: Likewise.
* mlc/array/3d.hh: Likewise.
* mlc/array/1d.hxx: Likewise.
* mlc/array/2d.hxx: Likewise.
* mlc/array/3d.hxx: Likewise.
Index: mlc/math.hh
===================================================================
--- mlc/math.hh (revision 110)
+++ mlc/math.hh (working copy)
@@ -64,17 +64,14 @@
internal::find_pow2sup< N,
typename internal::is_pow2<N>::ret >::value
};
- private:
- typedef typename is_true<N < 32>::ensure_type precondition_type;
+ ~pow2sup() { mlc::value<bool, (N < 32)>::ensure(); }
};
// Various tests on N (actually, we tests only oddness.)
template<unsigned N>
- class utest {
- public:
- typedef typename is_true<N/2 == (N+1)/2>::ensure_type is_odd_type;
- static void ensure_odd() { is_odd_type::is_true(); }
+ struct utest {
+ static void ensure_odd() { mlc::value<bool, (N/2 == (N+1)/2)>::ensure(); }
};
} // end of namespace mlc
Index: mlc/bool.hh
===================================================================
--- mlc/bool.hh (revision 110)
+++ mlc/bool.hh (working copy)
@@ -28,129 +28,36 @@
#ifndef METALIC_BOOL_HH
# define METALIC_BOOL_HH
+# include <mlc/value.hh>
+
namespace mlc
{
- struct false_type;
-
- struct true_type {
- static void is_true() {}
- typedef false_type not_type;
- typedef void is_true_type;
- };
-
- struct false_type {
- static void is_false() {}
- typedef true_type not_type;
- typedef void is_false_type;
- };
-
-
-
- /*----.
- | if_ |
- `----*/
-
- template <bool Cond, class if_true_type, class if_false_type>
- struct if_ {
- typedef if_true_type ret;
- };
-
- template<class if_true_type, class if_false_type>
- struct if_<false, if_true_type, if_false_type>
+ /// Specialization of mlc::value for T = bool and v = true; it provides ::ensure().
+ template <>
+ struct value <bool, true>
{
- typedef if_false_type ret;
- typedef false_type ensure_type;
+ static void ensure() {}
+ static const bool ret = true;
+ private:
+ value();
};
- /*--------.
- | switch_ |
- `--------*/
- struct invalid {};
+ /// Typedefs of true_type and false_type.
+ typedef value<bool, true> true_type;
+ typedef value<bool, false> false_type;
- template<unsigned Cond, class Ret, class Cases = invalid>
- struct case_ {};
- template<unsigned Cond, class Cases, class Default = invalid>
- struct switch_;
-
- template<unsigned Cond, unsigned Compare, class Ret, class Default>
- struct switch_<Cond, case_<Compare, Ret>, Default >
+ /// Class is_true<b> (provided for bkd compability).
+ template <bool b>
+ struct is_true : public value<bool, b>
{
- typedef typename if_< (Cond == Compare), Ret, Default >::ret ret;
};
- template<unsigned Cond,
- unsigned Compare,
- class Ret,
- class Cases,
- class Default>
- struct switch_<Cond, case_<Compare, Ret, Cases>, Default >
- {
- typedef typename
- if_< (Cond == Compare),
- Ret,
- typename switch_<Cond, Cases, Default>::ret>::ret ret;
- };
- template<bool Cond, class Ret, class Cases = invalid>
- struct bool_case_ {};
-
- template<class Cases, class Default = invalid>
- struct bool_switch_;
-
- template<bool Cond, class Ret, class Default>
- struct bool_switch_<bool_case_<Cond, Ret>, Default >
- {
- typedef typename if_< Cond, Ret, Default >::ret ret;
- };
-
- template<bool Cond,class Ret, class Cases, class Default>
- struct bool_switch_<bool_case_<Cond, Ret, Cases>, Default >
- {
- typedef typename
- if_< Cond,
- Ret,
- typename bool_switch_<Cases, Default>::ret >::ret ret;
- };
-
- /*-----.
- | misc |
- `-----*/
-
- template<bool> struct is_true;
- template<> struct is_true<true>
- {
- static void ensure() {};
- typedef true_type ensure_type;
- };
-
- template<bool> struct is_false;
- template<> struct is_false<false> { static void ensure() {}; };
-
- // FIXME: find a good name for this struct.
-
- // base class for meta-types returning Boolean values
-
- template<bool> struct returns_bool_;
-
- template<>
- struct returns_bool_<true> : public true_type
- {
- typedef void ensure_type;
- static const bool ret = true;
- static void ensure() {}
- };
-
- template<>
- struct returns_bool_<false> : public false_type
- {
- static const bool ret = false;
- };
-
} // end of namespace mlc
Index: mlc/properties.hh
===================================================================
--- mlc/properties.hh (revision 110)
+++ mlc/properties.hh (working copy)
@@ -31,38 +31,11 @@
# include <iostream>
# include <typeinfo>
-# include <mlc/types.hh>
-# include <mlc/bool.hh>
+# include <mlc/if.hh>
# include <mlc/cmp.hh>
-// FIXME: temporary routines; equivalent to the ones of mlc/bool.hh and mlc/cmp.hh
-// FIXME: modify mlc/* so that "types" are prefered to "values"...
-namespace mlc
-{
- namespace internal
- {
- template <class C, class T, class F> struct my_if;
- template <class T, class F> struct my_if <mlc::true_type, T, F> { typedef T ret; };
- template <class T, class F> struct my_if <mlc::false_type, T, F> { typedef F ret; };
-
- template <class T1, class T2> struct my_eq { typedef mlc::false_type ret; };
- template <class T> struct my_eq <T, T> { typedef mlc::true_type ret; };
-
- }
-}
-
-// FIXME: temporary macros (Cf. above)
-
-# define mlc_internal_if(C,T,F) \
-typename mlc::internal::my_if<C,T,F>::ret
-
-# define mlc_internal_eq(T1,T2) \
-typename mlc::internal::my_eq<T1,T2>::ret
-
-
-
/// macro to equip a namespace for properties:
# define mlc_equip_namespace_for_properties() \
@@ -158,7 +131,7 @@
struct get_prop < CATEGORY, type, target::TARGET > \
{ \
typedef get_prop_helper<CATEGORY, type, target::TARGET, \
- mlc_internal_eq(type, mlc::no_type), \
+ mlc_eq(type, mlc::no_type), \
typename get_props<CATEGORY, type>::user_defined_ \
> helper_type; \
typedef typename helper_type::ret ret; \
@@ -172,7 +145,7 @@
typename get_super_type<type>::ret, \
target::TARGET>::ret super_prop_type; \
\
- typedef mlc_internal_if( mlc_internal_eq(prop_type, mlc::unknown_type), \
+ typedef mlc_if( mlc_eq(prop_type, mlc::unknown_type), \
super_prop_type, \
prop_type ) ret; \
}; \
@@ -204,17 +177,17 @@
/// macros to declare a property:
# define mlc_decl_prop_with_default(CATEGORY, NAME, DEFAULT) \
- typedef mlc_internal_if(mlc_internal_eq(type, mlc::default_type), \
+ typedef mlc_if(mlc_eq(type, mlc::default_type), \
DEFAULT, \
- mlc_internal_if(mlc_internal_eq(type, mlc::no_type), \
+ mlc_if(mlc_eq(type, mlc::no_type), \
mlc::unknown_type, \
mlc_internal_retrieve_prop(CATEGORY, type, NAME)) \
) NAME
# define mlc_decl_prop(CATEGORY, NAME) \
- typedef mlc_internal_if(mlc_internal_eq(type, mlc::default_type), \
+ typedef mlc_if(mlc_eq(type, mlc::default_type), \
mlc::undefined_type, \
- mlc_internal_if(mlc_internal_eq(type, mlc::no_type), \
+ mlc_if(mlc_eq(type, mlc::no_type), \
mlc::unknown_type, \
mlc_internal_retrieve_prop(CATEGORY, type, NAME)) \
) NAME
@@ -228,9 +201,9 @@
TYPE, \
NAMESPACE::target::TARGET##_type>::ret
-# define mlc_type_of_(NAMESPACE, TYPE, TARGET) \
+# define mlc_type_of_(NAMESPACE, TYPE, TARGET) \
NAMESPACE::get_type_of<typename NAMESPACE::internal::get_category<TYPE>::ret, \
- TYPE, \
+ TYPE, \
NAMESPACE::target::TARGET##_type>::ret
Index: mlc/if.hh
===================================================================
--- mlc/if.hh (revision 0)
+++ mlc/if.hh (revision 0)
@@ -0,0 +1,61 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_IF_HH
+# define METALIC_IF_HH
+
+# include <mlc/bool.hh>
+
+
+/// Macro mlc_if.
+# define mlc_if(Cond, Then, Else) typename mlc::if_<(Cond), (Then), (Else)>::ret
+
+
+namespace mlc
+{
+
+ template <typename cond_type, typename then_type, typename else_type>
+ struct if_;
+
+ template <typename then_type, typename else_type>
+ struct if_ <true_type, then_type, else_type>
+ {
+ typedef then_type ret;
+ };
+
+ template <typename then_type, typename else_type>
+ struct if_ <false_type, then_type, else_type>
+ {
+ typedef else_type ret;
+ };
+
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_IF_HH
Index: mlc/switch.hh
===================================================================
--- mlc/switch.hh (revision 0)
+++ mlc/switch.hh (revision 0)
@@ -0,0 +1,92 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_SWITCH_HH
+# define METALIC_SWITCH_HH
+
+# include <mlc/bool.hh>
+# include <mlc/if.hh>
+
+
+namespace mlc
+{
+
+
+ // FIXME: not yet cleaned.
+
+ struct invalid {};
+
+ template<unsigned Cond, class Ret, class Cases = invalid>
+ struct case_ {};
+
+ template<unsigned Cond, class Cases, class Default = invalid>
+ struct switch_;
+
+ template<unsigned Cond, unsigned Compare, class Ret, class Default>
+ struct switch_<Cond, case_<Compare, Ret>, Default >
+ {
+ typedef typename if_< value<bool,(Cond == Compare)>, Ret, Default >::ret ret;
+ };
+
+ template<unsigned Cond,
+ unsigned Compare,
+ class Ret,
+ class Cases,
+ class Default>
+ struct switch_<Cond, case_<Compare, Ret, Cases>, Default >
+ {
+ typedef typename
+ if_< value<bool, bool(Cond == Compare)>,
+ Ret,
+ typename switch_<Cond, Cases, Default>::ret>::ret ret;
+ };
+
+ template<bool Cond, class Ret, class Cases = invalid>
+ struct bool_case_ {};
+
+ template<class Cases, class Default = invalid>
+ struct bool_switch_;
+
+ template<bool Cond, class Ret, class Default>
+ struct bool_switch_<bool_case_<Cond, Ret>, Default >
+ {
+ typedef typename if_< value<bool,Cond>, Ret, Default >::ret ret;
+ };
+
+ template<bool Cond,class Ret, class Cases, class Default>
+ struct bool_switch_<bool_case_<Cond, Ret, Cases>, Default >
+ {
+ typedef typename
+ if_< value<bool, Cond>,
+ Ret,
+ typename bool_switch_<Cases, Default>::ret >::ret ret;
+ };
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_SWITCH_HH
Index: mlc/types.hh
===================================================================
--- mlc/types.hh (revision 110)
+++ mlc/types.hh (working copy)
@@ -28,7 +28,10 @@
#ifndef METALIC_TYPES_HH
# define METALIC_TYPES_HH
+# include <mlc/value.hh>
+
+
/*! \namespace mlc
** \brief mlc namespace.
*/
Index: mlc/makefile.src
===================================================================
--- mlc/makefile.src (revision 110)
+++ mlc/makefile.src (working copy)
@@ -5,6 +5,7 @@
MLC_DEP = \
any.hh \
+ arith.hh \
array/1d.hh \
array/1d.hxx \
array/2d.hh \
@@ -19,10 +20,12 @@
cmp.hh \
config/system.hh \
contract.hh \
+ if.hh \
is_a.hh \
math.hh \
properties.hh \
+ switch.hh \
tracked_ptr.hh \
traits.hh \
- types.hh
-
+ types.hh \
+ value.hh
Index: mlc/arith.hh
===================================================================
--- mlc/arith.hh (revision 0)
+++ mlc/arith.hh (revision 0)
@@ -0,0 +1,63 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_ARITH_HH
+# define METALIC_ARITH_HH
+
+# include <mlc/bool.hh>
+
+
+
+namespace mlc
+{
+
+ template <typename T>
+ struct on
+ {
+ template <T i, T j> struct eq : public value <bool, (i == j)> {};
+ template <T i, T j> struct neq : public value <bool, (i != j)> {};
+
+ template <T i, T j> struct less : public value <bool, (i < j)> {};
+ template <T i, T j> struct leq : public value <bool, (i <= j)> {};
+
+ template <T i, T j> struct greater : public value <bool, (i > j)> {};
+ template <T i, T j> struct geq : public value <bool, (i >= j)> {};
+
+ template <T i, T j> struct min : public value<T, (i < j ? i : j)> {};
+ template <T i, T j> struct max : public value<T, (i > j ? i : j)> {};
+
+ template <T i, T j, T N> struct maxN : public value<T, (i > j ?
+ (i > N ? N : i) :
+ (j > N ? N : j))> {};
+ template <T i, T N> struct saturateN : public value<T, (i > N ? N : i)> {};
+ };
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_ARITH_HH
Index: mlc/is_a.hh
===================================================================
--- mlc/is_a.hh (revision 110)
+++ mlc/is_a.hh (working copy)
@@ -122,7 +122,7 @@
template<class T, class U>
struct check
- : public mlc::returns_bool_<( is_a__check_result_ )>
+ : public value<bool,( is_a__check_result_ )>
{
};
};
@@ -145,7 +145,7 @@
template<class T, template<class> class U>
struct check
- : public mlc::returns_bool_<( is_a__check_result_ )>
+ : public value<bool,( is_a__check_result_ )>
{
};
};
@@ -168,7 +168,7 @@
template<class T, template<class,class> class U>
struct check
- : public mlc::returns_bool_<( is_a__check_result_ )>
+ : public value<bool,( is_a__check_result_ )>
{};
};
Index: mlc/value.hh
===================================================================
--- mlc/value.hh (revision 0)
+++ mlc/value.hh (revision 0)
@@ -0,0 +1,51 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_VALUE_HH
+# define METALIC_VALUE_HH
+
+
+/*! \namespace mlc
+** \brief mlc namespace.
+*/
+namespace mlc {
+
+
+ /// Class that defines a mlc value as a type (for instance mlc::value<int,3>).
+ template <typename T, T v>
+ struct value
+ {
+ static const T ret = v;
+ private:
+ value();
+ };
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_VALUE_HH
Index: mlc/contract.hh
===================================================================
--- mlc/contract.hh (revision 110)
+++ mlc/contract.hh (working copy)
@@ -34,10 +34,10 @@
// FIXME: a lot of code has been removed here
// for simplification purpose only
-# define assertion(expr) assert(expr)
-# define invariant(expr) assert(expr)
-# define precondition(expr) assert(expr)
-# define postcondition(expr) assert(expr)
+# define assertion(expr) assert(expr)
+# define invariant(expr) assert(expr)
+# define precondition(expr) assert(expr)
+# define postcondition(expr) assert(expr)
#endif // ! METALIC_CONTRACT_HH
Index: mlc/cmp.hh
===================================================================
--- mlc/cmp.hh (revision 110)
+++ mlc/cmp.hh (working copy)
@@ -28,104 +28,47 @@
#ifndef METALIC_CMP_HH
# define METALIC_CMP_HH
-
# include <mlc/bool.hh>
-namespace mlc
-{
+/// Macro mlc_eq.
+# define mlc_eq(T1, T2) typename mlc::eq<T1, T2>::ret
- namespace type {
- /*-----------------.
- | Type comparisons |
- `-----------------*/
+namespace mlc
+{
- template <typename T, typename U>
- struct eq : returns_bool_<false> {};
+ /// Equality test between a couple of types.
- template <typename T>
- struct eq<T, T> : returns_bool_<true> {};
-
- } // end of namespace type
-
- /*-------------------.
- | Values comparisons |
- `-------------------*/
-
- // These struct are quite handy since constructions like
- // is_true<a < b>::ensure() cannot be parsed.
-
- template<int i, int j>
- struct less
- {
- enum { ret = (i < j) };
- static void ensure() { is_true<ret>::ensure(); };
- };
-
- template<int i, int j>
- struct lesseq
- {
- enum { ret = (i <= j) };
- static void ensure() { is_true<ret>::ensure(); };
- };
-
- template<int i, int j>
+ template <typename T1, typename T2>
struct eq
{
- enum { ret = (i == j) };
- static void ensure() { is_true<ret>::ensure(); };
+ typedef false_type ret;
};
- template<int i, int j>
- struct neq
+ template <typename T>
+ struct eq <T, T>
{
- enum { ret = (i != j) };
- static void ensure() { is_true<ret>::ensure(); };
+ typedef true_type ret;
};
- template<int i, int j>
- struct greater
- {
- enum { ret = (i > j) };
- static void ensure() { is_true<ret>::ensure(); };
- };
- template<int i, int j>
- struct greatereq
- {
- enum { ret = (i >= j) };
- static void ensure() { is_true<ret>::ensure(); };
- };
+ /// Inequality test between a couple of types.
- template<int i, int j>
- struct min
+ template <typename T1, typename T2>
+ struct neq
{
- enum { ret = (i < j ? i : j) };
+ typedef true_type ret;
};
- template<int i, int j>
- struct max
+ template <typename T>
+ struct neq <T, T>
{
- enum { ret = (i > j ? i : j) };
+ typedef false_type ret;
};
- template<int i, int j, int N>
- struct maxN
- {
- enum { ret = (i > j ?
- (i > N ? N : i) :
- (j > N ? N : j)) };
- };
- template<int i, int N>
- struct saturateN
- {
- enum { ret = (i > N ? N : i) };
- };
-
-
} // end of namespace mlc
Index: mlc/array/1d.hh
===================================================================
--- mlc/array/1d.hh (revision 110)
+++ mlc/array/1d.hh (working copy)
@@ -29,7 +29,7 @@
# define METALIC_ARRAY_1D_HH
# include <mlc/contract.hh>
-# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
# include <mlc/array/objs.hh>
# include <ntg/basics.hh>
# include <iostream>
@@ -59,8 +59,8 @@
array1d(T* ptr)
{
- less<0, Info_::card>::ensure();
- less< Info_::card, internal::max_card_ >::ensure();
+ on<unsigned>::less<0, Info_::card>::ensure();
+ on<unsigned>::less< Info_::card, internal::max_card_ >::ensure();
for (unsigned i = 0; i < Info_::card; ++i)
buffer_[i] = *ptr++;
}
@@ -230,14 +230,14 @@
template<unsigned i>
T get_at_() const {
- lesseq<i, Info_::card>::ensure();
+ on<unsigned>::leq<i, Info_::card>::ensure();
return *(buffer_ + i);
}
template<int i>
T get_() const {
- lesseq<-Info_::center, i>::ensure();
- lesseq<i, Info_::card - Info_::center - 1>::ensure();
+ on<int>::leq<-Info_::center, i>::ensure();
+ on<int>::leq<i, Info_::card - Info_::center - 1>::ensure();
return *(buffer_ + Info_::center + i);
}
Index: mlc/array/2d.hh
===================================================================
--- mlc/array/2d.hh (revision 110)
+++ mlc/array/2d.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/array/objs.hh>
# include <mlc/contract.hh>
-# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
# include <ntg/basics.hh>
# include <iostream>
@@ -58,9 +58,9 @@
array2d(T* ptr)
{
- less< 0, Info_::nrows >::ensure();
- less< 0, Info_::ncols >::ensure();
- less< Info_::card, internal::max_card_ >::ensure();
+ on<unsigned>::less< 0, Info_::nrows >::ensure();
+ on<unsigned>::less< 0, Info_::ncols >::ensure();
+ on<unsigned>::less< Info_::card, internal::max_card_ >::ensure();
for (unsigned i = 0; i < Info_::card; ++i)
buffer_[i] = *ptr++;
}
@@ -256,16 +256,16 @@
template<unsigned i>
T get_at_() const {
- lesseq<i, Info_::card>::ensure();
+ on<unsigned>::leq<i, Info_::card>::ensure();
return *(buffer_ + i);
}
template<int nrow, int ncol>
T get_() const {
- lesseq< -Info_::center_row, nrow >::ensure();
- lesseq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
- lesseq< -Info_::center_col, ncol >::ensure();
- lesseq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
+ on<int>::leq< -Info_::center_row, nrow >::ensure();
+ on<int>::leq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
+ on<int>::leq< -Info_::center_col, ncol >::ensure();
+ on<int>::leq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
return *(buffer_ + Info_::center + (nrow * Info_::ncols) + ncol);
}
Index: mlc/array/3d.hh
===================================================================
--- mlc/array/3d.hh (revision 110)
+++ mlc/array/3d.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/array/objs.hh>
# include <mlc/contract.hh>
-# include <mlc/cmp.hh>
+# include <mlc/arith.hh>
# include <ntg/basics.hh>
# include <iostream>
@@ -60,10 +60,10 @@
array3d(T* ptr)
{
- less< 0, Info_::nplanes >::ensure();
- less< 0, Info_::nrows >::ensure();
- less< 0, Info_::ncols >::ensure();
- less< Info_::card, internal::max_card_ >::ensure();
+ on<unsigned>::less< 0, Info_::nplanes >::ensure();
+ on<unsigned>::less< 0, Info_::nrows >::ensure();
+ on<unsigned>::less< 0, Info_::ncols >::ensure();
+ on<unsigned>::less< Info_::card, internal::max_card_ >::ensure();
for (unsigned i = 0; i < Info_::card; ++i)
buffer_[i] = *ptr++;
}
@@ -259,18 +259,18 @@
template<unsigned i>
T get_at_() const {
- lesseq<i, Info_::card>::ensure();
+ on<int>::leq<i, Info_::card>::ensure();
return *(buffer_ + i);
}
template<int nplane, int nrow, int ncol>
T get_() const {
- lesseq< -Info_::center_plane, nplane >::ensure();
- lesseq< nplane, Info::nplanes - Info_::center_plane - 1 >::ensure();
- lesseq< -Info_::center_row, nrow >::ensure();
- lesseq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
- lesseq< -Info_::center_col, ncol >::ensure();
- lesseq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
+ on<int>::leq< -Info_::center_plane, nplane >::ensure();
+ on<int>::leq< nplane, Info::nplanes - Info_::center_plane - 1 >::ensure();
+ on<int>::leq< -Info_::center_row, nrow >::ensure();
+ on<int>::leq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
+ on<int>::leq< -Info_::center_col, ncol >::ensure();
+ on<int>::leq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
return *(buffer_ + Info_::center + (nplane * Info::nrows * Info::ncols) + (nrow * Info::ncols) + ncol);
}
Index: mlc/array/1d.hxx
===================================================================
--- mlc/array/1d.hxx (revision 110)
+++ mlc/array/1d.hxx (working copy)
@@ -146,7 +146,7 @@
next_elt_t_ operator,(T val)
{
- is_true<Info::card == unknown_>::ensure();
+ value<bool, (Info::card == unknown_)>::ensure();
*ptr = val;
return next_elt_t_(ptr + 1, arr);
}
@@ -156,7 +156,7 @@
eat_center_t_ operator,(x_<T> val)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = val.ue; // FIXME : give a *name* to this variable !!
return eat_center_t_(ptr+1, arr);
}
@@ -166,7 +166,7 @@
eat_center_t_ operator,(x_<void>)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = T(0);
return eat_center_t_(ptr+1, arr);
}
@@ -177,7 +177,7 @@
array1d_t_ operator,(end_type)
{
// array is well-formed :
- is_true<Info::well_formed>::ensure();
+ value<bool, Info::well_formed>::ensure();
// centering is automatic or user-defined :
// (commented out to allow automatic centering on even sized arrays)
// mlc::logical_or< mlc::eq< Info::i % 2, 1 >::ret, mlc::neq< Info::center, unknown_ >::ret >::ensure();
Index: mlc/array/2d.hxx
===================================================================
--- mlc/array/2d.hxx (revision 110)
+++ mlc/array/2d.hxx (working copy)
@@ -170,7 +170,7 @@
next_elt_t_ operator,(T val)
{
- is_true<Info::nrows == unknown_>::ensure();
+ value<bool, (Info::nrows == unknown_)>::ensure();
*ptr = val;
return next_elt_t_(ptr + 1, arr);
}
@@ -180,7 +180,7 @@
eat_center_t_ operator,(x_<T> val)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = val.ue; // FIXME : give a *name* to this variable !!
return eat_center_t_(ptr + 1, arr);
}
@@ -190,7 +190,7 @@
eat_center_t_ operator,(x_<void>)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = T(0);
return eat_center_t_(ptr + 1, arr);
}
@@ -200,8 +200,8 @@
eat_lbrk_t_ operator,(lbrk_)
{
- is_true<Info::ncols == unknown_>::ensure();
- is_true<Info::ncols != 0>::ensure();
+ value<bool, (Info::ncols == unknown_)>::ensure();
+ value<bool, (Info::ncols != 0)>::ensure();
return eat_lbrk_t_(ptr, arr);
}
@@ -213,19 +213,19 @@
enum { nrows = Info::i / Info::ncols };
// array is well-formed :
- is_true<Info::well_formed == true>::ensure();
+ value<bool, (Info::well_formed == true)>::ensure();
// centering is automatic or user-defined :
- is_true<Info::ncols != unknown_>::ensure();
+ value<bool, (Info::ncols != unknown_)>::ensure();
// both nrows and ncols must be odd
// or the center must be user-defined
- is_true<
+ value<bool, (
((Info::ncols % 2 == 1) && (nrows % 2 == 1))
|| (Info::center != unknown_)
- >::ensure();
+ )>::ensure();
return array2d_t_(arr->ptr);
}
Index: mlc/array/3d.hxx
===================================================================
--- mlc/array/3d.hxx (revision 110)
+++ mlc/array/3d.hxx (working copy)
@@ -174,7 +174,7 @@
next_elt_t_ operator,(T val)
{
- is_true<Info::nplanes == unknown_>::ensure();
+ value<bool, (Info::nplanes == unknown_)>::ensure();
*ptr = val;
return next_elt_t_(ptr + 1, arr);
}
@@ -184,7 +184,7 @@
eat_center_t_ operator,(x_<T> val)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = val.ue; // FIXME : give a *name* to this variable !!
return eat_center_t_(ptr + 1, arr);
}
@@ -194,7 +194,7 @@
eat_center_t_ operator,(x_<void>)
{
- is_true<Info::center == unknown_>::ensure();
+ value<bool, (Info::center == unknown_)>::ensure();
*ptr = T(0);
return eat_center_t_(ptr + 1, arr);
}
@@ -204,7 +204,7 @@
eat_lbrk_t_ operator,(lbrk_)
{
- is_true<Info::ncols == unknown_>::ensure();
+ value<bool, (Info::ncols == unknown_)>::ensure();
return eat_lbrk_t_(ptr, arr);
}
@@ -212,7 +212,7 @@
// elt, pbrk
eat_pbrk_t_ operator,(pbrk_)
{
- is_true<Info::nplanes == unknown_>::ensure();
+ value<bool, (Info::nplanes == unknown_)>::ensure();
return eat_pbrk_t_(ptr, arr);
}
@@ -223,19 +223,19 @@
enum { nplanes = (Info::i / (Info::ncols * Info::nrows)) };
// array is well-formed :
- is_true<Info::well_formed>::ensure();
+ value<bool, (Info::well_formed)>::ensure();
// centering is automatic or user-defined :
- is_true<Info::ncols != unknown_>::ensure();
- is_true<Info::nrows != unknown_>::ensure();
+ value<bool, (Info::ncols != unknown_)>::ensure();
+ value<bool, (Info::nrows != unknown_)>::ensure();
// all of nplanes, nrows and ncols are odd
// or the center is user-defined
- is_true<
+ value<bool, (
(Info::ncols % 2 == 1 && Info::nrows % 2 == 1 && nplanes % 2 == 1)
|| (Info::center != unknown_)
- >::ensure();
+ )>::ensure();
return array3d_t_(arr->ptr);
}
1
0
2005-04-05 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/abstract/point.hh: Conform to mlc macros.
* oln/core/abstract/size.hh: Likewise.
Index: oln/core/abstract/point.hh
===================================================================
--- oln/core/abstract/point.hh (revision 109)
+++ oln/core/abstract/point.hh (working copy)
@@ -29,9 +29,11 @@
# define OLENA_CORE_ABSTRACT_POINT_HH
# include <mlc/any.hh>
+# include <mlc/if.hh>
+# include <mlc/cmp.hh>
+
# include <oln/core/coord.hh>
# include <oln/core/properties.hh>
-# include <mlc/properties.hh> // FIXME: for better 'meta if' and 'meta eq'
// fwd decl
@@ -41,8 +43,7 @@
-# define oln_point_type_from_2(P1, P2) \
-mlc_internal_if( mlc_internal_eq( P2, oln::any_point ), P1, P2 )
+# define oln_point_type_from_2(P1, P2) mlc_if( mlc_eq( P2, oln::any_point ), P1, P2 )
Index: oln/core/abstract/size.hh
===================================================================
--- oln/core/abstract/size.hh (revision 109)
+++ oln/core/abstract/size.hh (working copy)
@@ -29,7 +29,8 @@
# define OLENA_CORE_ABSTRACT_SIZE_HH
# include <mlc/any.hh>
-# include <mlc/properties.hh> // FIXME: for better 'meta if' and 'meta eq'
+# include <mlc/if.hh>
+# include <mlc/cmp.hh>
// fwd decl
@@ -38,8 +39,7 @@
}
-# define oln_size_type_from_2(S1, S2) \
-mlc_internal_if( mlc_internal_eq( S2, oln::any_size ), S1, S2 )
+# define oln_size_type_from_2(S1, S2) mlc_if( mlc_eq( S2, oln::any_size ), S1, S2 )
1
0
05 Apr '05
Ce patch complète oln::apply pour les fonctions unaires, mais il
s'agit surtout d'un test de vérification que je voulais terminer et
commettre ; en effet, oln::apply ne type pas assez fortement les
fonctions (AdaptableUnaryFun). On va utiliser Metalic pour résoudre
ça.
https://svn.lrde.epita.fr/svn/oln/prototypes/proto-1.0
ChangeLog | 10 ++++++++++
oln/core/apply.hh | 43 ++++++++++++++++++++++++++++++++++++++++---
tests/core/tests/apply | 32 ++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 3 deletions(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
More oln::apply (for Adaptable Unary Functions).
* oln/core/apply.hh: Pass the Adaptable Unary Functions by value
(copy), not by (const) reference.
(apply (AdaptableUnaryFun, const abstract::image<I>&)): Document.
(apply (const abstract::image<I>&)): New functions.
* tests/core/tests/apply: Test them.
Index: olena/tests/core/tests/apply
--- olena/tests/core/tests/apply (revision 108)
+++ olena/tests/core/tests/apply (working copy)
@@ -9,14 +9,46 @@
bool check()
{
+ // oln::apply, with an instantiated Adaptable Unary Function.
+ {
oln::image2d<ntg::int_u8> ima1(10, 10);
oln::level::fill(ima1, 10);
oln::image2d<ntg::int_u8> ima2(10, 10);
oln::level::fill(ima2, 30);
oln::image2d<ntg::int_u8> ima;
+
ima = oln::apply (std::bind2nd(std::multiplies<ntg::int_u8>(), 3), ima1);
+ if (oln::level::is_equal(ima, ima2))
+ return false;
+ }
+ // oln::apply, with a non-instantiated Adaptable Unary Function.
+ {
+ oln::image2d<ntg::int_s8> ima1(10, 10);
+ oln::level::fill(ima1, 10);
+ oln::image2d<ntg::int_s8> ima2(10, 10);
+ oln::level::fill(ima2, -10);
+ oln::image2d<ntg::int_s8> ima;
+
+ typedef std::negate<ntg::int_s8> negate_int_s8;
+ ima = oln::apply<negate_int_s8> (ima1);
if (oln::level::is_equal(ima, ima2))
return false;
+ }
+
+ // oln::apply, with a non-instantiated template Adaptable Unary
+ // Function.
+ {
+ oln::image2d<ntg::int_s8> ima1(10, 10);
+ oln::level::fill(ima1, 10);
+ oln::image2d<ntg::int_s8> ima2(10, 10);
+ oln::level::fill(ima2, -10);
+ oln::image2d<ntg::int_s8> ima;
+
+ ima = oln::apply<std::negate> (ima1);
+ if (oln::level::is_equal(ima, ima2))
+ return false;
+ }
+
return true;
}
Index: olena/oln/core/apply.hh
--- olena/oln/core/apply.hh (revision 108)
+++ olena/oln/core/apply.hh (working copy)
@@ -34,6 +34,10 @@
namespace oln {
+ /*--------.
+ | Unary. |
+ `--------*/
+
// fwd decl
namespace impl {
template <typename AdaptableUnaryFun, typename I> struct apply_type;
@@ -67,10 +71,10 @@
ch_value_type<I, typename AdaptableUnaryFun::result_type>::ret
output_type;
- const AdaptableUnaryFun& f_;
+ AdaptableUnaryFun f_;
box<const I> input_;
- apply_type(const AdaptableUnaryFun& f, const abstract::image<I>& input) :
+ apply_type(AdaptableUnaryFun f, const abstract::image<I>& input) :
f_ (f),
input_ (input.exact ())
{
@@ -88,15 +92,48 @@
} // end of namespace impl
+
+ /*! \brief Standard unary \a apply procedure.
+ **
+ ** Apply a function \a f to each element of \a input, the function
+ ** is passed as a type and is instantiated.
+ */
template <class AdaptableUnaryFun, typename I>
impl::apply_type<AdaptableUnaryFun, I>
- apply (const AdaptableUnaryFun& f, const abstract::image<I>& input)
+ apply(AdaptableUnaryFun f, const abstract::image<I>& input)
{
impl::apply_type<AdaptableUnaryFun, I> tmp (f, input);
tmp.run ();
return tmp;
}
+ /*! \brief Standard unary \a apply procedure.
+ **
+ ** Apply a function \a f to each element of \a input, the function
+ ** is passed as a type and is instantiated.
+ */
+ template<class AdaptableUnaryFun, class I>
+ impl::apply_type<AdaptableUnaryFun, I>
+ apply(const abstract::image<I>& input)
+ {
+ return apply(AdaptableUnaryFun(), input);
+ }
+
+ /*! \brief Standard unary \a apply procedure.
+ **
+ ** Apply function \a f to each element of \a input, the function is
+ ** passed as a type and is instantiated. For template functions
+ ** passed as template-id, one need to instantiate the function for
+ ** the type of the abstract::image.
+ */
+ template<template<class> class AdaptableUnaryFun, class I>
+ typename impl::apply_type<AdaptableUnaryFun<oln_type_of(I, value)>, I>
+ apply(const abstract::image<I>& input)
+ {
+ AdaptableUnaryFun<oln_type_of(I, value)> tmp;
+ return apply(tmp, input);
+ }
+
} // end of namespace oln
#endif // ! OLENA_CORE_APPLY_HH
1
0
05 Apr '05
2005-04-04 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* oln/core/pw/abstract/binary_function.hh: Likewise.
* oln/arith/ops.hh: Likewise.
* oln/core/pw/times.hh: Handle better point_type and size_type.
* oln/core/pw/div.hh: Likewise.
* oln/core/pw/plus.hh: Likewise.
* oln/core/pw/minus.hh: Likewise.
* oln/core/pw/image.hh: Cosmetic change.
* oln/core/pw/abstract/function.hh: Move macros to...
* oln/core/pw/macros.hh: ... this new file.
* oln/core/pw/literal.hh: Likewise.
* oln/core/any/dpoint.hh: Add fwd decls.
* oln/core/abstract/point.hh
(oln_point_type_from_2): New macro.
(nth): New method.
* oln/core/abstract/witer.hh: Add include to pass sanity check.
* oln/core/abstract/dpoint.hh: Likewise.
* oln/core/abstract/size.hh
(oln_size_type_from_2): New macro.
* oln/core/1d/dpoint1d.hh: Add inheritance.
(impl_nth): New method.
* oln/core/2d/dpoint2d.hh: Likewise.
* oln/core/3d/dpoint3d.hh: Likewise.
* oln/core/1d/point1d.hh (impl_nth): New method.
* oln/core/2d/point2d.hh: Likewise.
* oln/core/3d/point3d.hh: Likewise.
Index: oln/core/pw/times.hh
===================================================================
--- oln/core/pw/times.hh (revision 107)
+++ oln/core/pw/times.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLENA_CORE_PW_TIMES_HH
# define OLENA_CORE_PW_TIMES_HH
-# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/abstract/binary_function.hh>
# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
@@ -44,13 +44,16 @@
template <typename L, typename R>
struct traits < times<L, R> >
{
- typedef oln_pw_point_type(L) point_type;
- typedef ntg_return_type(times, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
- typedef oln_pw_size_type(L) size_type;
+ typedef abstract::binary_function<L, R, times<L, R> > super_type;
+ typedef typename traits<super_type>::point_type point_type;
+ typedef typename traits<super_type>::size_type size_type;
+ typedef ntg_return_type(times,
+ oln_pw_value_type(L),
+ oln_pw_value_type(R)) value_type;
};
template <typename L, typename R>
- struct times : public abstract::function < times<L, R> >
+ struct times : public abstract::binary_function < L, R, times<L, R> >
{
typedef times<L, R> self_type;
@@ -58,42 +61,28 @@
typedef oln_pw_value_type(self_type) value_type;
typedef oln_pw_size_type(self_type) size_type;
- L left;
- R right;
+ typedef abstract::binary_function<L, R, self_type> super_type;
times(const abstract::function<L>& left,
const abstract::function<R>& right) :
- left(left.exact()),
- right(right.exact())
+ super_type(left, right)
{
}
- const size_type& impl_size() const
- {
- return this->left.size();
- }
-
const value_type impl_get(const point_type& p) const
{
return this->left(p) * this->right(p);
}
- bool impl_hold(const point_type& p) const
- {
- return this->left.hold(p);
- }
-
- bool impl_hold_large(const point_type& p) const
- {
- return this->left.hold_large(p);
- }
};
+
} // end of namespace oln::pw
} // end of namespace oln
+
/// Operator * on pwf
template <typename L, typename R>
Index: oln/core/pw/image.hh
===================================================================
--- oln/core/pw/image.hh (revision 107)
+++ oln/core/pw/image.hh (working copy)
@@ -128,7 +128,7 @@
typedef mlc::no_type delegated_type;
- // FIXME: we do not know if it is 2d...
+ // FIXME: AWFUL we do not know if it is 2d...
typedef is_a<abstract::image2d> image_dimension_type;
typedef vectorialness_from_valuetype(value_type) image_vectorialness_type;
Index: oln/core/pw/div.hh
===================================================================
--- oln/core/pw/div.hh (revision 107)
+++ oln/core/pw/div.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLENA_CORE_PW_DIV_HH
# define OLENA_CORE_PW_DIV_HH
-# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/abstract/binary_function.hh>
# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
@@ -44,13 +44,16 @@
template <typename L, typename R>
struct traits < div<L, R> >
{
- typedef oln_pw_point_type(L) point_type;
- typedef ntg_return_type(div, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
- typedef oln_pw_size_type(L) size_type;
+ typedef abstract::binary_function<L, R, div<L, R> > super_type;
+ typedef typename traits<super_type>::point_type point_type;
+ typedef typename traits<super_type>::size_type size_type;
+ typedef ntg_return_type(div,
+ oln_pw_value_type(L),
+ oln_pw_value_type(R)) value_type;
};
template <typename L, typename R>
- struct div : public abstract::function < div<L, R> >
+ struct div : public abstract::binary_function < L, R, div<L, R> >
{
typedef div<L, R> self_type;
@@ -58,43 +61,29 @@
typedef oln_pw_value_type(self_type) value_type;
typedef oln_pw_size_type(self_type) size_type;
- L left;
- R right;
+ typedef abstract::binary_function<L, R, self_type> super_type;
div(const abstract::function<L>& left,
- const abstract::function<R>& right) :
- left(left.exact()),
- right(right.exact())
+ const abstract::function<R>& right) :
+ super_type(left, right)
{
}
- const size_type& impl_size() const
- {
- return this->left.size();
- }
-
const value_type impl_get(const point_type& p) const
{
precondition(this->right(p) != 0);
return this->left(p) / this->right(p);
}
- bool impl_hold(const point_type& p) const
- {
- return this->left.hold(p);
- }
-
- bool impl_hold_large(const point_type& p) const
- {
- return this->left.hold_large(p);
- }
};
+
} // end of namespace oln::pw
} // end of namespace oln
+
/// Operator / on pwf
template <typename L, typename R>
@@ -107,4 +96,9 @@
}
+oln_pw_operator(div, /, int)
+oln_pw_operator(div, /, float)
+oln_pw_operator(div, /, double)
+
+
#endif // ! OLENA_CORE_PW_DIV_HH
Index: oln/core/pw/plus.hh
===================================================================
--- oln/core/pw/plus.hh (revision 107)
+++ oln/core/pw/plus.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLENA_CORE_PW_PLUS_HH
# define OLENA_CORE_PW_PLUS_HH
-# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/abstract/binary_function.hh>
# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
@@ -44,13 +44,16 @@
template <typename L, typename R>
struct traits < plus<L, R> >
{
- typedef oln_pw_point_type(L) point_type;
- typedef ntg_return_type(plus, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
- typedef oln_pw_size_type(L) size_type;
+ typedef abstract::binary_function<L, R, plus<L, R> > super_type;
+ typedef typename traits<super_type>::point_type point_type;
+ typedef typename traits<super_type>::size_type size_type;
+ typedef ntg_return_type(plus,
+ oln_pw_value_type(L),
+ oln_pw_value_type(R)) value_type;
};
template <typename L, typename R>
- struct plus : public abstract::function < plus<L, R> >
+ struct plus : public abstract::binary_function < L, R, plus<L, R> >
{
typedef plus<L, R> self_type;
@@ -58,42 +61,28 @@
typedef oln_pw_value_type(self_type) value_type;
typedef oln_pw_size_type(self_type) size_type;
- L left;
- R right;
+ typedef abstract::binary_function<L, R, self_type> super_type;
plus(const abstract::function<L>& left,
const abstract::function<R>& right) :
- left(left.exact()),
- right(right.exact())
+ super_type(left, right)
{
}
- const size_type& impl_size() const
- {
- return this->left.size();
- }
-
const value_type impl_get(const point_type& p) const
{
return this->left(p) + this->right(p);
}
- bool impl_hold(const point_type& p) const
- {
- return this->left.hold(p);
- }
-
- bool impl_hold_large(const point_type& p) const
- {
- return this->left.hold_large(p);
- }
};
+
} // end of namespace oln::pw
} // end of namespace oln
+
/// Operator + on pwf
template <typename L, typename R>
@@ -109,20 +98,5 @@
oln_pw_operator(plus, +, float)
oln_pw_operator(plus, +, double)
-// template <typename L>
-// oln::pw::plus<L, oln::pw::literal<int> >
-// operator + (const oln::pw::abstract::function<L>& lhs,
-// int value)
-// {
-// return lhs + oln::pw::literal<int>(value);
-// }
-// template <typename R>
-// oln::pw::plus<oln::pw::literal<int>, R>
-// operator + (int value,
-// const oln::pw::abstract::function<R>& rhs)
-// {
-// return oln::pw::literal<int>(value) + rhs;
-// }
-
#endif // ! OLENA_CORE_PW_PLUS_HH
Index: oln/core/pw/macros.hh
===================================================================
--- oln/core/pw/macros.hh (revision 0)
+++ oln/core/pw/macros.hh (revision 0)
@@ -0,0 +1,57 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_CORE_PW_MACROS_HH
+# define OLENA_CORE_PW_MACROS_HH
+
+
+
+# define oln_pw_point_type(F) typename oln::pw::traits<F>::point_type
+# define oln_pw_value_type(F) typename oln::pw::traits<F>::value_type
+# define oln_pw_size_type(F) typename oln::pw::traits<F>::size_type
+
+
+// FIXME: rename
+# define oln_pw_operator(NAME, SYMBOL, TYPE) \
+template <typename L> \
+oln::pw::NAME<L, oln::pw::literal<TYPE> > \
+operator SYMBOL (const oln::pw::abstract::function<L>& lhs, \
+ TYPE value) \
+{ \
+ return lhs SYMBOL oln::pw::literal<TYPE>(value); \
+} \
+template <typename R> \
+oln::pw::NAME<oln::pw::literal<TYPE>, R> \
+operator SYMBOL (TYPE value, \
+ const oln::pw::abstract::function<R>& rhs) \
+{ \
+ return oln::pw::literal<TYPE>(value) SYMBOL rhs; \
+}
+
+
+
+#endif // ! OLENA_CORE_PW_MACROS_HH
Index: oln/core/pw/abstract/function.hh
===================================================================
--- oln/core/pw/abstract/function.hh (revision 107)
+++ oln/core/pw/abstract/function.hh (working copy)
@@ -30,13 +30,9 @@
# include <mlc/any.hh>
# include <oln/core/properties.hh>
+# include <oln/core/pw/macros.hh>
-# define oln_pw_point_type(T) typename oln::pw::traits<T>::point_type
-# define oln_pw_value_type(T) typename oln::pw::traits<T>::value_type
-# define oln_pw_size_type(T) typename oln::pw::traits<T>::size_type
-
-
namespace oln {
@@ -91,7 +87,7 @@
return this->exact().impl_hold_large(p);
}
-// minus< literal<value_type>, E> operator-() const;
+ minus< literal<value_type>, E> operator-() const;
protected:
function() {}
@@ -118,10 +114,11 @@
meth adr = &E::impl_hold_large;
adr = 0;
}
-
}
+
};
+
} // end of namespace oln::pw::abstract
} // end of namespace oln::pw
Index: oln/core/pw/abstract/binary_function.hh
===================================================================
--- oln/core/pw/abstract/binary_function.hh (revision 0)
+++ oln/core/pw/abstract/binary_function.hh (revision 0)
@@ -0,0 +1,150 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_CORE_PW_ABSTRACT_BINARY_FUNCTION_HH
+# define OLENA_CORE_PW_ABSTRACT_BINARY_FUNCTION_HH
+
+# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/abstract/point.hh>
+# include <oln/core/abstract/size.hh>
+
+
+
+namespace oln {
+
+
+ namespace pw { // means "point-wise"
+
+
+ // fwd decls
+ namespace abstract {
+ template <typename L, typename R, typename E> struct binary_function;
+ }
+
+
+ template <typename L, typename R, typename E>
+ struct traits < abstract::binary_function<L, R, E> >
+ {
+ typedef oln_pw_point_type(L) left_point_type;
+ typedef oln_pw_point_type(R) right_point_type;
+
+ typedef oln_point_type_from_2(left_point_type, right_point_type) point_type;
+
+ typedef oln_pw_size_type(L) left_size_type;
+ typedef oln_pw_size_type(R) right_size_type;
+
+ typedef oln_size_type_from_2(left_size_type, right_size_type) size_type;
+ };
+
+
+ namespace abstract {
+
+ namespace internal {
+
+ template <typename T1, typename T2>
+ struct binary_function_helper;
+
+ template <typename T>
+ struct binary_function_helper < T, T > {
+ template <typename L, typename R>
+ static const L& select(const L& l, R) {
+ return l;
+ }
+ };
+
+ template <typename S>
+ struct binary_function_helper < S, any_size > {
+ template <typename L, typename R>
+ static const L& select(const L& l, R) {
+ return l;
+ }
+ };
+
+ template <typename S>
+ struct binary_function_helper < any_size, S > {
+ template <typename L, typename R>
+ static const R& select(L, const R& r) {
+ return r;
+ }
+ };
+
+ } // end of namespace oln::pw::abstract::internal
+
+
+ template <typename L, typename R, typename E>
+ struct binary_function : public function<E>
+ {
+ typedef L left_type;
+ typedef R right_type;
+
+ L left;
+ R right;
+
+ binary_function(const abstract::function<L>& left,
+ const abstract::function<R>& right) :
+ left(left.exact()),
+ right(right.exact())
+ {
+ }
+
+ typedef abstract::binary_function<L, R, E> self_type;
+ typedef oln_pw_point_type(self_type) point_type;
+ typedef oln_pw_size_type(self_type) size_type;
+
+ typedef internal::binary_function_helper<oln_pw_size_type(L),
+ oln_pw_size_type(R) > _helper_type;
+
+ const size_type& impl_size() const
+ {
+ return _helper_type::select(this->left, this->right).size();
+ }
+
+ bool impl_hold(const point_type& p) const
+ {
+ return _helper_type::select(this->left, this->right).hold(p);
+ }
+
+ bool impl_hold_large(const point_type& p) const
+ {
+ return _helper_type::select(this->left, this->right).hold_large(p);
+ }
+
+ protected:
+ binary_function() {}
+
+ };
+
+
+ } // end of namespace oln::pw::abstract
+
+ } // end of namespace oln::pw
+
+} // end of namespace oln
+
+
+
+#endif // ! OLENA_CORE_PW_ABSTRACT_BINARY_FUNCTION_HH
Index: oln/core/pw/minus.hh
===================================================================
--- oln/core/pw/minus.hh (revision 107)
+++ oln/core/pw/minus.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef OLENA_CORE_PW_MINUS_HH
# define OLENA_CORE_PW_MINUS_HH
-# include <oln/core/pw/abstract/function.hh>
+# include <oln/core/pw/abstract/binary_function.hh>
# include <oln/core/pw/literal.hh>
# include <ntg/all.hh>
@@ -44,13 +44,16 @@
template <typename L, typename R>
struct traits < minus<L, R> >
{
- typedef oln_pw_point_type(L) point_type;
- typedef ntg_return_type(minus, oln_pw_value_type(L), oln_pw_value_type(R)) value_type;
- typedef oln_pw_size_type(L) size_type;
+ typedef abstract::binary_function<L, R, minus<L, R> > super_type;
+ typedef typename traits<super_type>::point_type point_type;
+ typedef typename traits<super_type>::size_type size_type;
+ typedef ntg_return_type(minus,
+ oln_pw_value_type(L),
+ oln_pw_value_type(R)) value_type;
};
template <typename L, typename R>
- struct minus : public abstract::function < minus<L, R> >
+ struct minus : public abstract::binary_function < L, R, minus<L, R> >
{
typedef minus<L, R> self_type;
@@ -58,52 +61,37 @@
typedef oln_pw_value_type(self_type) value_type;
typedef oln_pw_size_type(self_type) size_type;
- L left;
- R right;
+ typedef abstract::binary_function<L, R, self_type > super_type;
minus(const abstract::function<L>& left,
- const abstract::function<R>& right) :
- left(left.exact()),
- right(right.exact())
+ const abstract::function<R>& right) :
+ super_type(left, right)
{
}
- const size_type& impl_size() const
- {
- return this->left.size();
- }
-
const value_type impl_get(const point_type& p) const
{
return this->left(p) - this->right(p);
}
- bool impl_hold(const point_type& p) const
- {
- return this->left.hold(p);
- }
-
- bool impl_hold_large(const point_type& p) const
- {
- return this->left.hold_large(p);
- }
-
};
// FIXME: uncomment?
-// namespace abstract {
+ namespace abstract {
-// template <typename E>
-// minus< literal<oln_pw_value_type(E)>, E>
-// function<E>::operator-() const
-// {
-// literal<oln_pw_value_type(E)> lhs(0);
-// return lhs - *this;
-// }
+ template <typename E>
+ minus< literal<oln_pw_value_type(E)>, E>
+ function<E>::operator-() const
+ {
+ typedef literal<oln_pw_value_type(E)> lit_type;
+ static const lit_type lhs = 0;
+ minus< lit_type, E> tmp(lhs, this->exact());
+ return tmp;
+ }
-// }
+ }
} // end of namespace oln::pw
@@ -122,6 +110,9 @@
return tmp;
}
+oln_pw_operator(minus, -, int)
+oln_pw_operator(minus, -, float)
+oln_pw_operator(minus, -, double)
#endif // ! OLENA_CORE_PW_MINUS_HH
Index: oln/core/pw/literal.hh
===================================================================
--- oln/core/pw/literal.hh (revision 107)
+++ oln/core/pw/literal.hh (working copy)
@@ -99,22 +99,6 @@
} // end of namespace oln
-# define oln_pw_operator(NAME, SYMBOL, TYPE) \
-template <typename L> \
-oln::pw::NAME<L, oln::pw::literal<TYPE> > \
-operator SYMBOL (const oln::pw::abstract::function<L>& lhs, \
- TYPE value) \
-{ \
- return lhs SYMBOL oln::pw::literal<TYPE>(value); \
-} \
-template <typename R> \
-oln::pw::NAME<oln::pw::literal<TYPE>, R> \
-operator SYMBOL (TYPE value, \
- const oln::pw::abstract::function<R>& rhs) \
-{ \
- return oln::pw::literal<TYPE>(value) SYMBOL rhs; \
-}
-
#endif // ! OLENA_CORE_PW_LITERAL_HH
Index: oln/core/any/dpoint.hh
===================================================================
--- oln/core/any/dpoint.hh (revision 107)
+++ oln/core/any/dpoint.hh (working copy)
@@ -28,6 +28,7 @@
#ifndef OLENA_CORE_ANY_DPOINT_HH
# define OLENA_CORE_ANY_DPOINT_HH
+# include <iostream>
# include <oln/core/abstract/dpoint.hh>
# include <oln/core/any/point.hh>
@@ -35,6 +36,13 @@
namespace oln {
+ // fwd decls
+ struct any_point;
+ namespace abstract {
+ template <typename P> struct point;
+ }
+
+
struct any_dpoint : public abstract::dpoint < any_dpoint >
{
Index: oln/core/abstract/point.hh
===================================================================
--- oln/core/abstract/point.hh (revision 107)
+++ oln/core/abstract/point.hh (working copy)
@@ -29,21 +29,30 @@
# define OLENA_CORE_ABSTRACT_POINT_HH
# include <mlc/any.hh>
-# include <mlc/bool.hh>
-
+# include <oln/core/coord.hh>
# include <oln/core/properties.hh>
+# include <mlc/properties.hh> // FIXME: for better 'meta if' and 'meta eq'
+// fwd decl
+namespace oln {
+ struct any_point;
+}
+
+
+
+# define oln_point_type_from_2(P1, P2) \
+mlc_internal_if( mlc_internal_eq( P2, oln::any_point ), P1, P2 )
+
+
+
/*! \namespace oln
** \brief oln namespace.
*/
namespace oln {
- // fwd decls
-
- struct any_point;
-
+ // fwd decl
namespace abstract {
template <typename E> struct point;
}
@@ -93,9 +102,7 @@
typedef E exact_type;
-
/// Conversion to any_point (implemented in oln/core/any/point.hh).
-
operator any_point() const;
@@ -139,6 +146,12 @@
return this->exact().impl_minus(rhs);
}
+ coord_t nth(unsigned i) const
+ {
+ // FIXME: add precondition
+ return this->exact().impl_nth(i);
+ }
+
protected:
point() {}
Index: oln/core/abstract/witer.hh
===================================================================
--- oln/core/abstract/witer.hh (revision 107)
+++ oln/core/abstract/witer.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/any.hh>
# include <mlc/types.hh>
-
+# include <oln/core/coord.hh>
# include <oln/core/properties.hh>
# include <string>
Index: oln/core/abstract/dpoint.hh
===================================================================
--- oln/core/abstract/dpoint.hh (revision 107)
+++ oln/core/abstract/dpoint.hh (working copy)
@@ -28,8 +28,10 @@
#ifndef OLENA_CORE_ABSTRACT_DPOINT_HH
# define OLENA_CORE_ABSTRACT_DPOINT_HH
+# include <oln/core/coord.hh>
# include <mlc/any.hh>
+
/*! \namespace oln
** \brief oln namespace.
*/
@@ -67,6 +69,7 @@
coord_t nth(unsigned i) const
{
+ // FIXME: add precondition
return this->exact().impl_nth(i);
}
Index: oln/core/abstract/size.hh
===================================================================
--- oln/core/abstract/size.hh (revision 107)
+++ oln/core/abstract/size.hh (working copy)
@@ -29,9 +29,22 @@
# define OLENA_CORE_ABSTRACT_SIZE_HH
# include <mlc/any.hh>
+# include <mlc/properties.hh> // FIXME: for better 'meta if' and 'meta eq'
+
+// fwd decl
namespace oln {
+ struct any_size;
+}
+
+# define oln_size_type_from_2(S1, S2) \
+mlc_internal_if( mlc_internal_eq( S2, oln::any_size ), S1, S2 )
+
+
+
+namespace oln {
+
namespace abstract {
@@ -70,8 +83,4 @@
-# include <oln/core/any/size.hh>
-
-
-
#endif // ! OLENA_CORE_ABSTRACT_SIZE_HH
Index: oln/core/1d/dpoint1d.hh
===================================================================
--- oln/core/1d/dpoint1d.hh (revision 107)
+++ oln/core/1d/dpoint1d.hh (working copy)
@@ -29,22 +29,15 @@
# define OLENA_CORE_1D_DPOINT1D_HH
# include <ostream>
-
# include <oln/core/coord.hh>
+# include <oln/core/abstract/dpoint.hh>
-// FIXME: there's an assumption here: we do not need inheritance for
-// dpoints. so abstract::dpoint does not exist...
-// FIXME: doc!
-
-// FIXME: test that coords are defined
-
-
namespace oln {
struct point1d;
- struct dpoint1d
+ struct dpoint1d : public abstract::dpoint < dpoint1d >
{
dpoint1d()
{
@@ -95,6 +88,13 @@
const coord_t index() const { return index_; }
coord_t& index() { return index_; }
+ coord_t impl_nth(unsigned i) const
+ {
+ // FIXME: remove when add in abstract::point
+ precondition(i == 0);
+ return index_;
+ }
+
protected:
coord_t index_;
};
Index: oln/core/1d/point1d.hh
===================================================================
--- oln/core/1d/point1d.hh (revision 107)
+++ oln/core/1d/point1d.hh (working copy)
@@ -103,6 +103,13 @@
return this->index_ == rhs.index_;
}
+ coord_t impl_nth(unsigned i) const
+ {
+ // FIXME: remove when add in abstract::point
+ precondition(i == 0);
+ return index_;
+ }
+
protected:
coord_t index_;
Index: oln/core/2d/dpoint2d.hh
===================================================================
--- oln/core/2d/dpoint2d.hh (revision 107)
+++ oln/core/2d/dpoint2d.hh (working copy)
@@ -29,19 +29,15 @@
# define OLENA_CORE_2D_DPOINT2D_HH
# include <iostream>
-
# include <oln/core/coord.hh>
+# include <oln/core/abstract/dpoint.hh>
-// FIXME: there's an assumption here: we do not need inheritance for
-// dpoints. so abstract::dpoint does not exist...
-// FIXME: doc!
-
namespace oln {
struct point2d;
- struct dpoint2d
+ struct dpoint2d : public abstract::dpoint < dpoint2d >
{
dpoint2d()
{
@@ -108,8 +104,8 @@
coord_t& row() { return row_; }
coord_t& col() { return col_; }
- //FIXME : name it impl_nth when dpoint2d derives from abstract::dpoint
- coord_t& nth(unsigned i)
+
+ coord_t& impl_nth(unsigned i)
{
assert(i < 2);
Index: oln/core/2d/point2d.hh
===================================================================
--- oln/core/2d/point2d.hh (revision 107)
+++ oln/core/2d/point2d.hh (working copy)
@@ -107,6 +107,14 @@
return this->row_ == rhs.row_ && this->col_ == rhs.col_;
}
+ coord_t impl_nth(unsigned i) const
+ {
+ // FIXME: remove when add in abstract::point
+ precondition(i < 2);
+ // FIXME: replace by meta-prog when a meta-vec is attribute
+ return i == 0 ? row_ : col_;
+ }
+
protected:
coord_t row_, col_;
Index: oln/core/3d/dpoint3d.hh
===================================================================
--- oln/core/3d/dpoint3d.hh (revision 107)
+++ oln/core/3d/dpoint3d.hh (working copy)
@@ -29,19 +29,15 @@
# define OLENA_CORE_3D_DPOINT3D_HH
# include <iostream>
-
# include <oln/core/coord.hh>
+# include <oln/core/abstract/dpoint.hh>
-// FIXME: there's an assumption here: we do not need inheritance for
-// dpoints. so abstract::dpoint does not exist...
-// FIXME: doc!
-
namespace oln {
struct point3d;
- struct dpoint3d
+ struct dpoint3d : public abstract::dpoint < dpoint3d >
{
dpoint3d()
{
@@ -103,6 +99,23 @@
coord_t& col() { return col_; }
coord_t& slice() { return slice_; }
+ coord_t impl_nth(unsigned i) const
+ {
+ // FIXME: remove when add in abstract::point
+ precondition(i < 3);
+ // FIXME: replace by meta-prog when a meta-vec is attribute
+ switch (i) {
+ case 0:
+ return slice_;
+ case 1:
+ return row_;
+ case 2:
+ return col_;
+ }
+ postcondition(0);
+ return 0;
+ }
+
protected:
coord_t slice_, row_, col_;
};
Index: oln/core/3d/point3d.hh
===================================================================
--- oln/core/3d/point3d.hh (revision 107)
+++ oln/core/3d/point3d.hh (working copy)
@@ -103,6 +103,23 @@
coord_t& row() { return row_; }
coord_t& col() { return col_; }
+ coord_t impl_nth(unsigned i) const
+ {
+ // FIXME: remove when add in abstract::point
+ precondition(i < 3);
+ // FIXME: replace by meta-prog when a meta-vec is attribute
+ switch (i) {
+ case 0:
+ return slice_;
+ case 1:
+ return row_;
+ case 2:
+ return col_;
+ }
+ postcondition(0);
+ return 0;
+ }
+
protected:
coord_t slice_, row_, col_;
};
Index: oln/makefile.src
===================================================================
--- oln/makefile.src (revision 107)
+++ oln/makefile.src (working copy)
@@ -7,6 +7,7 @@
all.hh \
arith/max.hh \
arith/min.hh \
+ arith/ops.hh \
basics.hh \
basics1d.hh \
basics2d.hh \
@@ -63,17 +64,20 @@
core/any/point.hh \
core/any/size.hh \
core/apply.hh \
+ core/box.hh \
core/ch_value_type.hh \
core/compose.hh \
core/coord.hh \
core/gen/identity.hh \
core/properties.hh \
+ core/pw/abstract/binary_function.hh \
core/pw/abstract/function.hh \
core/pw/all.hh \
core/pw/cmp.hh \
core/pw/div.hh \
core/pw/image.hh \
core/pw/literal.hh \
+ core/pw/macros.hh \
core/pw/minus.hh \
core/pw/plus.hh \
core/pw/times.hh \
@@ -88,9 +92,13 @@
io/write_image_2d_pnm.hh \
level/compare.hh \
level/fill.hh \
+ morpho/cc_tarjan.hh \
morpho/dilation.hh \
morpho/erosion.hh \
morpho/reconstruction.hh \
morpho/splitse.hh \
morpho/stat.hh \
- utils/clone.hh
+ utils/buffer.hh \
+ utils/clone.hh \
+ utils/key.hh \
+ utils/md5.hh
Index: oln/arith/ops.hh
===================================================================
--- oln/arith/ops.hh (revision 0)
+++ oln/arith/ops.hh (revision 0)
@@ -0,0 +1,133 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_ARITH_OPS_HH
+# define OLENA_ARITH_OPS_HH
+
+# include <oln/core/abstract/image.hh>
+# include <oln/core/pw/all.hh>
+
+
+/// Operator + between 2 images.
+
+template <typename L, typename R>
+oln::image_from_pw< oln::pw::plus< oln::pw::image<L>,
+ oln::pw::image<R> > >
+operator + (const oln::abstract::image<L>& lhs,
+ const oln::abstract::image<R>& rhs)
+{
+ return oln::for_all_p(oln::p_value(lhs) + oln::p_value(rhs));
+}
+
+
+/// Operator - between 2 images.
+
+template <typename L, typename R>
+oln::image_from_pw< oln::pw::minus< oln::pw::image<L>,
+ oln::pw::image<R> > >
+operator - (const oln::abstract::image<L>& lhs,
+ const oln::abstract::image<R>& rhs)
+{
+ return oln::for_all_p(oln::p_value(lhs) - oln::p_value(rhs));
+}
+
+
+/// Operator - (unary) on image.
+
+template <typename R>
+oln::image_from_pw< oln::pw::minus< oln::pw::literal< oln_pw_value_type(R) >,
+ oln::pw::image<R> > >
+operator - (const oln::abstract::image<R>& rhs)
+{
+ return oln::for_all_p( - oln::p_value(rhs));
+}
+
+
+/// Operator * between 2 images.
+
+template <typename L, typename R>
+oln::image_from_pw< oln::pw::times< oln::pw::image<L>,
+ oln::pw::image<R> > >
+operator * (const oln::abstract::image<L>& lhs,
+ const oln::abstract::image<R>& rhs)
+{
+ return oln::for_all_p(oln::p_value(lhs) * oln::p_value(rhs));
+}
+
+
+/// Operator / between 2 images.
+
+template <typename L, typename R>
+oln::image_from_pw< oln::pw::div< oln::pw::image<L>,
+ oln::pw::image<R> > >
+operator / (const oln::abstract::image<L>& lhs,
+ const oln::abstract::image<R>& rhs)
+{
+ return oln::for_all_p(oln::p_value(lhs) / oln::p_value(rhs));
+}
+
+
+
+# define oln_decl_binary_operator(NAME, SYMBOL, TYPE) \
+template <typename L> \
+oln::image_from_pw< oln::pw::NAME< oln::pw::image<L>, \
+ oln::pw::literal<TYPE> > > \
+operator SYMBOL (const oln::abstract::image<L>& lhs, \
+ TYPE value) \
+{ \
+ return oln::for_all_p(oln::p_value(lhs) SYMBOL oln::p_lit(value)); \
+} \
+template <typename R> \
+oln::image_from_pw< oln::pw::NAME< oln::pw::literal<TYPE>, \
+ oln::pw::image<R> > > \
+operator SYMBOL (TYPE value, \
+ const oln::abstract::image<R>& rhs) \
+{ \
+ return oln::for_all_p(oln::p_lit(value) SYMBOL oln::p_value(rhs)); \
+}
+
+
+
+oln_decl_binary_operator(plus, +, int)
+oln_decl_binary_operator(plus, +, float)
+oln_decl_binary_operator(plus, +, double)
+
+oln_decl_binary_operator(minus, -, int)
+oln_decl_binary_operator(minus, -, float)
+oln_decl_binary_operator(minus, -, double)
+
+oln_decl_binary_operator(times, *, int)
+oln_decl_binary_operator(times, *, float)
+oln_decl_binary_operator(times, *, double)
+
+oln_decl_binary_operator(div, /, int)
+oln_decl_binary_operator(div, /, float)
+oln_decl_binary_operator(div, /, double)
+
+
+
+#endif // ! OLENA_ARITH_OPS_HH
2
2