701: Introduce lut_value_proxy and remove mutable_fwd_viter_lut.

https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Introduce oln::value::lut_value_proxy. * olena/oln/value/lut_value_proxy.hh: New. * oln/core/typedefs.hh (mutable_fwd_viter_type): Remove virtual type declaration. (value_proxy_type, mutable_value_proxy_type): New virtual types declarations. Aesthetic changes. * oln/core/abstract/image/value_wise_accessibility/hierarchy.hh (image_being_value_wise_random_accessible::fwd_viter_t): Remove typedef. (image_being_value_wise_random_accessible::value_proxy_t): New typedef. (image_being_value_wise_random_accessible::value): Return a value proxy instead of a value iterator. (mutable_image_being_value_wise_random_accessible::fwd_viter_t): Remove typedef. (mutable_image_being_value_wise_random_accessible::value_proxy_t): New typedef. (mutable_image_being_value_wise_random_accessible::value)): Return a value proxy instead of a value iterator. * oln/morpher/with_lut.hh (oln/value/lut_value_proxy.hh): Include it. (vtypes< morpher::with_lut<Image, Lut> >::value_proxy_type) (vtypes< morpher::with_lut<Image, Lut> >::mutable_value_proxy_type): New typedefs. (single_vtype<morpher::with_lut<Image, Lut>, typedef_::mutable_fwd_viter_type>): Remove single virtual type. (oln::morpher::with_lut::fwd_viter_type) (oln::morpher::with_lut::mutable_fwd_viter_type): Remove. (oln::morpher::with_lut::value_proxy_type) (oln::morpher::with_lut::mutable_value_proxy_type): New typedefs. (oln::morpher::with_lut::impl_value): Have these methods return value proxies instead of value iterators. * oln/Makefile.am (nobase_oln_HEADERS): Add value/lut_value_proxy.hh. Remove oln::mutable_fwd_viter_lut and clean up oln::fwd_viter_lut. * olena/oln/core/abstract/iterator_on_values.hh: New. * oln/core/internal/fwd_viter_lut.hh: (oln::internal::fwd_viter_lut<Exact>): Inherit from oln::abstract::iterator_on_values<Exact>. s/rvalue_type/value_type/g. (oln::internal::fwd_viter_lut(lut_type&, const value_type&)): Remove ctor. (oln::internal::fwd_viter_lut::start) (oln::internal::fwd_viter_lut::next) (oln::internal::fwd_viter_lut::invalidate) (oln::internal::fwd_viter_lut::is_valid): Rename methods as... (oln::internal::fwd_viter_lut::impl_start) (oln::internal::fwd_viter_lut::impl_next) (oln::internal::fwd_viter_lut::impl_invalidate) (oln::internal::fwd_viter_lut::impl_is_valid): ...these. * oln/core/gen/fwd_viter_lut.hh (oln::fwd_viter_lut<Lut>): s/rvalue_type/value_type/g. (oln::fwd_viter_lut::fwd_viter_lut(const Lut&, const rvalue_type&)): Remove ctor. (oln::fwd_viter_lut::operator rvalue_type): Turn this operator into... (oln::fwd_viter_lut::impl_to_value): ...this method. (oln::mutable_fwd_viter_lut): Remove this class and it virtual types. (operator<<(std::ostream&, const mutable_fwd_viter_lut<Lut>&)): Remove. * oln/Makefile.am (nobase_oln_HEADERS): Add core/abstract/iterator_on_values.hh Makefile.am | 2 core/abstract/image/value_wise_accessibility/hierarchy.hh | 22 - core/abstract/iterator_on_values.hh | 134 ++++++ core/gen/fwd_viter_lut.hh | 184 -------- core/internal/fwd_viter_lut.hh | 42 -- core/typedefs.hh | 40 + morpher/with_lut.hh | 35 - value/lut_value_proxy.hh | 289 ++++++++++++++ 8 files changed, 499 insertions(+), 249 deletions(-) Index: oln/core/typedefs.hh --- oln/core/typedefs.hh (revision 700) +++ oln/core/typedefs.hh (working copy) @@ -97,23 +97,21 @@ mlc_decl_typedef(bkd_niter_type); mlc_decl_typedef(fwd_viter_type); - mlc_decl_typedef(mutable_fwd_viter_type); // FIXME: bkd_viter_type. - // FIXME: mutable_bkd_viter_type. - /*----------------------. - | category::point_set. | - `-----------------------*/ + /*------------. + | Point set. | + `------------*/ mlc_decl_typedef(has_known_size_type); mlc_decl_typedef(is_random_accessible_type); mlc_decl_typedef(is_connected_type); - /*------------------. - | category::image. | - `------------------*/ + /*--------. + | Image. | + `--------*/ mlc_decl_typedef(is_computed_type); mlc_decl_typedef(value_type); @@ -134,26 +132,34 @@ mlc_decl_typedef(is_value_wise_mutable_type); - /*-----------------. - | category::grid. | - `-----------------*/ + /*-------. + | Grid. | + `-------*/ // FIXME: Merge with dim_type? mlc_decl_typedef(dimvalue_type); mlc_decl_typedef(coord_type); - /*-----------------. - | category::point. | - `-----------------*/ + /*--------. + | Point. | + `--------*/ mlc_decl_typedef(dim_type); mlc_decl_typedef(vec_type); - /*-------------------------. - | category::lookup_table. | - `-------------------------*/ + /*---------. + | Values. | + `---------*/ + + mlc_decl_typedef(value_proxy_type); + mlc_decl_typedef(mutable_value_proxy_type); + + + /*----------------. + | Look-up table. | + `----------------*/ mlc_decl_typedef(lut_type); mlc_decl_typedef(lut_iter_type); Index: oln/core/abstract/image/value_wise_accessibility/hierarchy.hh --- oln/core/abstract/image/value_wise_accessibility/hierarchy.hh (revision 700) +++ oln/core/abstract/image/value_wise_accessibility/hierarchy.hh (working copy) @@ -53,18 +53,22 @@ public automatic::get_impl< image_being_value_wise_random_accessible, E > { typedef oln_type_of(E, value) value_t; - typedef oln_type_of(E, fwd_viter) fwd_viter_t; - + typedef oln_type_of(E, value_proxy) value_proxy_t; public: - // Value descriptor (read-only access). - fwd_viter_t value(const value_t& v) const; + /// Get a (read-only) value descriptor from a value. + /// + /// This method is not really useful, but we keep it for the + /// symmetry with + /// mutable_image_being_value_wise_random_accessible::value(). + value_proxy_t value(const value_t& v) const; protected: /// Constructor (protected, empty). image_being_value_wise_random_accessible(); }; + /// Mutable image having a value-wise random accessibility. template <typename E> struct mutable_image_being_value_wise_random_accessible : @@ -72,12 +76,12 @@ public automatic::get_impl< mutable_image_being_value_wise_random_accessible, E > { typedef oln_type_of(E, value) value_t; - typedef oln_type_of(E, mutable_fwd_viter) mutable_fwd_viter_t; + typedef oln_type_of(E, mutable_value_proxy) mutable_value_proxy_t; public: using image_being_value_wise_random_accessible<E>::value; - // Value descriptor (read-write access). - mutable_fwd_viter_t value(const value_t& v); + /// Get a (read-only) value descriptor from a value. + mutable_value_proxy_t value(const value_t& v); protected: /// Constructor (protected, empty). @@ -91,7 +95,7 @@ // image_being_value_wise_random_accessible. template <typename E> - typename image_being_value_wise_random_accessible<E>::fwd_viter_t + typename image_being_value_wise_random_accessible<E>::value_proxy_t image_being_value_wise_random_accessible<E>::value(const typename image_being_value_wise_random_accessible<E>::value_t& v) const { return this->exact().impl_value(v); @@ -106,7 +110,7 @@ // mutable_image_being_value_wise_random_accessible. template <typename E> - typename mutable_image_being_value_wise_random_accessible<E>::mutable_fwd_viter_t + typename mutable_image_being_value_wise_random_accessible<E>::mutable_value_proxy_t mutable_image_being_value_wise_random_accessible<E>::value(const typename mutable_image_being_value_wise_random_accessible<E>::value_t& v) { return this->exact().impl_value(v); Index: oln/core/abstract/iterator_on_values.hh --- oln/core/abstract/iterator_on_values.hh (revision 0) +++ oln/core/abstract/iterator_on_values.hh (revision 0) @@ -0,0 +1,134 @@ +// Copyright (C) 2001, 2003, 2004, 2005, 2006 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_ABSTRACT_ITERATOR_ON_VALUES_HH +# define OLN_CORE_ABSTRACT_ITERATOR_ON_VALUES_HH + +# include <oln/core/abstract/iterator.hh> + + +namespace oln +{ + + + // Forward declaration. + namespace abstract { template <typename E> class iterator_on_values; } + + + // Super type declaration. + template <typename E> + struct set_super_type< abstract::iterator_on_values<E> > + { + typedef abstract::iterator<E> ret; + }; + + + /// Virtual types associated to abstract::iterator_on_values<E>. + template <typename E> + struct vtypes< abstract::iterator_on_values<E> > + { + typedef mlc::undefined value_type; + }; + + + namespace abstract + { + + /// Abstract value iterator class. + template <typename E> + class iterator_on_values : public abstract::iterator<E> + { + public: + typedef oln_type_of(E, value) value_type; + + value_type to_value() const; + + // Concrete method. + operator value_type() const; + + protected: + + iterator_on_values(); + + ~iterator_on_values(); + + }; // end of class oln::abstract::iterator_on_values<E> + + + template <typename E> + std::ostream& operator<<(std::ostream& ostr, + const iterator_on_values<E>& vit); + + +# ifndef OLN_INCLUDE_ONLY + + template <typename E> + typename iterator_on_values<E>::value_type + iterator_on_values<E>::to_value() const + { + precondition(this->is_valid()); + return this->exact().impl_to_value(); + } + + template <typename E> + // Concrete method. + iterator_on_values<E>::operator typename iterator_on_values<E>::value_type() const + { + precondition(this->is_valid()); + return this->to_value(); + } + + template <typename E> + iterator_on_values<E>::iterator_on_values() + { + } + + template <typename E> + iterator_on_values<E>::~iterator_on_values() + { + mlc::assert_defined_< typename iterator_on_values<E>::value_type >::check(); + } + + + template <typename E> + std::ostream& operator<<(std::ostream& ostr, + const iterator_on_values<E>& vit) + { + return ostr << vit.to_value(); + } + + +# endif + + } // end of namespace oln::abstract + + +} // end of namespace oln + + +#endif // ! OLN_CORE_ABSTRACT_ITERATOR_ON_VALUES_HH Index: oln/core/gen/fwd_viter_lut.hh --- oln/core/gen/fwd_viter_lut.hh (revision 700) +++ oln/core/gen/fwd_viter_lut.hh (working copy) @@ -34,9 +34,7 @@ namespace oln { - /*------------. - | fwd_viter. | - `------------*/ + // FIXME: Merge this file with oln/core/internal/fwd_viter_lut.hh? // Forward declaration. template <typename Lut> class fwd_viter_lut; @@ -58,7 +56,7 @@ // The look-up table is immutable. typedef const Lut lut_type; typedef typename Lut::const_iterator lut_iter_type; - typedef typename Lut::new_value_type rvalue_type; + typedef typename Lut::new_value_type value_type; }; @@ -74,16 +72,14 @@ public: typedef oln_type_of(self_t, lut) lut_t; - typedef oln_type_of(self_t, rvalue) rvalue_type; + typedef oln_type_of(self_t, value) value_type; public: // Construct an uninitialized value iterator. fwd_viter_lut(const Lut& lut); - // Construct an iterator pointing to value \a val. - fwd_viter_lut(const Lut& lut, const rvalue_type& val); // Get the value pointed by this iterator (const version). - operator rvalue_type() const; + value_type impl_to_value() const; void print(std::ostream& ostr) const; }; @@ -106,15 +102,8 @@ } template <typename Lut> - fwd_viter_lut<Lut>::fwd_viter_lut(const Lut& lut, - const typename fwd_viter_lut<Lut>::rvalue_type& val) - : super_t(lut, val) - { - // The underlying iterator is initialized by the super class. - } - - template <typename Lut> - fwd_viter_lut<Lut>::operator typename fwd_viter_lut<Lut>::rvalue_type() const + typename fwd_viter_lut<Lut>::value_type + fwd_viter_lut<Lut>::impl_to_value() const { precondition(this->is_valid()); return this->i_->first; @@ -124,7 +113,7 @@ void fwd_viter_lut<Lut>::print(std::ostream& ostr) const { precondition(this->is_valid()); - ostr << "fwd_viter_lut<Lut> { value = " << this->i_->first << " }"; + ostr << "{ value = " << this->i_->first << " }"; } @@ -138,165 +127,6 @@ # endif - - - /*--------------------. - | mutable_fwd_viter. | - `--------------------*/ - - // Forward declaration. - template <typename Lut> class mutable_fwd_viter_lut; - - - /// Super type declaration. - template <typename Lut> - struct set_super_type< mutable_fwd_viter_lut<Lut> > - { - typedef mutable_fwd_viter_lut<Lut> self_t; - typedef internal::fwd_viter_lut<self_t> ret; - }; - - - /// Virtual types associated to oln::mutable_fwd_viter_lut<Lut>. - template <typename Lut> - struct vtypes< mutable_fwd_viter_lut<Lut> > - { - typedef Lut lut_type; - typedef typename Lut::iterator lut_iter_type; - typedef typename Lut::new_value_type rvalue_type; - typedef typename Lut::new_value_type& lvalue_type; - }; - - - /// Const forward value iterator on look-up table. - template <typename Lut> - class mutable_fwd_viter_lut : - public stc_get_supers(mutable_fwd_viter_lut<Lut>) - // Check that Lut is a look-up table. - // FIXME: an abstract::lookup_table would be useful. - { - typedef mutable_fwd_viter_lut<Lut> self_t; - typedef stc_get_super(self_t) super_t; - typedef oln_type_of(self_t, lut_iter) lut_iter_t; - typedef typename Lut::orig_value_type orig_value_t; - typedef typename Lut::new_value_type new_value_t; - - public: - typedef Lut lut_t; - typedef oln_type_of(self_t, rvalue) rvalue_type; - typedef oln_type_of(self_t, lvalue) lvalue_type; - - self_t& operator=(const rvalue_type& rhs); - - public: - // Construct an uninitialized value iterator. - mutable_fwd_viter_lut(Lut& lut); - // Construct an iterator pointing to value \a val. - mutable_fwd_viter_lut(Lut& lut, const rvalue_type& val); - - // Get the value pointed by this iterator (const version). - operator rvalue_type() const; - // Get the value pointed by this iterator (mutable version). - operator lvalue_type(); - - void print(std::ostream& ostr) const; - }; - - - template <typename Lut> - std::ostream& operator<<(std::ostream& ostr, - const mutable_fwd_viter_lut<Lut>& t); - - - -# ifndef OLN_INCLUDE_ONLY - - template <typename Lut> - mutable_fwd_viter_lut<Lut>::mutable_fwd_viter_lut(Lut& lut) - : super_t(lut) - { - // Initialize underlying iterator (i.e., \a i_.) - this->invalidate(); - } - - template <typename Lut> - mutable_fwd_viter_lut<Lut>::mutable_fwd_viter_lut(Lut& lut, - const typename mutable_fwd_viter_lut<Lut>::rvalue_type& val) - : super_t(lut, val) - { - // The underlying iterator is initialized by the super class. - } - - template <typename Lut> - mutable_fwd_viter_lut<Lut>::operator typename mutable_fwd_viter_lut<Lut>::rvalue_type() const - { - precondition(this->is_valid()); - return this->i_->second; - } - - template <typename Lut> - mutable_fwd_viter_lut<Lut>::operator typename mutable_fwd_viter_lut<Lut>::lvalue_type() - { - precondition(this->is_valid()); - return this->i_->first; - } - - template <typename Lut> - mutable_fwd_viter_lut<Lut>& - mutable_fwd_viter_lut<Lut>::operator=(const typename mutable_fwd_viter_lut<Lut>::rvalue_type& rhs) - { - precondition(this->is_valid()); - - // Current ``new'' value. - new_value_t cur_new_val = this->i_->first; - - // Shortcuts. - typedef lut_iter_t new_iter_t; - typedef std::pair<new_iter_t, new_iter_t> new_iter_range_t; - - // Current ``original'' value(s) associated to the next ``new'' value RHS. - new_iter_range_t cur_orig_val_range = - this->lut_.new_to_orig_map().equal_range(cur_new_val); - // A temporary map where additional bindings will be stored. - typename Lut::new_to_orig_map_type additional_bindings; - - for (new_iter_t j = cur_orig_val_range.first; - j != cur_orig_val_range.second; ++j) - { - // Update the orig-to-new map (substitution). - orig_value_t orig_val = j->second; - this->lut_.orig_to_new_map()[orig_val] = rhs; - // Populate the temp map. - additional_bindings.insert(std::make_pair(rhs, orig_val)); - } - // Update the new-to-orig map (deletion). - this->lut_.new_to_orig_map().erase(cur_orig_val_range.first, - cur_orig_val_range.second); - // Update the new-to-orig map (insertion). - this->lut_.new_to_orig_map().insert(additional_bindings.begin(), - additional_bindings.end()); - return *this; - } - - template <typename Lut> - void mutable_fwd_viter_lut<Lut>::print(std::ostream& ostr) const - { - precondition(this->is_valid()); - ostr - << "mutable_fwd_viter_lut<Lut> { value = " << this->i_->first << " }"; - } - - - template <typename Lut> - std::ostream& operator<<(std::ostream& ostr, - const mutable_fwd_viter_lut<Lut>& t) - { - t.print(ostr); - return ostr; - } - -# endif - } // end of namespace oln Index: oln/core/internal/fwd_viter_lut.hh --- oln/core/internal/fwd_viter_lut.hh (revision 700) +++ oln/core/internal/fwd_viter_lut.hh (working copy) @@ -28,7 +28,7 @@ #ifndef OLN_CORE_INTERNAL_FWD_VITER_LUT_HH # define OLN_CORE_INTERNAL_FWD_VITER_LUT_HH -# include <oln/core/abstract/iterator.hh> +# include <oln/core/abstract/iterator_on_values.hh> namespace oln @@ -46,8 +46,7 @@ template <typename Exact> struct set_super_type< internal::fwd_viter_lut<Exact> > { - typedef internal::fwd_viter_lut<Exact> self_t; - typedef abstract::iterator<self_t> ret; + typedef abstract::iterator_on_values<Exact> ret; }; @@ -66,22 +65,23 @@ public: typedef oln_type_of(Exact, lut) lut_type; - typedef oln_type_of(Exact, rvalue) rvalue_type; + typedef oln_type_of(Exact, value) value_type; public: /// Iterator manipulators. /// \{ - void start(); - void next(); - void invalidate(); - bool is_valid() const; + void impl_start(); + void impl_next(); + void impl_invalidate(); + bool impl_is_valid() const; /// \} protected: // Construct an uninitialized value iterator. fwd_viter_lut(lut_type& lut); - // Construct an iterator pointing to value \a val. - fwd_viter_lut(lut_type& lut, const rvalue_type& val); +// FIXME: Should we keep this method? +// // Construct an iterator pointing to value \a val. +// fwd_viter_lut(lut_type& lut, const value_type& val); protected: /// Look-up table. @@ -109,33 +109,21 @@ } template <typename Exact> - fwd_viter_lut<Exact>::fwd_viter_lut(typename fwd_viter_lut<Exact>::lut_type& lut, - const typename fwd_viter_lut<Exact>::rvalue_type& val) - : super_t(), - lut_(lut), - i_() - { - // Initialize underlying iterator (i.e., \a i_.) - i_ = lut_.find(val); - assert(i_ != lut_.end()); - } - - template <typename Exact> void - fwd_viter_lut<Exact>::start() + fwd_viter_lut<Exact>::impl_start() { i_ = lut_.begin(); } template <typename Exact> void - fwd_viter_lut<Exact>::next() + fwd_viter_lut<Exact>::impl_next() { /* Iterate until a different key is reached. In fact, std::multimap might not be the best choice to implement new_to_orig_map_. Maybe a std::map binding orig_val to a std::set of new_val's would is better?. */ - rvalue_type val = i_->first; + value_type val = i_->first; do ++i_; while (i_ != lut_.end() and i_->first == val); @@ -143,14 +131,14 @@ template <typename Exact> void - fwd_viter_lut<Exact>::invalidate() + fwd_viter_lut<Exact>::impl_invalidate() { i_ = lut_.end(); } template <typename Exact> bool - fwd_viter_lut<Exact>::is_valid() const + fwd_viter_lut<Exact>::impl_is_valid() const { return (i_ != lut_.end()); } Index: oln/Makefile.am --- oln/Makefile.am (revision 700) +++ oln/Makefile.am (working copy) @@ -90,6 +90,7 @@ core/abstract/image.hh \ core/abstract/iterator.hh \ core/abstract/iterator_on_points.hh \ + core/abstract/iterator_on_values.hh \ core/abstract/neighborhood.hh \ core/abstract/point.hh \ core/abstract/point_set.hh \ @@ -210,6 +211,7 @@ value/bin.hh \ value/default.hh \ value/greylevel.hh \ + value/lut_value_proxy.hh \ value/proxy.hh \ value/rw_counter.hh \ value/tags.hh \ Index: oln/morpher/with_lut.hh --- oln/morpher/with_lut.hh (revision 700) +++ oln/morpher/with_lut.hh (working copy) @@ -30,6 +30,7 @@ # include <oln/morpher/internal/image_value_morpher.hh> # include <oln/core/lookup_table.hh> +# include <oln/value/lut_value_proxy.hh> # include <oln/core/gen/fwd_viter_lut.hh> @@ -70,17 +71,21 @@ /* lvalue_type: undefined (see oln/morpher/internal/image_value_morpher.hh). */ + /* FIXME: This virtual type (``is_value_wise_mutable'') is + useless, since the presence of mutable_value_proxy_type + suffices to state that the image is value-wise mutable. */ + /* Mutability. As the virtual type `lvalue' is undefined in with_lut<>, it is not point-wise mutable. However, it is value-wise mutable, i.e., the values of the look-up table can be modified. */ typedef mlc::true_ is_value_wise_mutable_type; - // fwd_viter_type: see below. - // mutable_fwd_viter_type: see below. + typedef value::lut_value_proxy<Lut> value_proxy_type; + typedef value::mutable_lut_value_proxy<Lut> mutable_value_proxy_type; + // fwd_viter_type: see below. // FIXME: implement bkd_viter_type! - // FIXME: implement mutable_bkd_viter_type! }; // Rvalue. @@ -100,14 +105,6 @@ { typedef fwd_viter_lut<Lut> ret; }; - - /// Mutable forward viter vtype of morpher::with_lut. - template <typename Image, typename Lut> - struct single_vtype< morpher::with_lut<Image, Lut>, - typedef_::mutable_fwd_viter_type > - { - typedef mutable_fwd_viter_lut<Lut> ret; - }; /// \} @@ -131,8 +128,8 @@ typedef oln_type_of(self_t, value) value_type; typedef oln_type_of(self_t, rvalue) rvalue_type; typedef oln_type_of(self_t, psite) psite_type; - typedef oln_type_of(self_t, fwd_viter) fwd_viter_type; - typedef oln_type_of(self_t, mutable_fwd_viter) mutable_fwd_viter_type; + typedef oln_type_of(self_t, value_proxy) value_proxy_type; + typedef oln_type_of(self_t, mutable_value_proxy) mutable_value_proxy_type; public: with_lut(const Image& image, const Lut& lut); @@ -141,8 +138,8 @@ rvalue_type impl_op_read(const psite_type& p) const; // FIXME: Constness of this method? - fwd_viter_type impl_value(const value_type& v) const; - mutable_fwd_viter_type impl_value(const value_type& v); + value_proxy_type impl_value(const value_type& v) const; + mutable_value_proxy_type impl_value(const value_type& v); protected: lut_type lut_; @@ -170,17 +167,17 @@ } template <typename Image, typename Lut> - typename with_lut<Image, Lut>::fwd_viter_type + typename with_lut<Image, Lut>::value_proxy_type with_lut<Image, Lut>::impl_value(const value_type& v) const { - return fwd_viter_type(lut_, v); + return value_proxy_type(lut_, v); } template <typename Image, typename Lut> - typename with_lut<Image, Lut>::mutable_fwd_viter_type + typename with_lut<Image, Lut>::mutable_value_proxy_type with_lut<Image, Lut>::impl_value(const value_type& v) { - return mutable_fwd_viter_type(lut_, v); + return mutable_value_proxy_type(lut_, v); } template <typename Image, typename Lut> Index: oln/value/lut_value_proxy.hh --- oln/value/lut_value_proxy.hh (revision 0) +++ oln/value/lut_value_proxy.hh (revision 0) @@ -0,0 +1,289 @@ +// Copyright (C) 2006 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_VALUE_LUT_VALUE_PROXY_HH +# define OLN_CORE_VALUE_LUT_VALUE_PROXY_HH + +# include <iostream> +# include <map> +# include <set> +# include <oln/value/proxy.hh> +# include <oln/core/abstract/image/all.hh> + + +namespace oln +{ + + namespace value + { + + /* FIXME: What entity we use to keep a reference on the pointed + value of the LUT: + - a LUT raw iterator (current choice), or + - a value iterator, or + - the value itself. + to keep a reference on the underlying value? + + The third choice (value) /seems/ the most elegant from the + exterior of the proxy, but it's probably the most error-prone + too. */ + + + /*------------------. + | lut_value_proxy. | + `------------------*/ + + template <typename Lut> + class lut_value_proxy : + public abstract::proxy< lut_value_proxy<Lut> > + { + public: + + typedef typename Lut::new_value_type value_type; + typedef typename Lut::const_iterator lut_iter_type; + + // Ctor. + lut_value_proxy(const Lut& lut, const value_type& v); + + // Read. + template <typename V> + operator V() const; + + // Explicit read. + value_type value() const; + + // Write. + template <typename V> + lut_value_proxy<Lut>& operator=(const V& value); + + // FIXME: Is this really necessary? + bool is_valid() const; + + protected: + const Lut& lut_; + lut_iter_type i_; + }; + + + template <typename Lut> + std::ostream& operator<<(std::ostream& ostr, + const lut_value_proxy<Lut>& proxy); + + +# ifndef OLN_INCLUDE_ONLY + + // Ctor. + template <typename Lut> + lut_value_proxy<Lut>::lut_value_proxy(const Lut& lut, + const typename lut_value_proxy<Lut>::value_type& v) + : lut_(lut) + { + i_ = lut_.find(v); + postcondition(is_valid()); + } + + // Read. + template <typename Lut> + template <typename V> + lut_value_proxy<Lut>::operator V() const + { + precondition(is_valid()); + V tmp = i_->second; + return tmp; + } + + // Explicit read. + template <typename Lut> + typename lut_value_proxy<Lut>::value_type + lut_value_proxy<Lut>::value() const + { + precondition(is_valid()); + precondition(i_ != lut_.end()); + return i_->second; + } + + template <typename Lut> + bool + lut_value_proxy<Lut>::is_valid() const + { + return i_ != lut_.end(); + } + + // Op <<. + template <typename Lut> + std::ostream& operator<<(std::ostream& ostr, + const lut_value_proxy<Lut>& proxy) + { + return ostr << proxy.value(); + } + +# endif + + + + /*--------------------------. + | mutable_lut_value_proxy. | + `--------------------------*/ + + template <typename Lut> + class mutable_lut_value_proxy : + public abstract::proxy< mutable_lut_value_proxy<Lut> > + { + public: + + typedef typename Lut::new_value_type value_type; + typedef typename Lut::iterator lut_iter_type; + + // Ctor. + mutable_lut_value_proxy(Lut& lut, const value_type& v); + + // Read. + template <typename V> + operator V() const; + + // Explicit read. + value_type value() const; + + // Write. + template <typename V> + mutable_lut_value_proxy<Lut>& operator=(const V& value); + + // FIXME: Is this really necessary? + bool is_valid() const; + + protected: + Lut& lut_; + lut_iter_type i_; + }; + + + template <typename Lut> + std::ostream& operator<<(std::ostream& ostr, + const mutable_lut_value_proxy<Lut>& proxy); + + +# ifndef OLN_INCLUDE_ONLY + + // Ctor. + template <typename Lut> + mutable_lut_value_proxy<Lut>::mutable_lut_value_proxy(Lut& lut, + const typename mutable_lut_value_proxy<Lut>::value_type& v) + : lut_(lut) + { + i_ = lut_.find(v); + postcondition(is_valid()); + } + + // Read. + template <typename Lut> + template <typename V> + mutable_lut_value_proxy<Lut>::operator V() const + { + // FIXME: Turn this into a is_valid method. + precondition(is_valid()); + V tmp = i_->second; + return tmp; + } + + // Explicit read. + template <typename Lut> + typename mutable_lut_value_proxy<Lut>::value_type + mutable_lut_value_proxy<Lut>::value() const + { + // FIXME: Turn this into a is_valid method. + precondition(is_valid()); + precondition(i_ != lut_.end()); + return i_->second; + } + + // Write. + + template <typename Lut> + template <typename V> + mutable_lut_value_proxy<Lut>& + mutable_lut_value_proxy<Lut>::operator=(const V& value) + { + precondition(is_valid()); + + typedef typename Lut::orig_value_type orig_value_t; + typedef typename Lut::new_value_type new_value_t; + + // Current ``new'' value. + new_value_t cur_new_val = i_->first; + + // Shortcuts. + typedef lut_iter_type new_iter_t; + typedef std::pair<new_iter_t, new_iter_t> new_iter_range_t; + + // Current ``original'' value(s) associated to the next ``new'' + // value VALUE. + new_iter_range_t cur_orig_val_range = + lut_.new_to_orig_map().equal_range(cur_new_val); + // A temporary map where additional bindings will be stored. + typename Lut::new_to_orig_map_type additional_bindings; + + for (new_iter_t j = cur_orig_val_range.first; + j != cur_orig_val_range.second; ++j) + { + // Update the orig-to-new map (substitution). + orig_value_t orig_val = j->second; + lut_.orig_to_new_map()[orig_val] = value; + // Populate the temp map. + additional_bindings.insert(std::make_pair(value, orig_val)); + } + // Update the new-to-orig map (deletion). + lut_.new_to_orig_map().erase(cur_orig_val_range.first, + cur_orig_val_range.second); + // Update the new-to-orig map (insertion). + lut_.new_to_orig_map().insert(additional_bindings.begin(), + additional_bindings.end()); + return *this; + } + + template <typename Lut> + bool + mutable_lut_value_proxy<Lut>::is_valid() const + { + return i_ != lut_.end(); + } + + // Op <<. + template <typename Lut> + std::ostream& operator<<(std::ostream& ostr, + const mutable_lut_value_proxy<Lut>& proxy) + { + return ostr << proxy.value(); + } + +# endif + + } // end of namespace oln::value + +} // end of namespace oln + + +#endif // ! OLN_CORE_VALUE_LUT_VALUE_PROXY_HH
participants (1)
-
Roland Levillain