https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add overloads in accu image and fix bugs.
* mln/accu/image/take_n_times.hh
(take_n_times_tests, take_n_times_dispatch)
(take_n_times, take_n_times_fastest): New overload for
argument as a value.
* mln/accu/image/take.hh (take): Likewise.
(todo): Remove; done.
* mln/accu/image/set_value.hh (set_value): Fix iterator.
(set_value_fastest): Fix missing border handling.
* mln/accu/image/take_as_init.hh: Likewise.
* mln/accu/image/take.hh: Copy to...
* mln/accu/image/untake.hh: ...this new file.
* mln/accu/image/all.hh: Update.
* mln/accu/sum.hh (trait): New.
(untake, set_value): New.
* tests/accu/image/take_n_times.cc: Augment.
* tests/accu/image/untake.cc: New.
* tests/accu/image/Makefile.am: Update.
mln/accu/image/all.hh | 1
mln/accu/image/set_value.hh | 7 -
mln/accu/image/take.hh | 113 ++++++++++++++++++++++---
mln/accu/image/take_as_init.hh | 5 -
mln/accu/image/take_n_times.hh | 145 ++++++++++++++++++++++++++++++--
mln/accu/image/untake.hh | 175 ++++++++++++++++++++++++++++++---------
mln/accu/sum.hh | 55 ++++++++++--
tests/accu/image/Makefile.am | 4
tests/accu/image/take_n_times.cc | 3
tests/accu/image/untake.cc | 53 +++++++++++
10 files changed, 486 insertions(+), 75 deletions(-)
Index: mln/accu/image/take_n_times.hh
--- mln/accu/image/take_n_times.hh (revision 3746)
+++ mln/accu/image/take_n_times.hh (working copy)
@@ -33,11 +33,11 @@
/// Update an image of accumulators by taking the contents of another
/// image with a multiplicity.
///
-/// \todo Add "take(input, n, arg_value)".
+/// \todo Add versions with n as unsigned.
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
-# include <mln/border/resize.hh>
+# include <mln/border/resize_equal.hh>
namespace mln
@@ -49,6 +49,10 @@
namespace image
{
+ template <typename I, typename J>
+ void
+ take_n_times(Image<I>& input, const Image<J>& n_times, const
mln_deduce(I, value, argument)& arg);
+
template <typename I, typename J, typename K>
void
take_n_times(Image<I>& input, const Image<J>& n_times, const
Image<K>& arg);
@@ -63,7 +67,25 @@
namespace internal
{
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times_tests(Image<I>& input_, const Image<J>& n_times_)
+ {
+ I& input = exact(input_);
+ const J& n_times = exact(n_times_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(n_times.is_valid());
+
+ mln_precondition(n_times.domain() <= input.domain());
+
+ (void) input;
+ (void) n_times;
+ }
+
template <typename I, typename J, typename K>
+ inline
void
take_n_times_tests(Image<I>& input_, const Image<J>& n_times_, const
Image<K>& arg_)
{
@@ -91,12 +113,13 @@
namespace impl
{
- // Generic version.
+ // Generic versions.
namespace generic
{
template <typename I, typename J, typename K>
+ inline
void
take_n_times(Image<I>& input_, const Image<J>& n_times_, const
Image<K>& arg_)
{
@@ -119,12 +142,62 @@
trace::exiting("accu::impl::image::generic::take_n_times");
}
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times(Image<I>& input_, const Image<J>& n_times_, const
mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::impl::image::generic::take_n_times");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+ mlc_converts_to(mln_value(J), unsigned)::check();
+
+ I& input = exact(input_);
+ const J& n_times = exact(n_times_);
+
+ internal::take_n_times_tests(input, n_times);
+
+ mln_piter(J) p(n_times.domain());
+ for_all(p)
+ input(p).take_n_times(n_times(p), arg);
+
+ trace::exiting("accu::impl::image::generic::take_n_times");
+ }
+
} // end of namespace mln::accu::image::impl::generic
- // Fastest version.
+ // Fastest versions.
+
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times_fastest(Image<I>& input_, const Image<J>& n_times_,
const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::impl::image::take_n_times_fastest");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+ mlc_converts_to(mln_value(J), unsigned)::check();
+
+ I& input = exact(input_);
+ const J& n_times = exact(n_times_);
+
+ internal::take_n_times_tests(input, n_times);
+ // Extra (stronger) test:
+ mln_precondition(n_times.domain() == input.domain());
+
+ border::resize_equal(input, n_times);
+
+ mln_pixter(I) p_in(input);
+ mln_pixter(const J) p_ntm(n_times);
+ for_all_2(p_in, p_ntm)
+ p_in.val().take_n_times( p_ntm.val(), arg );
+
+ trace::exiting("accu::impl::image::take_n_times_fastest");
+ }
template <typename I, typename J, typename K>
+ inline
void
take_n_times_fastest(Image<I>& input_, const Image<J>& n_times_,
const Image<K>& arg_)
{
@@ -165,7 +238,45 @@
namespace internal
{
+ // 'arg' as value.
+
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times_dispatch(trait::image::speed::any,
+ trait::image::speed::any,
+ Image<I>& input, const Image<J>& n_times, const
mln_deduce(I, value, argument)& arg)
+ {
+ impl::generic::take_n_times(input, n_times, arg);
+ }
+
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times_dispatch(trait::image::speed::fastest,
+ trait::image::speed::fastest,
+ Image<I>& input, const Image<J>& n_times, const
mln_deduce(I, value, argument)& arg)
+ {
+ if (exact(n_times).domain() == exact(input).domain())
+ impl::take_n_times_fastest(input, n_times, arg);
+ else
+ impl::generic::take_n_times(input, n_times, arg);
+ }
+
+ template <typename I, typename J>
+ inline
+ void
+ take_n_times_dispatch(Image<I>& input, const Image<J>& n_times,
const mln_deduce(I, value, argument)& arg)
+ {
+ take_n_times_dispatch(mln_trait_image_speed(I)(),
+ mln_trait_image_speed(J)(),
+ input, n_times, arg);
+ }
+
+ // Triplet of images.
+
template <typename I, typename J, typename K>
+ inline
void
take_n_times_dispatch(trait::image::speed::any,
trait::image::speed::any,
@@ -176,6 +287,7 @@
}
template <typename I, typename J, typename K>
+ inline
void
take_n_times_dispatch(trait::image::speed::fastest,
trait::image::speed::fastest,
@@ -190,6 +302,7 @@
}
template <typename I, typename J, typename K>
+ inline
void
take_n_times_dispatch(Image<I>& input, const Image<J>& n_times,
const Image<K>& arg)
{
@@ -202,11 +315,27 @@
} // end of namespace mln::accu::image::internal
- // Facade.
+ // Facades.
+
+ template <typename I, typename J>
+ void
+ take_n_times(Image<I>& input, const Image<J>& n_times, const
mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::image::take_n_times");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+ mlc_converts_to(mln_value(J), unsigned)::check();
+
+ internal::take_n_times_tests(input, n_times);
+ internal::take_n_times_dispatch(input, n_times, arg);
+
+ trace::exiting("accu::image::take_n_times");
+ }
template <typename I, typename J, typename K>
+ inline
void
- take_n_times(Image<I>& input_, const Image<J>& n_times_, const
Image<K>& arg_)
+ take_n_times(Image<I>& input, const Image<J>& n_times, const
Image<K>& arg)
{
trace::entering("accu::image::take_n_times");
@@ -214,10 +343,6 @@
mlc_converts_to(mln_value(J), unsigned)::check();
mlc_converts_to(mln_value(K), mln_deduce(I, value, argument))::check();
- I& input = exact(input_);
- const J& n_times = exact(n_times_);
- const K& arg = exact(arg_);
-
internal::take_n_times_tests(input, n_times, arg);
internal::take_n_times_dispatch(input, n_times, arg);
Index: mln/accu/image/take.hh
--- mln/accu/image/take.hh (revision 3746)
+++ mln/accu/image/take.hh (working copy)
@@ -30,10 +30,8 @@
/// \file mln/accu/image/take.hh
///
-/// Update an image of accumulators by taking the contents of another
-/// image.
-///
-/// \todo Add "take(input, arg_value)".
+/// Update an image of accumulators by taking a value or the contents
+/// of another image.
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
@@ -49,12 +47,15 @@
namespace image
{
+ template <typename I>
+ void
+ take(Image<I>& input, const mln_deduce(I, value, argument)& arg);
+
template <typename I, typename J>
void
take(Image<I>& input, const Image<J>& arg);
-
# ifndef MLN_INCLUDE_ONLY
@@ -64,6 +65,7 @@
{
template <typename I, typename J>
+ inline
void
take_tests(Image<I>& input_, const Image<J>& arg_)
{
@@ -88,12 +90,32 @@
namespace impl
{
- // Generic version.
+ // Generic versions.
namespace generic
{
+ template <typename I>
+ inline
+ void
+ take(Image<I>& input_, const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::impl::image::generic::take");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+
+ I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ input(p).take(arg);
+
+ trace::exiting("accu::impl::image::generic::take");
+ }
+
template <typename I, typename J>
+ inline
void
take(Image<I>& input_, const Image<J>& arg_)
{
@@ -117,9 +139,29 @@
} // end of namespace mln::accu::image::impl::generic
- // Fastest version.
+ // Fastest versions.
+
+ template <typename I>
+ inline
+ void
+ take_fastest(Image<I>& input_, const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::impl::image::take_fastest");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+
+ I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ mln_pixter(I) px(input);
+ for_all(px)
+ px.val().take(arg);
+
+ trace::exiting("accu::impl::image::take_fastest");
+ }
template <typename I, typename J>
+ inline
void
take_fastest(Image<I>& input_, const Image<J>& arg_)
{
@@ -154,7 +196,39 @@
namespace internal
{
+ // 'arg' as value.
+
+ template <typename I>
+ inline
+ void
+ take_dispatch(trait::image::speed::any,
+ Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ impl::generic::take(input, arg);
+ }
+
+ template <typename I>
+ inline
+ void
+ take_dispatch(trait::image::speed::fastest,
+ Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ impl::take_fastest(input, arg);
+ }
+
+ template <typename I>
+ inline
+ void
+ take_dispatch(Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ take_dispatch(mln_trait_image_speed(I)(),
+ input, arg);
+ }
+
+ // 'arg' as image.
+
template <typename I, typename J>
+ inline
void
take_dispatch(trait::image::speed::any,
trait::image::speed::any,
@@ -164,6 +238,7 @@
}
template <typename I, typename J>
+ inline
void
take_dispatch(trait::image::speed::fastest,
trait::image::speed::fastest,
@@ -176,6 +251,7 @@
}
template <typename I, typename J>
+ inline
void
take_dispatch(Image<I>& input, const Image<J>& arg)
{
@@ -187,20 +263,33 @@
} // end of namespace mln::accu::image::internal
- // Facade.
+ // Facades.
+
+ template <typename I>
+ inline
+ void
+ take(Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::image::take");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+
+ mln_precondition(exact(input).is_valid());
+ internal::take_dispatch(input, arg);
+
+ trace::exiting("accu::image::take");
+ }
template <typename I, typename J>
+ inline
void
- take(Image<I>& input_, const Image<J>& arg_)
+ take(Image<I>& input, const Image<J>& arg)
{
trace::entering("accu::image::take");
mlc_is_a(mln_value(I), Accumulator)::check();
mlc_converts_to(mln_value(J), mln_deduce(I, value, argument))::check();
- I& input = exact(input_);
- const J& arg = exact(arg_);
-
internal::take_tests(input, arg);
internal::take_dispatch(input, arg);
Index: mln/accu/image/set_value.hh
--- mln/accu/image/set_value.hh (revision 3746)
+++ mln/accu/image/set_value.hh (working copy)
@@ -31,11 +31,10 @@
/// \file mln/accu/image/set_value.hh
///
/// Set the values of an image of accumulators.
-///
-/// \todo Add "set_value(Image<I>& input, const Image<J>&
values)".
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
+# include <mln/border/resize_equal.hh>
namespace mln
@@ -133,7 +132,7 @@
internal::set_value_tests(input, res);
- mln_piter(I) p(res.domain());
+ mln_piter(J) p(res.domain());
for_all(p)
input(p).set_value(res(p));
@@ -186,6 +185,8 @@
internal::set_value_tests(input, res);
mln_precondition(res.domain() == input.domain());
+ border::resize_equal(input, res);
+
mln_pixter(I) p_in(input);
mln_pixter(const J) p_res(res);
for_all_2(p_in, p_res)
Index: mln/accu/image/untake.hh
--- mln/accu/image/untake.hh (revision 3746)
+++ mln/accu/image/untake.hh (working copy)
@@ -25,15 +25,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_IMAGE_TAKE_HH
-# define MLN_ACCU_IMAGE_TAKE_HH
+#ifndef MLN_ACCU_IMAGE_UNTAKE_HH
+# define MLN_ACCU_IMAGE_UNTAKE_HH
-/// \file mln/accu/image/take.hh
+/// \file mln/accu/image/untake.hh
///
-/// Update an image of accumulators by taking the contents of another
-/// image.
-///
-/// \todo Add "take(input, arg_value)".
+/// Update an image of accumulators by untaking a value or the
+/// contents of another image.
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
@@ -49,10 +47,13 @@
namespace image
{
- template <typename I, typename J>
+ template <typename I>
void
- take(Image<I>& input, const Image<J>& arg);
+ untake(Image<I>& input, const mln_deduce(I, value, argument)& arg);
+ template <typename I, typename J>
+ void
+ untake(Image<I>& input, const Image<J>& arg);
# ifndef MLN_INCLUDE_ONLY
@@ -64,8 +65,9 @@
{
template <typename I, typename J>
+ inline
void
- take_tests(Image<I>& input_, const Image<J>& arg_)
+ untake_tests(Image<I>& input_, const Image<J>& arg_)
{
I& input = exact(input_);
const J& arg = exact(arg_);
@@ -88,16 +90,36 @@
namespace impl
{
- // Generic version.
+ // Generic versions.
namespace generic
{
+ template <typename I>
+ inline
+ void
+ untake(Image<I>& input_, const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::impl::image::generic::untake");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+
+ I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ input(p).untake(arg);
+
+ trace::exiting("accu::impl::image::generic::untake");
+ }
+
template <typename I, typename J>
+ inline
void
- take(Image<I>& input_, const Image<J>& arg_)
+ untake(Image<I>& input_, const Image<J>& arg_)
{
- trace::entering("accu::impl::image::generic::take");
+ trace::entering("accu::impl::image::generic::untake");
mlc_is_a(mln_value(I), Accumulator)::check();
mlc_converts_to(mln_value(J), mln_deduce(I, value, argument))::check();
@@ -105,25 +127,45 @@
I& input = exact(input_);
const J& arg = exact(arg_);
- internal::take_tests(input, arg);
+ internal::untake_tests(input, arg);
mln_piter(J) p(arg.domain());
for_all(p)
- input(p).take(arg(p));
+ input(p).untake(arg(p));
- trace::exiting("accu::impl::image::generic::take");
+ trace::exiting("accu::impl::image::generic::untake");
}
} // end of namespace mln::accu::image::impl::generic
- // Fastest version.
+ // Fastest versions.
+
+ template <typename I>
+ inline
+ void
+ untake_fastest(Image<I>& input_, const mln_deduce(I, value, argument)&
arg)
+ {
+ trace::entering("accu::impl::image::untake_fastest");
+
+ mlc_is_a(mln_value(I), Accumulator)::check();
+
+ I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ mln_pixter(I) px(input);
+ for_all(px)
+ px.val().untake(arg);
+
+ trace::exiting("accu::impl::image::untake_fastest");
+ }
template <typename I, typename J>
+ inline
void
- take_fastest(Image<I>& input_, const Image<J>& arg_)
+ untake_fastest(Image<I>& input_, const Image<J>& arg_)
{
- trace::entering("accu::impl::image::take_fastest");
+ trace::entering("accu::impl::image::untake_fastest");
mlc_is_a(mln_value(I), Accumulator)::check();
mlc_converts_to(mln_value(J), mln_deduce(I, value, argument))::check();
@@ -131,7 +173,7 @@
I& input = exact(input_);
const J& arg = exact(arg_);
- internal::take_tests(input, arg);
+ internal::untake_tests(input, arg);
// Extra (stronger) test.
mln_precondition(arg.domain() == input.domain());
@@ -140,9 +182,9 @@
mln_pixter(I) p_in(input);
mln_pixter(const J) p_arg(arg);
for_all_2(p_in, p_arg)
- p_in.val().take( p_arg.val() );
+ p_in.val().untake( p_arg.val() );
- trace::exiting("accu::impl::image::take_fastest");
+ trace::exiting("accu::impl::image::untake_fastest");
}
} // end of namespace mln::accu::image::impl
@@ -154,32 +196,66 @@
namespace internal
{
+ // 'arg' as value.
+
+ template <typename I>
+ inline
+ void
+ untake_dispatch(trait::image::speed::any,
+ Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ impl::generic::untake(input, arg);
+ }
+
+ template <typename I>
+ inline
+ void
+ untake_dispatch(trait::image::speed::fastest,
+ Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ impl::untake_fastest(input, arg);
+ }
+
+ template <typename I>
+ inline
+ void
+ untake_dispatch(Image<I>& input, const mln_deduce(I, value, argument)&
arg)
+ {
+ untake_dispatch(mln_trait_image_speed(I)(),
+ input, arg);
+ }
+
+ // 'arg' as image.
+
template <typename I, typename J>
+ inline
void
- take_dispatch(trait::image::speed::any,
+ untake_dispatch(trait::image::speed::any,
trait::image::speed::any,
Image<I>& input, const Image<J>& arg)
{
- impl::generic::take(input, arg);
+ impl::generic::untake(input, arg);
}
template <typename I, typename J>
+ inline
void
- take_dispatch(trait::image::speed::fastest,
+ untake_dispatch(trait::image::speed::fastest,
trait::image::speed::fastest,
Image<I>& input, const Image<J>& arg)
{
if (exact(arg).domain() == exact(input).domain())
- impl::take_fastest(input, arg);
+ impl::untake_fastest(input, arg);
else
- impl::generic::take(input, arg);
+ impl::generic::untake(input, arg);
}
template <typename I, typename J>
+ inline
void
- take_dispatch(Image<I>& input, const Image<J>& arg)
+ untake_dispatch(Image<I>& input, const Image<J>& arg)
{
- take_dispatch(mln_trait_image_speed(I)(),
+ untake_dispatch(mln_trait_image_speed(I)(),
mln_trait_image_speed(J)(),
input, arg);
}
@@ -187,24 +263,43 @@
} // end of namespace mln::accu::image::internal
- // Facade.
+ // Facades.
+
+ template <typename I>
+ inline
+ void
+ untake(Image<I>& input, const mln_deduce(I, value, argument)& arg)
+ {
+ trace::entering("accu::image::untake");
+
+ typedef mln_value(I) A;
+ mlc_is_a(A, Accumulator)::check();
+ mlc_equal(mln_trait_accumulator_has_untake(A),
+ trait::accumulator::has_untake::yes)::check();
+
+ mln_precondition(exact(input).is_valid());
+ internal::untake_dispatch(input, arg);
+
+ trace::exiting("accu::image::untake");
+ }
template <typename I, typename J>
+ inline
void
- take(Image<I>& input_, const Image<J>& arg_)
+ untake(Image<I>& input, const Image<J>& arg)
{
- trace::entering("accu::image::take");
+ trace::entering("accu::image::untake");
- mlc_is_a(mln_value(I), Accumulator)::check();
+ typedef mln_value(I) A;
+ mlc_is_a(A, Accumulator)::check();
+ mlc_equal(mln_trait_accumulator_has_untake(A),
+ trait::accumulator::has_untake::yes)::check();
mlc_converts_to(mln_value(J), mln_deduce(I, value, argument))::check();
- I& input = exact(input_);
- const J& arg = exact(arg_);
-
- internal::take_tests(input, arg);
- internal::take_dispatch(input, arg);
+ internal::untake_tests(input, arg);
+ internal::untake_dispatch(input, arg);
- trace::exiting("accu::image::take");
+ trace::exiting("accu::image::untake");
}
# endif // ! MLN_INCLUDE_ONLY
@@ -216,4 +311,4 @@
} // end of namespace mln
-#endif // ! MLN_ACCU_IMAGE_TAKE_HH
+#endif // ! MLN_ACCU_IMAGE_UNTAKE_HH
Property changes on: mln/accu/image/untake.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/accu/image/all.hh
--- mln/accu/image/all.hh (revision 3746)
+++ mln/accu/image/all.hh (working copy)
@@ -52,6 +52,7 @@
# include <mln/accu/image/take.hh>
# include <mln/accu/image/take_n_times.hh>
# include <mln/accu/image/to_result.hh>
+# include <mln/accu/image/untake.hh>
#endif // ! MLN_ACCU_IMAGE_ALL_HH
Index: mln/accu/image/take_as_init.hh
--- mln/accu/image/take_as_init.hh (revision 3746)
+++ mln/accu/image/take_as_init.hh (working copy)
@@ -34,6 +34,7 @@
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/image.hh>
+# include <mln/border/resize_equal.hh>
namespace mln
@@ -123,7 +124,7 @@
internal::take_as_init_tests(input, values);
- mln_piter(I) p(values.domain());
+ mln_piter(J) p(values.domain());
for_all(p)
input(p).take_as_init(values(p));
@@ -170,6 +171,8 @@
// Extra test:
mln_precondition(values.domain() == input.domain());
+ border::resize_equal(input, values);
+
mln_pixter(I) p_in(input);
mln_pixter(const J) p_v(values);
for_all_2(p_in, p_v)
Index: mln/accu/sum.hh
--- mln/accu/sum.hh (revision 3746)
+++ mln/accu/sum.hh (working copy)
@@ -46,18 +46,38 @@
namespace mln
{
- namespace accu
+ // Forward declaration.
+ namespace accu { template <typename T, typename S> struct sum; }
+
+
+ // Traits.
+
+ namespace trait
{
+ template <typename T, typename S>
+ struct accumulator_< accu::sum<T,S> >
+ {
+ typedef accumulator::has_untake::yes has_untake;
+ typedef accumulator::has_set_value::yes has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::not_ok when_pix;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace accu
+ {
/// \brief Generic sum accumulator class.
- /*!
- * Parameter \c T is the type of values that we sum. Parameter \c
- * S is the type to store the value sum; the default type of
- * \c S is the summation type (property) of \c T.
- *
- * \ingroup modaccuvalues
- */
+ ///
+ /// Parameter \c T is the type of values that we sum. Parameter \c
+ /// S is the type to store the value sum; the default type of
+ /// \c S is the summation type (property) of \c T.
+ ///
+ /// \ingroup modaccuvalues
+ //
template <typename T, typename S = mln_sum(T)>
struct sum : public mln::accu::internal::base< const S&, sum<T,S> >
{
@@ -71,6 +91,9 @@
void take(const argument& t);
void take_as_init_(const argument& t);
void take(const sum<T,S>& other);
+
+ void untake(const argument& t);
+ void set_value(const S& s);
/// \}
/// Get the value of the accumulator.
@@ -105,6 +128,7 @@
} // end of namespace mln::accu::meta
+
# ifndef MLN_INCLUDE_ONLY
template <typename T, typename S>
@@ -131,6 +155,13 @@
template <typename T, typename S>
inline
+ void sum<T,S>::untake(const argument& t)
+ {
+ s_ -= static_cast<S>(t);
+ }
+
+ template <typename T, typename S>
+ inline
void sum<T,S>::take_as_init_(const argument& t)
{
s_ = static_cast<S>(t);
@@ -154,6 +185,14 @@
template <typename T, typename S>
inline
+ void
+ sum<T,S>::set_value(const S& s)
+ {
+ s_ = s;
+ }
+
+ template <typename T, typename S>
+ inline
bool
sum<T,S>::is_valid() const
{
Index: tests/accu/image/take_n_times.cc
--- tests/accu/image/take_n_times.cc (revision 3746)
+++ tests/accu/image/take_n_times.cc (working copy)
@@ -53,4 +53,7 @@
accu::image::take_n_times(ima, dta, dta);
mln_assertion(ima == (pw::cst(49) | ima.domain()));
+
+ accu::image::take_n_times(ima, (pw::cst(2) | ima.domain()), 1);
+ mln_assertion(ima == (pw::cst(51) | ima.domain()));
}
Index: tests/accu/image/Makefile.am
--- tests/accu/image/Makefile.am (revision 3746)
+++ tests/accu/image/Makefile.am (working copy)
@@ -8,7 +8,8 @@
take \
take_as_init \
take_n_times \
- to_result
+ to_result \
+ untake
init_SOURCES = init.cc
set_value_SOURCES = set_value.cc
@@ -16,5 +17,6 @@
take_as_init_SOURCES = take_as_init.cc
take_n_times_SOURCES = take_n_times.cc
to_result_SOURCES = to_result.cc
+untake_SOURCES = untake.cc
TESTS = $(check_PROGRAMS)
Index: tests/accu/image/untake.cc
--- tests/accu/image/untake.cc (revision 0)
+++ tests/accu/image/untake.cc (revision 0)
@@ -0,0 +1,53 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/accu/image/untake.cc
+///
+/// Tests on mln::accu::image::untake.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/data/fill.hh>
+#include <mln/level/compare.hh>
+#include <mln/pw/cst.hh>
+#include <mln/pw/image.hh>
+
+#include <mln/accu/sum.hh>
+#include <mln/accu/image/take_as_init.hh>
+#include <mln/accu/image/untake.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef accu::sum<int,int> A;
+ image2d<A> ima(2, 2);
+ accu::image::take_as_init(ima, 60);
+
+ accu::image::untake(ima, 9);
+ mln_assertion(ima == (pw::cst(51) | ima.domain()));
+}