
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add the explicit 'inplace' mechanism. * oln/core/internal/op_image_plus_nbh.hh: Rename as... * oln/core/internal/op_image_extended_by_nbh.hh: ...this. * oln/core/gen/inplace.hh: New. * oln/debug/fill.hh, * oln/debug/iota.hh, * oln/level/paste.hh, * oln/level/apply_inplace.hh, * oln/core/gen/safe_image.hh: Update. * oln/core/gen/op.hh (plus): Rename as... (extended_by): ...this; less ambiguous. (oln_decl_inplace_image_op): New. * oln/core/internal/op_image_such_as_fp2b.hh: Fix temp hack; precisely, replace inheritance by delegation. * oln/core/internal/image_base.hh (oln_possible_lvalue): New. (possible_lvalue_from_): New. * oln/core/gen/neighb.hh, * oln/core/internal/image_ops.hh, * oln/core/internal/op_image_restricted_to_pset.hh, * oln/draw/bresenham.hh: Update. * TODO: Update. TODO | 6 - oln/core/gen/inplace.hh | 97 +++++++++++++++++++++++ oln/core/gen/neighb.hh | 4 oln/core/gen/op.hh | 21 ++++ oln/core/gen/safe_image.hh | 25 ++++- oln/core/internal/image_base.hh | 13 +++ oln/core/internal/image_ops.hh | 36 +++++++- oln/core/internal/op_image_extended_by_nbh.hh | 26 +++--- oln/core/internal/op_image_restricted_to_pset.hh | 5 - oln/core/internal/op_image_such_as_fp2b.hh | 37 +++++++- oln/debug/fill.hh | 18 +++- oln/debug/iota.hh | 16 +++ oln/draw/bresenham.hh | 23 ++++- oln/level/apply_inplace.hh | 49 +++++++---- oln/level/paste.hh | 10 ++ 15 files changed, 319 insertions(+), 67 deletions(-) Index: TODO --- TODO (revision 930) +++ TODO (working copy) @@ -26,19 +26,13 @@ draw routines -window types such as lines, rectangles, and so on - meta-window type; for instance, ball, segment, etc. -provide "- win" for morpho::opening and morpho::closing. - const promotions for op_<L,O,R> types + result is Mutable only if the underlying type is not 'const' in image_identity.hh use 'current' -provide arith::minus et al. with explicit output type - use Generalized_Point when possible Index: oln/debug/fill.hh --- oln/debug/fill.hh (revision 930) +++ oln/debug/fill.hh (working copy) @@ -29,6 +29,7 @@ # define OLN_DEBUG_FILL_HH # include <oln/core/concept/image.hh> +# include <oln/core/gen/inplace.hh> namespace oln @@ -38,17 +39,26 @@ { template <typename I, typename V> - void fill(Mutable_Image<I>& input, const V values[]); + void fill(Mutable_Image<I>& in_out, const V values[]); + + template <typename I, typename V> + void fill(inplace_<I> in_out, const V values[]); # ifndef OLN_INCLUDE_ONLY template <typename I> - void fill(Mutable_Image<I>& input, const oln_value(I)& value) + void fill(Mutable_Image<I>& in_out, const oln_value(I)& value) { - oln_piter(I) p(input.points()); + oln_piter(I) p(in_out.points()); for_all(p) - input(p) = value; + in_out(p) = value; + } + + template <typename I, typename V> + void fill(inplace_<I> in_out, const V values[]) + { + fill(in_out.unwrap(), values); } # endif // ! OLN_INCLUDE_ONLY Index: oln/debug/iota.hh --- oln/debug/iota.hh (revision 930) +++ oln/debug/iota.hh (working copy) @@ -29,6 +29,7 @@ # define OLN_DEBUG_IOTA_HH # include <oln/core/concept/image.hh> +# include <oln/core/gen/inplace.hh> namespace oln @@ -37,6 +38,14 @@ namespace debug { + template <typename I> + void iota(Mutable_Image<I>& in_out); + + template <typename I> + void iota(inplace_<I> in_out); + + +# ifndef OLN_INCLUDE_ONLY template <typename I> void iota(Mutable_Image<I>& in_out) @@ -47,6 +56,13 @@ in_out(p) = v++; } + template <typename I> + void iota(inplace_<I> in_out) + { + iota(in_out.unwrap()); + } + +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln::debug Index: oln/core/gen/neighb.hh --- oln/core/gen/neighb.hh (revision 930) +++ oln/core/gen/neighb.hh (working copy) @@ -31,7 +31,7 @@ # include <oln/core/internal/dpoints_impl.hh> # include <oln/core/internal/neighborhood_base.hh> -# include <oln/core/internal/op_image_plus_nbh.hh> +# include <oln/core/internal/op_image_extended_by_nbh.hh> namespace oln @@ -39,7 +39,7 @@ // Op. - oln_decl_op_plus(Image, Neighborhood); + oln_decl_op_extended_by(Image, Neighborhood); Index: oln/core/gen/inplace.hh --- oln/core/gen/inplace.hh (revision 0) +++ oln/core/gen/inplace.hh (revision 0) @@ -0,0 +1,97 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef OLN_CORE_GEN_INPLACE_HH +# define OLN_CORE_GEN_INPLACE_HH + +# include <oln/core/concept/image.hh> + + +namespace oln +{ + + + template <typename I> + class inplace_ : private mlc::assert_< mlc_is_a(I, Mutable_Image) > + { + typedef inplace_<I> current; + public: + + inplace_(I& ima); + + I& unwrap() const; // explicit + operator I() const; // implicit + + private: + I ima_; + }; + + + + template <typename I> + inplace_<I> + inplace(const Mutable_Image<I>& ima); + + + +# ifndef OLN_INCLUDE_ONLY + + template <typename I> + inplace_<I>::inplace_(I& ima) + : ima_(ima) + { + } + + template <typename I> + I& + inplace_<I>::unwrap() const + { + current* this_ = const_cast<current*>(this); + return this_->ima_; + } + + template <typename I> + inplace_<I>::operator I() const + { + return this->unwrap(); + } + + template <typename I> + inplace_<I> + inplace(const Mutable_Image<I>& ima) + { + I& ima_ = const_cast<I&>(exact(ima)); + inplace_<I> tmp(ima_); + return tmp; + } + +# endif // ! OLN_INCLUDE_ONLY + +} // end of namespace oln + + +#endif // ! OLN_CORE_GEN_INPLACE_HH Index: oln/core/gen/op.hh --- oln/core/gen/op.hh (revision 930) +++ oln/core/gen/op.hh (working copy) @@ -32,6 +32,7 @@ # include <oln/core/internal/category_of.hh> # include <oln/core/concept/function.hh> # include <oln/core/concept/value.hh> +# include <oln/core/gen/inplace.hh> @@ -74,7 +75,23 @@ struct e_n_d___w_i_t_h___a___s_e_m_i___c_o_l_u_m_n -# define oln_decl_op_plus(Lconcept, Rconcept) oln_decl_op_( plus, Lconcept, +, Rconcept) + +# define oln_decl_inplace_image_op(OpName, OpSym, Rconcept) \ + \ + template <typename L, typename R> \ + inplace_< op_<L, OpName, R> > \ + operator OpSym (inplace_<L> lhs, Rconcept<R>& rhs) \ + { \ + mlc::assert_< mlc_is_a(L, Mutable_Image) >::check(); \ + op_<L, OpName, R> tmp(exact(lhs), exact(rhs)); \ + return inplace(tmp); \ + } \ + \ + struct e_n_d___w_i_t_h___a___s_e_m_i___c_o_l_u_m_n + + + +# define oln_decl_op_extended_by(Lconcept, Rconcept) oln_decl_op_( extended_by, Lconcept, +, Rconcept) # define oln_decl_op_such_as(Lconcept, Rconcept) oln_decl_op_( such_as, Lconcept, |, Rconcept) # define oln_decl_op_restricted_to(Lconcept, Rconcept) oln_decl_op_( restricted_to, Lconcept, |, Rconcept) # define oln_decl_op_over(Lconcept, Rconcept) oln_decl_op_( over, Lconcept, /, Rconcept) @@ -89,7 +106,7 @@ /// \{ /// Operator Names. - struct plus; + struct extended_by; struct such_as; struct restricted_to; struct over; Index: oln/core/gen/safe_image.hh --- oln/core/gen/safe_image.hh (revision 930) +++ oln/core/gen/safe_image.hh (working copy) @@ -30,6 +30,7 @@ # include <oln/core/internal/image_base.hh> # include <oln/core/gen/infty_pset.hh> +# include <oln/core/gen/inplace.hh> namespace oln @@ -100,11 +101,10 @@ template <typename I> - safe_image<I> safe(Mutable_Image<I>& ima) - { - safe_image<I> tmp(ima); - return tmp; - } + safe_image<I> safe(Mutable_Image<I>& ima); + + template <typename I> + inplace_< safe_image<I> > safe(inplace_<I> ima); @@ -192,6 +192,21 @@ return this->data_->value; } + template <typename I> + safe_image<I> safe(Mutable_Image<I>& ima) + { + safe_image<I> tmp(ima); + return tmp; + } + + template <typename I> + inplace_< safe_image<I> > safe(inplace_<I> ima) + { + safe_image<I> tmp_ = safe(ima.unwrap()); + inplace_< safe_image<I> > tmp(tmp_); + return tmp; + } + # endif // ! OLN_INCLUDE_ONLY } // end of namespace oln Index: oln/core/internal/op_image_such_as_fp2b.hh --- oln/core/internal/op_image_such_as_fp2b.hh (revision 930) +++ oln/core/internal/op_image_such_as_fp2b.hh (working copy) @@ -48,8 +48,7 @@ template <typename I, typename F> struct super_trait_< internal::current > { - typedef op_< const oln_pset(I), such_as, F > S; - typedef internal::special_op_< stc::is<Image>, I, restricted_to, stc::is<Point_Set>, const S > ret; + typedef internal::image_extension_< op_<I, such_as, F> > ret; }; @@ -61,6 +60,15 @@ template <typename I, typename F> struct vtypes< internal::current > { + typedef op_< const oln_pset(I), such_as, F > S__; + typedef op_< I, restricted_to, const S__ > delegatee; + + typedef internal::singleton<delegatee> data; + + typedef oln_point(I) point; + typedef oln_possible_lvalue(I) lvalue; + typedef op_<oln_plain(I), such_as, F> plain; + typedef op_<pl::rec<I>, such_as, F> skeleton; }; @@ -74,8 +82,11 @@ { public: - stc_using(point); - stc_using(box); + stc_using(delegatee); + stc_using(data); + + delegatee& impl_image(); + const delegatee& impl_image() const; protected: special_op_(); @@ -92,8 +103,24 @@ template <typename I, typename F> current::special_op_(I& ima, F& f) - : super(ima, (ima.points() | f)) { + this->data_ = new data( ima | (ima.points() | f) ); + } + + template <typename I, typename F> + typename current::delegatee& + current::impl_image() + { + assert(this->has_data()); + return this->data_->value; + } + + template <typename I, typename F> + const typename current::delegatee& + current::impl_image() const + { + assert(this->has_data()); + return this->data_->value; } # endif // ! OLN_INCLUDE_ONLY Index: oln/core/internal/image_ops.hh --- oln/core/internal/image_ops.hh (revision 930) +++ oln/core/internal/image_ops.hh (working copy) @@ -32,21 +32,25 @@ # include <oln/core/internal/op_image_restricted_to_pset.hh> # include <oln/core/internal/op_image_such_as_fp2b.hh> # include <oln/core/internal/op_fp2v_over_pset.hh> +# include <oln/core/gen/literal.hh> namespace oln { + // FIXME: when L is Image the "non-const" version should feature Mutable_Image + // Image | Point_Set ( ima restricted_to pset ) oln_decl_op_restricted_to(Image, Point_Set); - + oln_decl_inplace_image_op(restricted_to, |, Point_Set); // Image | Function_p2b ( ima such_as "f : p -> b" // is ima restricted_to (ima.points such_as f) ) oln_decl_op_such_as(Image, Function_p2b); + oln_decl_inplace_image_op(such_as, |, Function_p2b); @@ -70,7 +74,16 @@ return tmp; } - // FIXME: Add "literal / point set"... + // Specialisation "literal T over Point_Set". + + template <typename V, typename S> + op_<const lit_p2v_<oln_point(S), V>, over, const S> + operator / (const literal_<V>& value, const Point_Set<S>& pts) + { + lit_p2v_<oln_point(S), V> lit(value); + op_<const lit_p2v_<oln_point(S), V>, over, const S> tmp(lit, exact(pts)); + return tmp; + } @@ -89,7 +102,7 @@ template <typename I, typename B, typename P> op_<I, such_as, const fun_p2b_<B (*)(P)> > - operator | (Image<I>& ima, B (*f)(P)) + operator | (Mutable_Image<I>& ima, B (*f)(P)) { typedef oln_strip_(P) P_; mlc::assert_< mlc_is_a(P_, Point) >::check(); // FIXME: Add err msg. @@ -98,6 +111,13 @@ return tmp; } + template <typename I, typename B, typename P> + inplace_< op_<I, such_as, const fun_p2b_<B (*)(P)> > > + operator | (inplace_<I> ima, B (*f)(P)) + { + return inplace(ima.unwrap() | f); + } + // Specialization "Image such_as ima : P -> B". @@ -113,7 +133,7 @@ template <typename I, typename J> op_<I, such_as, const fun_p2b_< Binary_Image<J> > > - operator | (Image<I>& ima, const Binary_Image<J>& f_ima_b) + operator | (Mutable_Image<I>& ima, const Binary_Image<J>& f_ima_b) { precondition(f_ima_b.points() >= ima.points()); mlc::assert_equal_< oln_point(I), oln_point(J) >::check(); @@ -121,8 +141,12 @@ return tmp; } - - // FIXME: What about Mutable_Image so that "ima | something" can be left-value? + template <typename I, typename J> + inplace_< op_<I, such_as, const fun_p2b_< Binary_Image<J> > > > + operator | (inplace_<I> ima, const Binary_Image<J>& f_ima_b) + { + return inplace(ima.unwrap() | f_ima_b); + } } // end of namespace oln Index: oln/core/internal/op_image_restricted_to_pset.hh --- oln/core/internal/op_image_restricted_to_pset.hh (revision 930) +++ oln/core/internal/op_image_restricted_to_pset.hh (working copy) @@ -52,12 +52,11 @@ template <typename I, typename S> struct vtypes< internal::current > { - typedef op_<I, restricted_to, S> Exact; - typedef stc_type(I, point) point__; - typedef I delegatee; typedef internal::pair<I,S> data; + typedef oln_possible_lvalue(I) lvalue; + typedef S pset; typedef op_<oln_plain(I), restricted_to, S> plain; Index: oln/core/internal/image_base.hh --- oln/core/internal/image_base.hh (revision 930) +++ oln/core/internal/image_base.hh (working copy) @@ -36,6 +36,10 @@ # include <oln/core/gen/box.hh> +# define oln_possible_lvalue(I) \ + typename internal::possible_lvalue_from_< I >::ret + + namespace oln { @@ -266,6 +270,15 @@ }; + template <typename I> + struct possible_lvalue_from_ + { + typedef typename mlc::if_< mlc_is_const(I), + stc::not_delegated, + stc_find_type(I, lvalue) >::ret ret; + }; + + /// single_image_morpher_<Exact> template <typename Exact> Index: oln/core/internal/op_image_extended_by_nbh.hh --- oln/core/internal/op_image_extended_by_nbh.hh (revision 929) +++ oln/core/internal/op_image_extended_by_nbh.hh (working copy) @@ -25,8 +25,8 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef OLN_CORE_INTERNAL_OP_IMAGE_PLUS_NBH_HH -# define OLN_CORE_INTERNAL_OP_IMAGE_PLUS_NBH_HH +#ifndef OLN_CORE_INTERNAL_OP_IMAGE_EXTENDED_BY_NBH_HH +# define OLN_CORE_INTERNAL_OP_IMAGE_EXTENDED_BY_NBH_HH # include <oln/core/concept/neighborhood.hh> # include <oln/core/internal/image_base.hh> @@ -39,7 +39,7 @@ { # define current \ - special_op_< stc::is<Image>, I, plus, stc::is<Neighborhood>, N > + special_op_< stc::is<Image>, I, extended_by, stc::is<Neighborhood>, N > // Instant value. oln_decl_instant_value(nbh); @@ -54,7 +54,7 @@ template <typename I, typename N> struct super_trait_< internal::current > { - typedef internal::image_extension_< op_<I, plus, N> > ret; + typedef internal::image_extension_< op_<I, extended_by, N> > ret; }; @@ -62,19 +62,21 @@ template <typename I, typename N> struct vtypes< internal::current > { - typedef op_<I, plus, N> Exact; + typedef op_<I, extended_by, N> Exact; typedef I delegatee; typedef internal::pair<I,N> data; typedef N nbh; + typedef oln_possible_lvalue(I) lvalue; + // FIXME: Wrong! typedef niter_has_< dpoints_fwd_piter_<oln_point(I)>, oln_pset(I) > fwd_niter; typedef niter_has_< dpoints_bkd_piter_<oln_point(I)>, oln_pset(I) > bkd_niter; - typedef op_<oln_plain(I), plus, N> plain; - typedef op_<pl::rec<I>, plus, N> skeleton; + typedef op_<oln_plain(I), extended_by, N> plain; + typedef op_<pl::rec<I>, extended_by, N> skeleton; }; @@ -86,10 +88,10 @@ template <typename I, typename N> class current : - public internal::image_extension_< op_<I, plus, N> >, + public internal::image_extension_< op_<I, extended_by, N> >, private mlc::assert_< mlc_is_not_a(I, Image_with_Nbh) > // FIXME: Add err msg. { - typedef internal::image_extension_< op_<I, plus, N> > super; + typedef internal::image_extension_< op_<I, extended_by, N> > super; public: stc_using(nbh); stc_using(data); @@ -202,7 +204,7 @@ bool init_(internal::current* this_, const D& dat) { precondition(not this_->has_data()); - this_->data__() = new typename op_<I, plus, N>::data; + this_->data__() = new typename op_<I, extended_by, N>::data; bool ima_ok = init(this_->data__()->first, with, dat); bool nbh_ok = init(this_->data__()->second, with, dat); postcondition(ima_ok); @@ -216,7 +218,7 @@ bool prepare(internal::current& target, with_t, const D& dat) { precondition(not target.has_data()); - target.data__() = new typename op_<I, plus, N>::data; + target.data__() = new typename op_<I, extended_by, N>::data; bool ima_ok = prepare(target.data__()->first, with, dat); bool nbh_ok = init(target.data__()->second, with, dat); postcondition(ima_ok); @@ -231,4 +233,4 @@ } // end of namespace oln -#endif // ! OLN_CORE_INTERNAL_OP_IMAGE_PLUS_NBH_HH +#endif // ! OLN_CORE_INTERNAL_OP_IMAGE_EXTENDED_BY_NBH_HH Index: oln/draw/bresenham.hh --- oln/draw/bresenham.hh (revision 930) +++ oln/draw/bresenham.hh (working copy) @@ -29,8 +29,8 @@ # define OLN_DRAW_BRESENHAM_HH # include <oln/core/concept/image.hh> +# include <oln/core/gen/inplace.hh> # include <oln/core/2d/line2d.hh> -# include <oln/core/gen/single_value_image.hh> # include <oln/level/paste.hh> @@ -48,6 +48,11 @@ const oln_point(I)& begin, const oln_point(I)& end, const oln_value(I)& value); + template <typename I> + void bresenham(inplace_<I> in_out, + const oln_point(I)& begin, const oln_point(I)& end, + const oln_value(I)& value); + # ifndef OLN_INCLUDE_ONLY @@ -59,15 +64,13 @@ const oln_point(I)& begin, const oln_point(I)& end, const oln_value(I)& value) { - line2d line(begin, end); - single_value_image<line2d, oln_value(I)> line_image(line, value); - level::paste(line_image, in_out); - // FIXME: Make it as simple as level::paste(line2d(begin, end) + value, in_out); + level::paste(literal(value) / line2d(begin, end), in_out); } } // end of namespace oln::draw::impl - // Facade. + + // Facades. template <typename I> void bresenham(Mutable_Image<I>& in_out, @@ -77,6 +80,14 @@ impl::bresenham_(exact(in_out), begin, end, value); } + template <typename I> + void bresenham(inplace_<I> in_out, + const oln_point(I)& begin, const oln_point(I)& end, + const oln_value(I)& value) + { + bresenham(in_out.unwrap(), begin, end, value); + } + # endif // ! OLN_INCLUDE_ONLY } // end of namespace oln::draw Index: oln/level/paste.hh --- oln/level/paste.hh (revision 930) +++ oln/level/paste.hh (working copy) @@ -29,6 +29,7 @@ # define OLN_LEVEL_PASTE_HH # include <oln/core/concept/image.hh> +# include <oln/core/gen/inplace.hh> namespace oln @@ -42,6 +43,9 @@ template <typename I, typename J> void paste(const Image<I>& data, /* in */ Mutable_Image<J>& destination); + template <typename I, typename J> + void paste(const Image<I>& data, /* in */ inplace_<J> destination); + # ifndef OLN_INCLUDE_ONLY @@ -73,6 +77,12 @@ impl::paste_(exact(data), exact(destination)); } + template <typename I, typename J> + void paste(const Image<I>& data, /* in */ inplace_<J> destination) + { + paste(data, destination.unwrap()); + } + # endif // ! OLN_INCLUDE_ONLY } // end of namespace oln::level Index: oln/level/apply_inplace.hh --- oln/level/apply_inplace.hh (revision 930) +++ oln/level/apply_inplace.hh (working copy) @@ -30,6 +30,7 @@ # include <oln/core/concept/image.hh> # include <oln/core/gen/fun.hh> +# include <oln/core/gen/inplace.hh> namespace oln @@ -41,12 +42,19 @@ /// Fwd decls. template <typename F, typename I> - void - apply_inplace(const Function_v2v<F>& f, Mutable_Image<I>& input); + void apply_inplace(const Function_v2v<F>& f, Mutable_Image<I>& in_out); template <typename R, typename A, typename I> - void - apply_inplace(R (*f)(A), Mutable_Image<I>& input); + void apply_inplace(R (*f)(A), Mutable_Image<I>& in_out); + + + // for images created on the fly + + template <typename F, typename I> + void apply_inplace(const Function_v2v<F>& f, inplace_<I> in_out); + + template <typename R, typename A, typename I> + void apply_inplace(R (*f)(A), inplace_<I> in_out); # ifndef OLN_INCLUDE_ONLY @@ -57,13 +65,12 @@ // Generic version. template <typename F, typename I> - void - apply_inplace_(const F& f, Mutable_Image<I>& input) + void apply_inplace_(const F& f, Mutable_Image<I>& in_out) { - oln_piter(I) p(input.points()); + oln_piter(I) p(in_out.points()); for_all(p) - input(p) = f(input(p)); - // FIXME: input(p) = static_cast<oln_value(I)>( f_( static_cast<oln_argument(F)>(input(p)) ) ); + in_out(p) = f(in_out(p)); + // FIXME: in_out(p) = static_cast<oln_value(I)>( f_( static_cast<oln_argument(F)>(in_out(p)) ) ); } @@ -73,20 +80,30 @@ /// Facades. template <typename F, typename I> - void - apply_inplace(const Function_v2v<F>& f, Mutable_Image<I>& input) + void apply_inplace(const Function_v2v<F>& f, Mutable_Image<I>& in_out) + { + impl::apply_inplace_(exact(f), exact(in_out)); + } + + template <typename R, typename A, typename I> + void apply_inplace(R (*f)(A), Mutable_Image<I>& in_out) + { + impl::apply_inplace_(functorize_v2v(f), exact(in_out)); + } + + template <typename F, typename I> + void apply_inplace(const Function_v2v<F>& f, inplace_<I> in_out) { - impl::apply_inplace_(exact(f), exact(input)); + apply_inplace(f, in_out.unwrap()); } template <typename R, typename A, typename I> - void - apply_inplace(R (*f)(A), Mutable_Image<I>& input) + void apply_inplace(R (*f)(A), inplace_<I> in_out) { - impl::apply_inplace_(functorize_v2v(f), exact(input)); + apply_inplace(f, in_out.unwrap()); } -# endif +# endif // ! OLN_INCLUDE_ONLY } // end of namespace oln::level