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
April 2005
- 8 participants
- 73 discussions
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
04 Apr '05
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/convert/ng_to_se.hh: Convert a neighborhood to a structuring
element.
* oln/core/value_box.hh: Fix operator==.
* oln/core/properties.hh: Add window property.
* oln/core/abstract/struct_elt.hh: Add operator-.
* oln/core/abstract/witer.hh (nth): Add method.
* oln/core/abstract/dpoint.hh (nth): Add method.
* oln/core/abstract/neighborhood.hh: Add a window property.
* oln/core/2d/dpoint2d.hh (nth): Add method.
* oln/core/2d/neighborhood2d.hh: Add a window property.
* oln/core/2d/fwd_witer2d.hh: Replace unknown type in constructor.
* oln/utils/clone.hh: Use concrete_type.
* oln/makefile.src: Add new files.
* oln/morpho/reconstruction.hh: New. Sequential and hybrid versions.
* oln/morpho/splitse.hh: New. Split a structuring element.
* oln/morpho/stat.hh: Typo fix.
* oln/morpho/erosion.hh: Fix erroneus function name .
* oln/io/write_image_2d_pnm.hh: Invert binary values (0=>1, 1=>0).
* oln/io/read_image_2d_pnm.hh: Invert binary values.
convert/ng_to_se.hh | 88 +++++
core/2d/dpoint2d.hh | 21 +
core/2d/fwd_witer2d.hh | 4
core/2d/neighborhood2d.hh | 18 -
core/abstract/dpoint.hh | 5
core/abstract/neighborhood.hh | 22 -
core/abstract/struct_elt.hh | 38 +-
core/abstract/witer.hh | 13
core/properties.hh | 1
core/value_box.hh | 18 -
io/read_image_2d_pnm.hh | 4
io/write_image_2d_pnm.hh | 2
makefile.src | 4
morpho/erosion.hh | 6
morpho/reconstruction.hh | 646 ++++++++++++++++++++++++++++++++++++++++++
morpho/splitse.hh | 208 +++++++++++++
morpho/stat.hh | 2
utils/clone.hh | 7
18 files changed, 1062 insertions, 45 deletions
Index: oln/convert/ng_to_se.hh
--- oln/convert/ng_to_se.hh (revision 0)
+++ oln/convert/ng_to_se.hh (revision 0)
@@ -0,0 +1,88 @@
+// 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/core/value_box.hh
--- oln/core/value_box.hh (revision 106)
+++ oln/core/value_box.hh (working copy)
@@ -81,11 +81,17 @@
/// op==
- bool operator==(const value_box<const I>& rhs) const
+ bool operator==(const value_box<I>& rhs) const
{
return this->value() == rhs.value();
}
+ template <typename II>
+ bool operator==(const value_box<II>& rhs) const
+ {
+ return this->value() < rhs.value();
+ }
+
template <typename V>
bool operator==(const V& rhs) const
{
@@ -113,7 +119,7 @@
template <typename II>
bool operator<(const value_box<II>& rhs) const
{
- return this->value() < value.value();
+ return this->value() < rhs.value();
}
/*! \brief specialized version for value_box<I>
@@ -122,7 +128,7 @@
*/
bool operator<(const value_box<I>& rhs) const
{
- return this->value() < value.value();
+ return this->value() < rhs.value();
}
/*! \brief op=
@@ -277,6 +283,12 @@
return this->value() == rhs.value();
}
+ template <typename II>
+ bool operator==(const value_box<const II>& rhs) const
+ {
+ return this->value() < rhs.value();
+ }
+
template <typename V>
bool operator==(const V& rhs) const
{
Index: oln/core/properties.hh
--- oln/core/properties.hh (revision 106)
+++ oln/core/properties.hh (working copy)
@@ -68,6 +68,7 @@
struct delegated_type;
struct size_type;
struct se_type;
+ struct window_type;
struct image_constness_type;
struct image_dimension_type;
Index: oln/core/abstract/struct_elt.hh
--- oln/core/abstract/struct_elt.hh (revision 106)
+++ oln/core/abstract/struct_elt.hh (working copy)
@@ -47,7 +47,7 @@
// category
template <typename E>
- struct set_category< abstract::struct_elt<E> >
+ struct set_category< abstract::struct_elt<E> >
{
typedef category::struct_elt ret;
};
@@ -71,7 +71,7 @@
<< " fwd_witer_type = " << typeid(fwd_witer_type).name() << "," << std::endl
<< " dpoint_type = " << typeid(dpoint_type).name() << " }" << std::endl;
}
-
+
};
mlc_register_prop(category::struct_elt, dpoint_type);
@@ -137,7 +137,7 @@
get_delta() const
{
return this->exact().impl_get_delta();
- }
+ }
coord_t
delta_update(const dpoint_type& dp)
@@ -145,14 +145,36 @@
return this->exact().impl_delta_update(dp);
}
+ exact_type
+ operator-() const
+ {
+ exact_type se(this->exact());
+
+ se.sym();
+ return se;
+ }
+
+ void
+ sym()
+ {
+ this->exact().impl_sym();
+ }
+
protected:
+ void
+ impl_sym()
+ {
+ for (unsigned i = 0; i < this->card(); ++i)
+ dp_[i] = - dp_[i];
+ }
+
bool
impl_has(const dpoint_type& dp) const
{
return std::find(dp_.begin(), dp_.end(), dp) != dp_.end();
- }
-
+ }
+
exact_type&
impl_add(const dpoint_type& dp)
{
@@ -172,14 +194,14 @@
impl_card() const
{
return dp_.size();
- }
+ }
const dpoint_type
impl_at(unsigned i) const
{
precondition(i < this->card());
return dp_[i];
- }
+ }
struct_elt() : dp_(), delta_(0)
{};
@@ -208,6 +230,6 @@
o << "]";
return o;
}
-
+
#endif // ! OLENA_CORE_STRUCT_ELT_HH
Index: oln/core/abstract/witer.hh
--- oln/core/abstract/witer.hh (revision 106)
+++ oln/core/abstract/witer.hh (working copy)
@@ -64,7 +64,7 @@
}
};
- mlc_register_prop(category::witer, se_type);
+ mlc_register_prop(category::witer, se_type);
namespace abstract {
@@ -104,7 +104,12 @@
this->exact().impl_invalidate();
postcondition(! this->is_valid());
}
-
+
+ coord_t nth(unsigned i)
+ {
+ return this->se_[this->pos_].nth(i);
+ }
+
protected:
void impl_start()
@@ -127,8 +132,8 @@
pos_ = se_.card();
}
- witer(const se_type& se)
- : se_(se), pos_(0)
+ witer(const se_type& se)
+ : se_(se), pos_(0)
{}
const se_type& se_;
Index: oln/core/abstract/dpoint.hh
--- oln/core/abstract/dpoint.hh (revision 106)
+++ oln/core/abstract/dpoint.hh (working copy)
@@ -65,6 +65,11 @@
return not this->operator==(rhs);
}
+ coord_t nth(unsigned i) const
+ {
+ return this->exact().impl_nth(i);
+ }
+
protected:
dpoint() {}
Index: oln/core/abstract/neighborhood.hh
--- oln/core/abstract/neighborhood.hh (revision 106)
+++ oln/core/abstract/neighborhood.hh (working copy)
@@ -47,7 +47,7 @@
// category
template <typename E>
- struct set_category< abstract::neighborhood<E> >
+ struct set_category< abstract::neighborhood<E> >
{
typedef category::neighborhood ret;
};
@@ -61,6 +61,7 @@
mlc_decl_prop(category::neighborhood, dpoint_type);
mlc_decl_prop(category::neighborhood, size_type);
+ mlc_decl_prop(category::neighborhood, window_type);
static void echo(std::ostream& ostr)
{
@@ -69,11 +70,12 @@
<< " size_type = " << typeid(size_type).name() << "," << std::endl
<< " dpoint_type = " << typeid(dpoint_type).name() << " }" << std::endl;
}
-
+
};
mlc_register_prop(category::neighborhood, dpoint_type);
mlc_register_prop(category::neighborhood, size_type);
+ mlc_register_prop(category::neighborhood, window_type);
namespace abstract {
@@ -134,7 +136,7 @@
get_delta() const
{
return this->exact().impl_get_delta();
- }
+ }
coord_t
delta_update(const dpoint_type& dp)
@@ -148,8 +150,8 @@
impl_has(const dpoint_type& dp) const
{
return std::find(dp_.begin(), dp_.end(), dp) != dp_.end();
- }
-
+ }
+
exact_type&
impl_add(const dpoint_type& dp)
{
@@ -161,25 +163,25 @@
this->delta_update(dp);
return this->exact();
}
-
+
coord_t
impl_get_delta() const
{
return delta_;
}
-
+
unsigned
impl_card() const
{
return dp_.size();
- }
+ }
const dpoint_type
impl_at(unsigned i) const
{
precondition(i < this->card());
return dp_[i];
- }
+ }
neighborhood() : dp_(), delta_(0)
{};
@@ -208,6 +210,6 @@
o << "]";
return o;
}
-
+
#endif // ! OLENA_CORE_NEIGHBORHOOD_HH
Index: oln/core/2d/dpoint2d.hh
--- oln/core/2d/dpoint2d.hh (revision 106)
+++ oln/core/2d/dpoint2d.hh (working copy)
@@ -94,10 +94,31 @@
const coord_t row() const { return row_; }
const coord_t col() const { return col_; }
+ //FIXME : name it impl_nth when dpoint2d derives from abstract::dpoint
+ const coord_t nth(unsigned i) const
+ {
+ assert(i < 2);
+ if (i == 0)
+ return row_;
+ else
+ return col_;
+ }
+
+
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)
+ {
+ assert(i < 2);
+ if (i == 0)
+ return row_;
+ else
+ return col_;
+ }
+
protected:
coord_t row_, col_;
};
Index: oln/core/2d/neighborhood2d.hh
--- oln/core/2d/neighborhood2d.hh (revision 106)
+++ oln/core/2d/neighborhood2d.hh (working copy)
@@ -30,6 +30,7 @@
# include <oln/core/2d/dpoint2d.hh>
# include <oln/core/2d/size2d.hh>
+# include <oln/core/2d/window2d.hh>
# include <oln/core/coord.hh>
# include <oln/core/abstract/neighborhood.hh>
@@ -39,7 +40,7 @@
// category
template <>
- struct set_category< neighborhood2d >
+ struct set_category< neighborhood2d >
{ typedef category::neighborhood ret; };
// super_type
@@ -50,18 +51,19 @@
};
template <>
- struct set_props< category::neighborhood, neighborhood2d >
+ struct set_props< category::neighborhood, neighborhood2d >
: public props_of<category::neighborhood>
{
typedef dpoint2d dpoint_type;
typedef size2d size_type;
+ typedef window2d window_type;
};
class neighborhood2d : public abstract::neighborhood<neighborhood2d>
{
public:
-
+
typedef abstract::neighborhood<neighborhood2d> super_type;
/*!
@@ -86,13 +88,13 @@
{
for (unsigned i = 0; i < 2 * n; i += 2)
this->add(dpoint_type(crd[i], crd[i+1]));
- }
+ }
neighborhood2d&
add(const dpoint_type& dp)
{
return this->exact().impl_add(dp);
- }
+ }
neighborhood2d&
add(coord_t row, coord_t col)
@@ -100,8 +102,8 @@
dpoint_type dp(row, col);
return add(dp);
}
-
+
/// Return the name of the type.
static std::string
name()
@@ -116,7 +118,7 @@
delta_(abs(dp.col()));
return delta_;
}
-
+
};
inline const neighborhood2d&
@@ -134,7 +136,7 @@
static const neighborhood2d neighb(4, crd);
return neighb;
}
-
+
} // end of oln
#endif // OLENA_CORE_NEIGHBORHOOD2D_HH
Index: oln/core/2d/fwd_witer2d.hh
--- oln/core/2d/fwd_witer2d.hh (revision 106)
+++ oln/core/2d/fwd_witer2d.hh (working copy)
@@ -48,13 +48,13 @@
{
typedef window2d se_type;
};
-
+
struct fwd_witer2d : public abstract::witer< fwd_witer2d >
{
typedef abstract::witer<fwd_witer2d> super_type;
- fwd_witer2d(const se_type& se) :
+ fwd_witer2d(const window2d& se) :
super_type(se)
{
this->exact_ptr = this;
Index: oln/utils/clone.hh
--- oln/utils/clone.hh (revision 106)
+++ oln/utils/clone.hh (working copy)
@@ -60,10 +60,11 @@
namespace impl {
template <typename I>
- struct clone_type : public abstract::image_unary_operator<I, I, clone_type<I> >
+ struct clone_type
+ : public abstract::image_unary_operator<oln_type_of(I, concrete), I, clone_type<I> >
// FIXME: use concrete_type; Cf. erosion.hh
{
- typedef abstract::image_unary_operator<I, I, clone_type<I> > super_type;
+ typedef abstract::image_unary_operator<oln_type_of(I, concrete), I, clone_type<I> > super_type;
clone_type(const abstract::image<I>& input) :
super_type(input)
@@ -72,7 +73,7 @@
void impl_run()
{
- I tmp(this->input.size()); // FIXME: trick
+ oln_type_of(I, concrete) tmp(this->input.size()); // FIXME: trick
this->output = tmp;
oln_type_of(I, fwd_piter) p(this->input.size());
Index: oln/makefile.src
--- oln/makefile.src (revision 106)
+++ oln/makefile.src (working copy)
@@ -13,6 +13,7 @@
basics3d.hh \
config/pconf.hh \
config/system.hh \
+ convert/ng_to_se.hh \
convert/value_to_point.hh \
core/1d/array1d.hh \
core/1d/dpoint1d.hh \
@@ -87,6 +88,9 @@
io/write_image_2d_pnm.hh \
level/compare.hh \
level/fill.hh \
+ morpho/dilation.hh \
morpho/erosion.hh \
+ morpho/reconstruction.hh \
+ morpho/splitse.hh \
morpho/stat.hh \
utils/clone.hh
Index: oln/morpho/reconstruction.hh
--- oln/morpho/reconstruction.hh (revision 0)
+++ oln/morpho/reconstruction.hh (revision 0)
@@ -0,0 +1,646 @@
+// Copyright (C) 2001, 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 filek 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_MORPHO_RECONSTRUCTION_HH
+# define OLENA_MORPHO_RECONSTRUCTION_HH
+
+# include <queue>
+
+# include <mlc/contract.hh>
+# include <oln/convert/ng_to_se.hh>
+# include <oln/morpho/splitse.hh>
+# include <oln/level/compare.hh>
+# include <oln/core/abstract/neighborhood.hh>
+# include <oln/core/properties.hh>
+# include <oln/core/abstract/image_operator.hh>
+# include <oln/utils/clone.hh>
+
+// FIXME: ADD TESTS !!!!
+
+namespace oln {
+
+ namespace morpho {
+
+ // fwd decl
+ template <typename I, typename E> struct reconstruction_ret;
+
+ }
+
+ // category
+ template <typename I, typename E>
+ struct set_category< morpho::reconstruction_ret<I,E> > { typedef category::image ret; };
+
+ // super_type
+ template <typename I, typename E>
+ struct set_super_type< morpho::reconstruction_ret<I,E> >
+ {
+ typedef abstract::image_binary_operator<I, I, I, morpho::reconstruction_ret<I, E> > ret;
+ // FIXME: see below
+ };
+
+
+ namespace morpho {
+
+ template <typename I, typename N>
+ struct reconstruction_ret : public abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> >
+ // FIXME: abstract::image_binary_operator<oln_type_of(I, concrete), ...
+ {
+ typedef abstract::image_binary_operator<I, I, I, reconstruction_ret<I, N> > super_type;
+
+ const N ng;
+
+ reconstruction_ret(const abstract::non_vectorial_image<I>& input1,
+ const abstract::non_vectorial_image<I>& input2,
+ const abstract::neighborhood<N>& ng) :
+ super_type(input1.exact(), input2.exact()),
+ ng(ng.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>
+ {
+ 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)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ 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));
+
+ 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)
+ {
+ 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());
+ for_all (bkd_p)
+ work[bkd_p] = ntg::min(morpho::max(work, bkd_p, se_minus), this->input2[bkd_p].value());
+ non_stability = !(level::is_equal(work, output));
+ output = work;
+ }
+ this->output = output;
+ }
+ };
+
+ }
+
+ 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;
+ }
+ }// 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>
+ {
+ 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)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ 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());
+
+ for_all (fwd_p)
+ output[fwd_p] = ntg::min(morpho::max(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))
+ 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::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_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>
+ {
+ typedef reconstruction_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)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ 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));
+
+ 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)
+ {
+ 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;
+ }
+ 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;
+ }
+
+ } // 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>
+ {
+ typedef reconstruction_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)
+
+ : super_type(input1, input2, ng)
+ {}
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+ precondition(this->input1.size() == this->input2.size());
+ precondition(level::is_greater_or_equal(this->input2, this->input1));
+
+ 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());
+
+ 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;
+ }
+ };
+
+ }
+
+ 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;
+ }
+ }// hybrid
+
+ }
+
+}
+
+#endif // ! OLENA_MORPHO_RECONSTRUCTION_HH
Index: oln/morpho/splitse.hh
--- oln/morpho/splitse.hh (revision 0)
+++ oln/morpho/splitse.hh (revision 0)
@@ -0,0 +1,208 @@
+// Copyright (C) 2001, 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_MORPHO_SPLITSE_HH
+# define OLENA_MORPHO_SPLITSE_HH
+
+# include <oln/basics.hh>
+
+# include <oln/core/1d/size1d.hh>
+# include <oln/core/2d/size2d.hh>
+# include <oln/core/3d/size3d.hh>
+
+namespace oln {
+ namespace morpho {
+
+ template <class S>
+ struct dim_traits
+ {
+ };
+
+ template <>
+ struct dim_traits<size1d>
+ {
+ enum {dim = 1};
+ };
+
+ template <>
+ struct dim_traits<size2d>
+ {
+ enum {dim = 2};
+ };
+
+ template <>
+ struct dim_traits<size3d>
+ {
+ enum {dim = 3};
+ };
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0.
+ **
+ */
+
+
+ template<class E>
+ E
+ get_plus_se_only(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) < 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) > 0) {
+ break;
+ }
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
+ ** belongs to [[0..dim-1]] p(i) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_plus_se_p(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) < 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) > 0) {
+ break;
+ }
+ // All p.nth(n) are 0.
+ if (n == dim_traits<oln_type_of(E, size)>::dim)
+ out.add(dp);
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_minus_se_only(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) > 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) < 0) {
+ break;
+ }
+ }
+ return out;
+ }
+
+ /*!
+ ** \brief Get a sub part of a structuring element.
+ **
+ ** \param E Exact type of the structuring element.
+ **
+ ** \arg se The structuring element.
+ **
+ ** A point p take part of the new structuring element if it exists
+ ** a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j
+ ** that belongs to [[0..i-1]] p(j) = 0 or if for all i that
+ ** belongs to [[0..dim-1]] p(i) = 0.
+ **
+ */
+ template<class E>
+ E
+ get_minus_se_p(const abstract::struct_elt<E>& se)
+ {
+ oln_type_of(E, fwd_witer) dp(se.exact());
+ E out;
+
+ for_all (dp)
+ {
+ unsigned n;
+ for (n = 0; n < dim_traits<oln_type_of(E, size)>::dim; ++n)
+ if (dp.nth(n) > 0) {
+ out.add(dp);
+ break;
+ } else if (dp.nth(n) < 0) {
+ break;
+ }
+ // All p.nth(n) are 0.
+ if (n == dim_traits<oln_type_of(E, size)>::dim)
+ out.add(dp);
+ }
+ return out;
+ }
+
+ } // morpho
+} // oln
+
+#endif // OLENA_MORPHO_SPLITSE_HH
Index: oln/morpho/stat.hh
--- oln/morpho/stat.hh (revision 106)
+++ oln/morpho/stat.hh (working copy)
@@ -47,7 +47,7 @@
** \param E Structuring element type.
** \param V Associated value type.
*/
- template <class I, class E, class V =oln_type_of(I, value)>
+ template <class I, class E, class V = oln_type_of(I, value)>
struct stat_
{
/*!
Index: oln/morpho/erosion.hh
--- oln/morpho/erosion.hh (revision 106)
+++ oln/morpho/erosion.hh (working copy)
@@ -43,7 +43,7 @@
/// Erosion as a procedure (do not use it; prefer morpho::erosion).
template<typename I, typename S>
- oln_type_of(I, concrete) dilation(const abstract::image<I>& input,
+ oln_type_of(I, concrete) erosion(const abstract::image<I>& input,
const abstract::struct_elt<S>& se)
{
oln_type_of(I, concrete) output(input.size());
@@ -131,14 +131,14 @@
typedef typename super_type::output_type output_type;
const E se;
-
+
erosion_ret(const abstract::image<I>& input,
const abstract::struct_elt<E>& se) :
super_type(input),
se(se.exact())
{
}
-
+
};
Index: oln/io/write_image_2d_pnm.hh
--- oln/io/write_image_2d_pnm.hh (revision 106)
+++ oln/io/write_image_2d_pnm.hh (working copy)
@@ -122,7 +122,7 @@
bin_v = 0;
ret = true;
}
- if (c == value_type(1))
+ if (c == value_type(0))
bin_v |= 1 << bin_offset;
bin_offset--;
return ret;
Index: oln/io/read_image_2d_pnm.hh
--- oln/io/read_image_2d_pnm.hh (revision 106)
+++ oln/io/read_image_2d_pnm.hh (working copy)
@@ -172,9 +172,9 @@
offset = 7;
}
if ((int)(v & (1<<offset--)) == 0)
+ c = 0;
+ else
c = 1;
- else
- c = 0;
}
};
1
1
proto-1.0 106: Add connected component labelling algorithm using the Tarjan Union-Find (naive version)
by Simon Odou 03 Apr '05
by Simon Odou 03 Apr '05
03 Apr '05
Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/morpho/cc_tarjan.hh: New. Add the connected component
labelling algorithm using the Tarjan Union-Find.
cc_tarjan.hh | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 234 insertions(+)
Index: oln/morpho/cc_tarjan.hh
--- oln/morpho/cc_tarjan.hh (revision 0)
+++ oln/morpho/cc_tarjan.hh (revision 0)
@@ -0,0 +1,234 @@
+// 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_CC_TARJAN_HH
+# define OLENA_CC_TARJAN_HH
+
+# include <vector>
+
+# include <oln/basics2d.hh>
+# include <oln/core/abstract/image_operator.hh>
+# include <oln/level/fill.hh>
+
+//
+// Based on "Ruminations on Tarjan's Union-Find algorithm and connected
+// operators" of Thierry Geraud.
+//
+
+
+namespace oln {
+
+ // fwd decl
+ namespace morpho {
+ template <typename T, typename I, typename E> struct cc_tarjan_ret;
+ }
+
+ // FIXME: this macro is waiting for the mute.
+ // (we may use a property to do it)
+ #define tmp_mute(I, T) image2d< T >
+
+ // category
+ template <typename T, typename I, typename E>
+ struct set_category< morpho::cc_tarjan_ret<T,I,E> >
+ { typedef category::image ret; };
+
+ // super_type
+ template <typename T, typename I, typename E>
+ 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> >
+ ret;
+ };
+
+
+ namespace morpho {
+
+ template <typename T, typename I, typename E>
+ 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> >
+ 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())
+ {
+ }
+
+ };
+
+
+ namespace impl {
+
+
+ namespace misc {
+
+ // FIXME: This code should be generalized.
+ // While iterating on image and then on a neighborhood, here we do
+ // not want to see the neighborhood points ever seen.
+ std::vector<dpoint2d> get_superior(const neighborhood2d& n)
+ {
+ std::vector<dpoint2d> output;
+ for (unsigned i = 0; i < n.card(); ++i)
+ {
+ dpoint2d dp = n.dp(i);
+ if (dp.row() < 0 || (dp.row() == 0 && dp.col() < 0))
+ output.push_back(dp);
+ }
+ return output;
+ }
+
+ std::vector<dpoint2d> get_inferior(const neighborhood2d& n)
+ {
+ std::vector<dpoint2d> output;
+ for (unsigned i = 0; i < n.card(); ++i)
+ {
+ dpoint2d dp = n.dp(i);
+ if (dp.row() > 0 || (dp.row() == 0 && dp.col() > 0))
+ output.push_back(dp);
+ }
+ return output;
+ }
+
+ } // end of misc namespace
+
+
+ template <typename T, typename I, typename N>
+ struct generic_cc_tarjan : public cc_tarjan_ret<T, I, N>
+ {
+ typedef cc_tarjan_ret<T, I, N> super_type;
+ typedef typename super_type::output_type output_type;
+
+ tmp_mute(I, oln_type_of(I, point)) parent;
+ T ncomps;
+
+ generic_cc_tarjan(const abstract::image<I>& input,
+ const abstract::neighborhood<N>& ng) :
+ super_type(input, ng),
+ parent(input.size())
+ {
+ }
+
+ void impl_run()
+ {
+ mlc::is_true<mlc::type::eq<oln_type_of(I, size),
+ oln_type_of(N, size)>::ret>::ensure();
+
+ output_type tmp(this->input.size()); // FIXME: trick
+ this->output = tmp;
+
+ first_pass();
+ second_pass();
+ }
+
+ void first_pass()
+ {
+ std::vector<dpoint2d> neighb = misc::get_inferior(this->ng);
+ oln_type_of(I, bkd_piter) p(this->input.size());
+ for_all(p)
+ if (this->input[p])
+ {
+ make_set(p);
+ for (unsigned v = 0; v < neighb.size(); ++v)
+ {
+ oln_type_of(I, point) n = oln_type_of(I, point)(p) + neighb[v];
+ 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);
+ 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]);
+ }
+ }
+
+ void make_set(const oln_type_of(I, point)& x)
+ {
+ parent[x] = x;
+ }
+
+ oln_type_of(I, point) find_root(const oln_type_of(I, point)& x)
+ {
+ if (parent[x] != x)
+ {
+ parent[x] = find_root(parent[x]);
+ return parent[x];
+ }
+ return x;
+ }
+
+ 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
+
+
+ /// Connected component labelling via Tarjan Union-Find generic routine.
+
+ // T is the component label type (usually unsigned).
+ template<typename T, typename I, typename N>
+ cc_tarjan_ret<T, I, N> cc_tarjan(const abstract::image<I>& input,
+ const abstract::neighborhood<N>& ng)
+ {
+ impl::generic_cc_tarjan<T, I, N> tmp(input, ng);
+ tmp.run();
+ return tmp;
+ }
+
+
+ } // end of namespace oln::morpho
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CC_TARJAN_HH
1
0
proto-1.0 105: Fix the backward point iterator (missing property declaration)
by Simon Odou 03 Apr '05
by Simon Odou 03 Apr '05
03 Apr '05
Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/core/properties.hh: Add missing property declaration for
backward point iterator and point iterator.
* oln/core/abstract/image.hh: Likewise.
abstract/image.hh | 4 ++++
properties.hh | 1 +
2 files changed, 5 insertions(+)
Index: oln/core/properties.hh
--- oln/core/properties.hh (revision 104)
+++ oln/core/properties.hh (working copy)
@@ -60,6 +60,7 @@
struct point_type;
struct concrete_type;
struct dpoint_type;
+ struct piter_type;
struct fwd_piter_type;
struct bkd_piter_type;
struct fwd_witer_type;
Index: oln/core/abstract/image.hh
--- oln/core/abstract/image.hh (revision 104)
+++ oln/core/abstract/image.hh (working copy)
@@ -64,7 +64,9 @@
mlc_decl_prop(category::image, value_type);
mlc_decl_prop(category::image, point_type);
mlc_decl_prop(category::image, size_type);
+ mlc_decl_prop(category::image, piter_type);
mlc_decl_prop(category::image, fwd_piter_type);
+ mlc_decl_prop(category::image, bkd_piter_type);
mlc_decl_prop_with_default(category::image, value_storage_type, mlc::no_type);
mlc_decl_prop_with_default(category::image, storage_type, mlc::no_type);
mlc_decl_prop_with_default(category::image, delegated_type, mlc::no_type);
@@ -101,7 +103,9 @@
mlc_register_prop(category::image, value_type);
mlc_register_prop(category::image, point_type);
mlc_register_prop(category::image, size_type);
+ mlc_register_prop(category::image, piter_type);
mlc_register_prop(category::image, fwd_piter_type);
+ mlc_register_prop(category::image, bkd_piter_type);
mlc_register_prop(category::image, value_storage_type);
mlc_register_prop(category::image, storage_type);
mlc_register_prop(category::image, delegated_type);
1
0