cleanup-2008 2893: Cleanup optional methods in neighborhoods.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Cleanup optional methods in neighborhoods. * tests/make/dual_neighb.cc: Test foreground and bg methods. * mln/core/internal/neighborhood_base.hh (neighborhood_extra_impl, neighborhood_impl): New. (D): Change parameter into... (W): ...this; that allows for factoring code here. * mln/core/neighb.hh: Upgrade doc style. Update inheritance. (window, size, delta, dp): Move... * mln/core/internal/neighborhood_base.hh (neighborhood_impl): ...in this new class. * mln/core/concept/neighborhood.hh: Upgrade doc style. (operator==): New. * mln/metal/ands.hh: New. * mln/metal/all.hh: Update. * mln/win/multiple_size.hh (n): New parameter. (todo): New. * mln/make/dual_neighb.hh: Upgrade doc style. Update. mln/core/concept/neighborhood.hh | 30 ++++-- mln/core/internal/neighborhood_base.hh | 148 +++++++++++++++++++++++++++++---- mln/core/neighb.hh | 80 ++--------------- mln/make/dual_neighb.hh | 15 +-- mln/metal/all.hh | 1 mln/metal/ands.hh | 69 +++++++++++++++ mln/win/multiple_size.hh | 135 +++++++++++++++--------------- tests/make/dual_neighb.cc | 3 8 files changed, 313 insertions(+), 168 deletions(-) Index: tests/make/dual_neighb.cc --- tests/make/dual_neighb.cc (revision 2892) +++ tests/make/dual_neighb.cc (working copy) @@ -59,6 +59,9 @@ mln_assertion( count(ima, make::dual_neighb(ima, c4(), c8())) == c4().size() + c8().size() ); + mln_assertion( make::dual_neighb(ima, c4(), c8()).foreground() == c4() ); + mln_assertion( make::dual_neighb(ima, c4(), c8()).background() == c8() ); + // We can observe that the neighboord is not restricted by the // respective domains defined by ima(p) == false and ima(p) == true: // for instance, at (0,0) we are in the *object* (ima(0,0) == true), Index: mln/core/internal/neighborhood_base.hh --- mln/core/internal/neighborhood_base.hh (revision 2892) +++ mln/core/internal/neighborhood_base.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008 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 @@ -28,49 +28,163 @@ #ifndef MLN_CORE_INTERNAL_NEIGHBORHOOD_BASE_HH # define MLN_CORE_INTERNAL_NEIGHBORHOOD_BASE_HH -/*! \file mln/core/internal/neighborhood_base.hh - * - * \brief Definition of a base class for neighborhood classes. - */ +/// \file mln/core/internal/neighborhood_base.hh +/// +/// Definition of a base class for neighborhood classes. +/// +/// \todo Complete conditional implementation inheritance +/// w.r.t. properties. # include <mln/core/concept/neighborhood.hh> +# include <mln/core/concept/window.hh> namespace mln { + + // Forward declaration. + namespace win + { + template <unsigned n, typename W, typename F> + class multiple_size; + } + + namespace internal { + template <typename W, typename E> + struct neighborhood_extra_impl + : public Neighborhood<E> + { + }; - /*! A base class for neighborhood classes. - * - * \p D is a dpsite type. - */ - template <typename D, typename E> - struct neighborhood_base : public Neighborhood<E> + template <typename W, typename F, typename E> + struct neighborhood_extra_impl< win::multiple_size<2,W,F>, E > + : public Neighborhood<E> { - /// DPsite associated type. - typedef D dpsite; + /// Give the foreground neighborhood in the case of a dual + /// neighborhood. For instance, with (object:c4, background:c8), + /// the result is c4. + + neighb<W> foreground() const + { + W win = internal::force_exact<E>(*this).win().window_(1); // True, so object. + neighb<W> nbh(win); + return nbh; + } + + /// Give the background neighborhood in the case of a dual + /// neighborhood. For instance, with (object:c4, background:c8), + /// the result is c8. + + neighb<W> background() const + { + W win = internal::force_exact<E>(*this).win().window_(0); // False, so background. + neighb<W> nbh(win); + return nbh; + } + + }; + + + + + template <typename W, typename E> + struct neighborhood_impl : public neighborhood_extra_impl<W,E> + { + // Optional methods... + + /// Give the neighborhood size, i.e., the number of elements it + /// contains. + unsigned size() const; + + /// Give the maximum coordinate gap between the neighborhood + /// center and a neighboring point. + unsigned delta() const; + + /// Give the maximum coordinate gap between the neighborhood + /// center and a neighboring point. + const mln_dpsite(W)& dp(unsigned i) const; + + // end of Optional methods. + }; + + + /// Base class for neighborhood implementation classes. + /// + /// \p W is the underlying window type. + + template <typename W, typename E> + struct neighborhood_base : public neighborhood_impl<W,E> + { + /// Window associated type. + typedef W window; + + /// Dpsite associated type. + typedef mln_dpsite(W) dpsite; /// Psite associated type. - typedef mln_psite(D) psite; + typedef mln_psite(W) psite; /// Site associated type. - typedef mln_site(D) site; + typedef mln_site(W) site; protected: neighborhood_base(); }; + + # ifndef MLN_INCLUDE_ONLY - template <typename D, typename E> + + // neighborhood_base + + template <typename W, typename E> + inline + neighborhood_base<W,E>::neighborhood_base() + { + } + + + // neighborhood_impl + + template <typename W, typename E> + inline + unsigned + neighborhood_impl<W,E>::size() const + { + mlc_is(mln_trait_window_size(W), + trait::window::size::fixed)::check(); + return exact(this)->win().size(); + } + + template <typename W, typename E> + inline + unsigned + neighborhood_impl<W,E>::delta() const + { + mlc_is(mln_trait_window_support(W), + trait::window::support::regular)::check(); + mlc_is_not(mln_trait_window_definition(W), + trait::window::definition::varying)::check(); + return exact(this)->win().delta(); + } + + template <typename W, typename E> inline - neighborhood_base<D,E>::neighborhood_base() + const mln_dpsite(W)& + neighborhood_impl<W,E>::dp(unsigned i) const { + mlc_is(mln_trait_window_support(W), + trait::window::support::regular)::check(); + mlc_is(mln_trait_window_definition(W), + trait::window::definition::unique)::check(); + return exact(this)->win().dp(i); } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2892) +++ mln/core/neighb.hh (working copy) @@ -28,18 +28,14 @@ #ifndef MLN_CORE_NEIGHB_HH # define MLN_CORE_NEIGHB_HH -/*! \file mln/core/neighb.hh - * - * \brief Definition of a window-to-neighborhood adapter. - * - * \todo Introduce properties so that we can deal properly with - * optional methods. - * - * \todo See if the impl of from_to is fine. What about removing the - * origin? etc. - */ +/// \file mln/core/neighb.hh +/// +/// Definition of a window-to-neighborhood adapter. +/// +/// +/// \todo See if the impl of from_to is fine. What about removing the +/// origin? etc. -# include <mln/core/concept/window.hh> # include <mln/core/internal/neighborhood_base.hh> # include <mln/core/internal/site_relative_iterator_base.hh> @@ -53,17 +49,15 @@ template <typename W> class neighb_bkd_niter; - /*! \brief Adapter class from window to neighborhood. - */ + + /// Adapter class from window to neighborhood. + template <typename W> - class neighb : public internal::neighborhood_base< mln_dpsite(W), neighb<W> >, + class neighb : public internal::neighborhood_base< W, neighb<W> >, private mlc_is_a(W, Window)::check_t { public: - /// Window associated type. - typedef W window; - /// Forward site iterator associated type. typedef neighb_fwd_niter<W> fwd_niter; @@ -87,27 +81,11 @@ void change_window(const W& new_win); - // Optional methods... - - /// Give the neighborhood size, i.e., the number of elements it - /// contains. - unsigned size() const; - - /// Give the maximum coordinate gap between the neighborhood - /// center and a neighboring point. - unsigned delta() const; - - /// Give the maximum coordinate gap between the neighborhood - /// center and a neighboring point. - const mln_dpsite(W)& dp(unsigned i) const; - - // end of Optional methods. - - /// \internal Hook to the window. W& hook_win_(); private: + W win_; }; @@ -238,40 +216,6 @@ template <typename W> inline - unsigned - neighb<W>::size() const - { - mlc_is(mln_trait_window_size(W), - trait::window::size::fixed)::check(); - return win_.size(); - } - - template <typename W> - inline - unsigned - neighb<W>::delta() const - { - mlc_is(mln_trait_window_support(W), - trait::window::support::regular)::check(); - mlc_is_not(mln_trait_window_definition(W), - trait::window::definition::varying)::check(); - return win_.delta(); - } - - template <typename W> - inline - const mln_dpsite(W)& - neighb<W>::dp(unsigned i) const - { - mlc_is(mln_trait_window_support(W), - trait::window::support::regular)::check(); - mlc_is(mln_trait_window_definition(W), - trait::window::definition::unique)::check(); - return win_.dp(i); - } - - template <typename W> - inline W& neighb<W>::hook_win_() { Index: mln/core/concept/neighborhood.hh --- mln/core/concept/neighborhood.hh (revision 2892) +++ mln/core/concept/neighborhood.hh (working copy) @@ -1,4 +1,5 @@ // Copyright (C) 2007, 2008 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 @@ -28,9 +29,9 @@ #ifndef MLN_CORE_CONCEPT_NEIGHBORHOOD_HH # define MLN_CORE_CONCEPT_NEIGHBORHOOD_HH -/*! \file mln/core/concept/neighborhood.hh - * \brief Definition of the concept of mln::Neighborhood. - */ +/// \file mln/core/concept/neighborhood.hh +/// +/// Definition of the concept of mln::Neighborhood. # include <mln/core/concept/object.hh> # include <mln/trait/windows.hh> @@ -42,7 +43,9 @@ // Fwd decl. template <typename E> struct Neighborhood; - // Neighborhood category flag type. + + /// Neighborhood category flag type. + template <> struct Neighborhood<void> { @@ -50,11 +53,11 @@ }; - /*! \brief Base class for implementation classes that are neighborhoods. - * - * \see mln::doc::Neighborhood for a complete documentation of this - * class contents. - */ + /// \brief Base class for implementation classes that are neighborhoods. + /// + /// \see mln::doc::Neighborhood for a complete documentation of this + /// class contents. + template <typename E> struct Neighborhood : public Object<E> { @@ -78,6 +81,9 @@ + template <typename L, typename R> + bool operator==(const Neighborhood<L>& lhs, const Neighborhood<R>& rhs); + template <typename N> std::ostream& @@ -108,6 +114,12 @@ } + template <typename L, typename R> + inline + bool operator==(const Neighborhood<L>& lhs, const Neighborhood<R>& rhs) + { + return exact(lhs).win() == exact(rhs).win(); + } template <typename N> inline Index: mln/metal/ands.hh --- mln/metal/ands.hh (revision 0) +++ mln/metal/ands.hh (revision 0) @@ -0,0 +1,69 @@ +// Copyright (C) 2008 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. + +#ifndef MLN_METAL_ANDS_HH +# define MLN_METAL_ANDS_HH + +/// \file mln/metal/ands.hh +/// +/// Definition of a multiple-"and"s Boolean expression. + +# include <mln/metal/bool.hh> + + +namespace mln +{ + + namespace metal + { + + /// Ands type. + template < typename E1, + typename E2, + typename E3, + typename E4 = true_, + typename E5 = true_, + typename E6 = true_, + typename E7 = true_, + typename E8 = true_ > + struct ands : bool_<( E1::value && + E2::value && + E3::value && + E4::value && + E5::value && + E6::value && + E7::value && + E8::value )> + {}; + + + } // end of namespace mln::metal + +} // end of namespace mln + + +#endif // ! MLN_METAL_ANDS_HH Index: mln/metal/all.hh --- mln/metal/all.hh (revision 2892) +++ mln/metal/all.hh (working copy) @@ -54,6 +54,7 @@ # include <mln/metal/none.hh> # include <mln/metal/abort.hh> +# include <mln/metal/ands.hh> # include <mln/metal/bexpr.hh> # include <mln/metal/bool.hh> # include <mln/metal/equal.hh> Index: mln/make/dual_neighb.hh --- mln/make/dual_neighb.hh (revision 2892) +++ mln/make/dual_neighb.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008 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 @@ -28,10 +28,9 @@ #ifndef MLN_MAKE_DUAL_NEIGHB_HH # define MLN_MAKE_DUAL_NEIGHB_HH -/*! \file mln/make/dual_neighb.hh - * - * \brief Routine to create a dual neighborhood. - */ +/// \file mln/make/dual_neighb.hh +/// +/// Routine to create a dual neighborhood. # include <mln/core/concept/image.hh> # include <mln/core/concept/neighborhood.hh> @@ -47,7 +46,7 @@ { template <typename I, typename N> - neighb< win::multiple_size< mln_window(N), pw::value_<I> > > + neighb< win::multiple_size< 2, mln_window(N), pw::value_<I> > > dual_neighb(const Image<I>& ima, const Neighborhood<N>& nbh_true, const Neighborhood<N>& nbh_false); @@ -59,7 +58,7 @@ template <typename I, typename N> inline - neighb< win::multiple_size< mln_window(N), pw::value_<I> > > + neighb< win::multiple_size< 2, mln_window(N), pw::value_<I> > > dual_neighb(const Image<I>& ima_, const Neighborhood<N>& nbh_true_, const Neighborhood<N>& nbh_false_) @@ -73,7 +72,7 @@ const N& nbh_false = exact(nbh_false_); mln_precondition(ima.has_data()); - typedef win::multiple_size< mln_window(N), pw::value_<I> > W; + typedef win::multiple_size< 2, mln_window(N), pw::value_<I> > W; W win(pw::value(ima)); win.set_window(false, nbh_false.win()); // 0 win.set_window(true, nbh_true .win()); // 1 Index: mln/win/multiple_size.hh --- mln/win/multiple_size.hh (revision 2892) +++ mln/win/multiple_size.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory +// Copyright (C) 2008 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 @@ -28,14 +28,16 @@ #ifndef MLN_WIN_MULTIPLE_SIZE_HH # define MLN_WIN_MULTIPLE_SIZE_HH -/*! \file mln/win/multiple_size.hh - * - * \brief Definition of a multiple-size window. - */ +/// \file mln/win/multiple_size.hh +/// +/// Definition of a multiple-size window. +/// +/// \todo Use n for tests and code!!! # include <mln/core/internal/window_base.hh> # include <mln/core/internal/site_relative_iterator_base.hh> # include <mln/util/array.hh> +# include <mln/metal/ands.hh> @@ -45,8 +47,8 @@ // Forward declarations. namespace win { - template <typename W, typename F> class multiple_size; - template <typename W, typename F> class multiple_size_qiter; + template <unsigned n, typename W, typename F> class multiple_size; + template <unsigned n, typename W, typename F> class multiple_size_qiter; } @@ -54,8 +56,8 @@ namespace trait { - template <typename W, typename F> - struct window_< win::multiple_size<W,F> > + template <unsigned n, typename W, typename F> + struct window_< win::multiple_size<n,W,F> > { typedef trait::window::size::unknown size; typedef trait::window::support::regular support; @@ -69,12 +71,13 @@ namespace win { - template <typename W, typename F> + template <unsigned n, typename W, typename F> class multiple_size - : public internal::window_base< mln_dpsite(W), multiple_size<W,F> >, + : public internal::window_base< mln_dpsite(W), multiple_size<n,W,F> >, - private metal::and_< mlc_is(mln_trait_window_size(W), + private metal::ands< mlc_bool(n > 1), + mlc_is(mln_trait_window_size(W), trait::window::size::fixed), mlc_is(mln_trait_window_support(W), trait::window::support::regular) >::check_t @@ -85,11 +88,11 @@ typedef mln_psite(W) psite; typedef mln_site(W) site; - typedef multiple_size< window<dpsite>, F > regular; + typedef multiple_size< n, window<dpsite>, F > regular; - typedef multiple_size_qiter<W,F> fwd_qiter; - typedef multiple_size_qiter<W,F> bkd_qiter; - typedef multiple_size_qiter<W,F> qiter; + typedef multiple_size_qiter<n,W,F> fwd_qiter; + typedef multiple_size_qiter<n,W,F> bkd_qiter; + typedef multiple_size_qiter<n,W,F> qiter; typedef W element; @@ -126,19 +129,19 @@ }; - template <typename W, typename F> + template <unsigned n, typename W, typename F> class multiple_size_qiter - : public internal::site_relative_iterator_base< multiple_size<W,F>, - multiple_size_qiter<W,F> > + : public internal::site_relative_iterator_base< multiple_size<n,W,F>, + multiple_size_qiter<n,W,F> > { - typedef multiple_size_qiter<W,F> self_; - typedef internal::site_relative_iterator_base< multiple_size<W,F>, self_ > super_; + typedef multiple_size_qiter<n,W,F> self_; + typedef internal::site_relative_iterator_base< multiple_size<n,W,F>, self_ > super_; public: multiple_size_qiter(); template <typename P> - multiple_size_qiter(const multiple_size<W,F>& w, const P& c); + multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c); /// Test the iterator validity. bool is_valid_() const; @@ -164,68 +167,68 @@ # ifndef MLN_INCLUDE_ONLY - // win::multiple_size<W,F> + // win::multiple_size<n,W,F> - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline - multiple_size<W,F>::multiple_size() + multiple_size<n,W,F>::multiple_size() : f_() { } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline - multiple_size<W,F>::multiple_size(const F& f) + multiple_size<n,W,F>::multiple_size(const F& f) : f_(f) { } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline bool - multiple_size<W,F>::is_empty() const + multiple_size<n,W,F>::is_empty() const { return win_.is_empty(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline void - multiple_size<W,F>::set_window(unsigned i, const W& win) + multiple_size<n,W,F>::set_window(unsigned i, const W& win) { mln_precondition(i == win_.nelements()); win_.append(win); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline const W& - multiple_size<W,F>::window_(unsigned i) const + multiple_size<n,W,F>::window_(unsigned i) const { mln_precondition(i < win_.nelements()); return win_[i]; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline unsigned - multiple_size<W,F>::nwindows() const + multiple_size<n,W,F>::nwindows() const { return win_.nelements(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline const F& - multiple_size<W,F>::function() const + multiple_size<n,W,F>::function() const { return f_; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline bool - multiple_size<W,F>::is_centered() const + multiple_size<n,W,F>::is_centered() const { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) @@ -234,10 +237,10 @@ return true; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline bool - multiple_size<W,F>::is_symmetric() const + multiple_size<n,W,F>::is_symmetric() const { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) @@ -246,20 +249,20 @@ return true; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline void - multiple_size<W,F>::sym() + multiple_size<n,W,F>::sym() { mln_precondition(win_.nelements() >= 1); for (unsigned i = 0; i < win_.nelements(); ++i) win_[i].sym(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline unsigned - multiple_size<W,F>::delta() const + multiple_size<n,W,F>::delta() const { mln_precondition(win_.nelements() >= 1); unsigned d = win_[0].delta(); @@ -272,20 +275,20 @@ return d; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline unsigned - multiple_size<W,F>::size_around(const mln_psite(W)& p) const + multiple_size<n,W,F>::size_around(const mln_psite(W)& p) const { mln_precondition(win_.nelements() >= 2); mln_precondition(f_(p) < win_.nelements()); return win_[f_(p)].size(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline const mln_dpsite(W)& - multiple_size<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const + multiple_size<n,W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const { mln_precondition(win_.nelements() >= 2); mln_precondition(f_(p) < win_.nelements()); @@ -294,18 +297,18 @@ } - // win::multiple_size_qiter<W,F> + // win::multiple_size_qiter<n,W,F> - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline - multiple_size_qiter<W,F>::multiple_size_qiter() + multiple_size_qiter<n,W,F>::multiple_size_qiter() { } - template <typename W, typename F> + template <unsigned n, typename W, typename F> template <typename P> inline - multiple_size_qiter<W,F>::multiple_size_qiter(const multiple_size<W,F>& w, const P& c) + multiple_size_qiter<n,W,F>::multiple_size_qiter(const multiple_size<n,W,F>& w, const P& c) { this->center_at(c); // We have to first change the center so that 'invalidate' can @@ -313,50 +316,50 @@ this->change_target(w); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline bool - multiple_size_qiter<W,F>::is_valid_() const + multiple_size_qiter<n,W,F>::is_valid_() const { return i_ < size_(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline void - multiple_size_qiter<W,F>::invalidate_() + multiple_size_qiter<n,W,F>::invalidate_() { i_ = size_(); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline void - multiple_size_qiter<W,F>::do_start_() + multiple_size_qiter<n,W,F>::do_start_() { i_ = 0; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline void - multiple_size_qiter<W,F>::do_next_() + multiple_size_qiter<n,W,F>::do_next_() { ++i_; } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline mln_psite(W) - multiple_size_qiter<W,F>::compute_p_() const + multiple_size_qiter<n,W,F>::compute_p_() const { return *this->c_ + this->s_->ith_dp_around(i_, *this->c_); } - template <typename W, typename F> + template <unsigned n, typename W, typename F> inline unsigned - multiple_size_qiter<W,F>::size_() const + multiple_size_qiter<n,W,F>::size_() const { return this->s_->size_around(*this->c_); }
participants (1)
-
Thierry Geraud