2006-10-24 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
Add a morpher to count read-write ops.
* tests/morphers/count_rw_morpher.cc: New.
* tests/morphers/Makefile.am: Update.
* oln/morpher/count_rw.hh: New.
* oln/value/proxy.hh: New.
* oln/value/rw_counter.hh: New.
* oln/Makefile.am: Update.
* oln/core/traits_id.hh (unop_vproxy, binop_vproxy): New.
(others): Update.
* oln/core/typedefs.hh
(oln_is_computed, oln_is_computed_): New.
* oln/morpher/internal/image_value_morpher.hh
(image_value_morpher): New overloading for ctor.
(image_): Add & to its type.
Index: tests/morphers/count_rw_morpher.cc
===================================================================
--- tests/morphers/count_rw_morpher.cc (revision 0)
+++ tests/morphers/count_rw_morpher.cc (revision 0)
@@ -0,0 +1,53 @@
+// 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.
+
+/// Test the count_rw morpher.
+
+#include <cassert>
+#include <oln/basics2d.hh>
+#include <oln/morpher/count_rw.hh>
+
+
+int main()
+{
+ using namespace oln;
+
+ typedef image2d<int> image_t;
+ image_t ima(3,3);
+ morpher::count_rw<image_t> ima2(ima);
+ point2d p(0,0);
+
+ ima2(p);
+ ima2(p) = 51;
+ int i = ima2(p);
+ i = 0; // suppress "unused i" warning
+
+ assert(value::counter::n_readwrite_calls(ima) == 3);
+ assert(value::counter::n_readonly_calls(ima) == 0);
+ assert(value::counter::n_reads(ima) == 1);
+ assert(value::counter::n_writes(ima) == 1);
+}
Index: tests/morphers/Makefile.am
===================================================================
--- tests/morphers/Makefile.am (revision 674)
+++ tests/morphers/Makefile.am (working copy)
@@ -21,6 +21,7 @@
check_PROGRAMS = \
identity_morpher \
add_neighborhood_morpher \
+ count_rw_morpher \
slice_morpher \
stack_morpher \
value_cast \
@@ -31,6 +32,7 @@
# Morphers.
identity_morpher_SOURCES = identity_morpher.cc
add_neighborhood_morpher_SOURCES = add_neighborhood_morpher.cc
+count_rw_morpher_SOURCES = count_rw_morpher.cc
slice_morpher_SOURCES = slice_morpher.cc
stack_morpher_SOURCES = stack_morpher.cc
value_cast_SOURCES = value_cast.cc
Index: oln/core/traits_id.hh
===================================================================
--- oln/core/traits_id.hh (revision 674)
+++ oln/core/traits_id.hh (working copy)
@@ -37,12 +37,22 @@
namespace id
{
+ /// \{
+ /// Generic identifiers for operators.
+ enum {
+ unop_vproxy = 1,
+ binop_vproxy = 1
+ };
+
+ /// \}
+
+
/// \{
/// Identifiers for oln binary operators +.
enum {
- op_plus_pointnd_dpointnd = 1
+ op_plus_pointnd_dpointnd = 2
};
/// \}
@@ -53,8 +63,8 @@
/// Identifiers for oln binary operators -.
enum {
- op_minus_pointnd_pointnd = 1,
- op_minus_pointnd_dpointnd = 2
+ op_minus_pointnd_pointnd = 2,
+ op_minus_pointnd_dpointnd = 3
};
/// \}
@@ -65,7 +75,7 @@
/// Identifiers for oln unary operators -.
enum {
- op_uminus_dpointnd = 1
+ op_uminus_dpointnd = 2
};
/// \}
Index: oln/core/typedefs.hh
===================================================================
--- oln/core/typedefs.hh (revision 674)
+++ oln/core/typedefs.hh (working copy)
@@ -227,6 +227,9 @@
# define oln_dpoint(T) oln_type_of(T, dpoint)
# define oln_dpoint_(T) oln_type_of_(T, dpoint)
+# define oln_is_computed(T) oln_type_of(T, is_computed)
+# define oln_is_computed_(T) oln_type_of_(T, is_computed)
+
# define oln_value(T) oln_type_of(T, value)
# define oln_value_(T) oln_type_of_(T, value)
Index: oln/Makefile.am
===================================================================
--- oln/Makefile.am (revision 674)
+++ oln/Makefile.am (working copy)
@@ -170,6 +170,7 @@
morpher/internal/image_value_morpher.hh \
\
morpher/add_neighborhood.hh \
+ morpher/count_rw.hh \
morpher/fwd_decls.hh \
morpher/identity.hh \
morpher/tags.hh \
@@ -186,6 +187,8 @@
value/all.hh \
value/default.hh \
value/greylevel.hh \
+ value/proxy.hh \
+ value/rw_counter.hh \
value/tags.hh \
\
basics1d.hh \
Index: oln/morpher/internal/image_value_morpher.hh
===================================================================
--- oln/morpher/internal/image_value_morpher.hh (revision 674)
+++ oln/morpher/internal/image_value_morpher.hh (working copy)
@@ -88,13 +88,15 @@
{
public:
- // FIXME: Handle the constness.
+ // FIXME: Hack here; constness should be properly handled.
image_value_morpher(const Image& image);
+ image_value_morpher(Image& image);
+
const Image& delegate() const;
Image& delegate();
protected:
- Image image_;
+ Image& image_;
};
@@ -103,6 +105,12 @@
template <typename Image, typename Exact>
image_value_morpher<Image, Exact>::image_value_morpher(const Image&
image) :
+ image_(const_cast<Image&>(image))
+ {
+ }
+
+ template <typename Image, typename Exact>
+ image_value_morpher<Image, Exact>::image_value_morpher(Image& image) :
image_(image)
{
}
Index: oln/morpher/count_rw.hh
===================================================================
--- oln/morpher/count_rw.hh (revision 0)
+++ oln/morpher/count_rw.hh (revision 0)
@@ -0,0 +1,156 @@
+// 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_MORPHER_COUNT_RW_HH
+# define OLN_MORPHER_COUNT_RW_HH
+
+# include <oln/value/rw_counter.hh>
+# include <oln/morpher/internal/image_value_morpher.hh>
+
+
+namespace oln
+{
+
+
+ namespace morpher
+ {
+ // Forward declaration.
+ template <typename Image> struct count_rw;
+
+ } // end of namespace oln::morpher
+
+
+ /// Super type.
+ template <typename Image>
+ struct set_super_type< morpher::count_rw<Image> >
+ {
+ typedef morpher::count_rw<Image> self_t;
+ typedef morpher::internal::image_value_morpher<Image, self_t> ret;
+ };
+
+
+ template <typename Image>
+ struct vtypes< morpher::count_rw<Image> >
+ {
+ public:
+ typedef mlc::true_ is_computed_type;
+
+ typedef oln_value(Image) value_type;
+ typedef value::rw_counter<Image> lvalue_type;
+ };
+
+ template <typename Image>
+ struct single_vtype< morpher::count_rw<Image>, typedef_::rvalue_type >
+ {
+ typedef value::ro_counter<Image> ret;
+ };
+
+
+
+ namespace morpher
+ {
+
+ /// 'Image thru Function' morpher.
+ template <typename Image>
+ class count_rw : public internal::image_value_morpher< Image,
+ morpher::count_rw<Image> >
+ {
+ private:
+
+ typedef count_rw<Image> self_t;
+ typedef internal::image_value_morpher<Image, self_t> super_t;
+
+ using super_t::image_;
+
+ public:
+
+ count_rw(Image& image);
+ count_rw(oln::abstract::mutable_image<Image>& image);
+
+ oln_rvalue(self_t) impl_op_read(const oln_psite(self_t)& p) const;
+ oln_lvalue(self_t) impl_op_readwrite(const oln_psite(self_t)& p);
+ };
+
+
+ namespace ERROR
+ {
+
+ struct FIXME;
+
+ } // end of namespace oln::morpher::ERROR
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ // public
+
+ template <typename Image>
+ count_rw<Image>::count_rw(Image& image) :
+ super_t(image)
+ {
+ }
+
+ template <typename Image>
+ count_rw<Image>::count_rw(oln::abstract::mutable_image<Image>& image)
:
+ super_t(image.exact())
+ {
+ }
+
+ template <typename Image>
+ oln_rvalue(count_rw<Image>)
+ count_rw<Image>::impl_op_read(const oln_psite(count_rw<Image>)& p)
const
+ {
+ value::ro_counter<Image> tmp(image_, p);
+ return tmp;
+ }
+
+ template <typename Image>
+ oln_lvalue(count_rw<Image>)
+ count_rw<Image>::impl_op_readwrite(const oln_psite(count_rw<Image>)&
p)
+ {
+ value::rw_counter<Image> tmp(image_, p);
+ return tmp;
+ }
+
+# endif
+
+ } // end of namespace oln::morpher
+
+
+ template <typename I>
+ morpher::count_rw<I>
+ count_rw(oln::abstract::mutable_image<I>& input)
+ {
+ morpher::count_rw<I> tmp(input.exact());
+ return tmp;
+ }
+
+
+} // end of namespace oln
+
+
+#endif // ! OLN_MORPHER_COUNT_RW_HH
Index: oln/value/proxy.hh
===================================================================
--- oln/value/proxy.hh (revision 0)
+++ oln/value/proxy.hh (revision 0)
@@ -0,0 +1,472 @@
+// 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_PROXY_HH
+# define OLN_CORE_VALUE_PROXY_HH
+
+# include <xtd/optraits.hh>
+# include <oln/core/type.hh>
+# include <oln/core/traits_id.hh>
+
+
+namespace oln
+{
+
+
+ namespace value
+ {
+
+ namespace abstract
+ {
+
+ template <typename E>
+ struct proxy : public virtual stc::any__simple<E>,
+ public oln::type
+ {
+ protected:
+ proxy();
+ };
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ template <typename E>
+ proxy<E>::proxy()
+ {
+ }
+
+# endif
+
+ } // end of namespace oln::value::abstract
+
+
+ } // end of namespace oln::value
+
+
+
+ // Traits.
+ //---------------------------
+
+
+ /// unary op on a value proxy
+ template <typename name, typename T>
+ struct case_ < xtd::op_<name>, T,
+ oln::id::unop_vproxy >
+ : where_< mlc_is_a(T, value::abstract::proxy) >
+ {
+ struct protected_ {
+ typedef typename T::value_type V;
+ typedef xtd_unop_trait(xtd::op_<name>, V) ret;
+ };
+ };
+
+
+ /// binary op involving at least one value proxy
+ template <typename name, typename T1, typename T2>
+ struct case_ < xtd::op_<name>, mlc::pair_<T1,T2>,
+ oln::id::binop_vproxy >
+ : where_< mlc::or_< mlc_is_a(T1, value::abstract::proxy),
+ mlc_is_a(T2, value::abstract::proxy) > >
+ {
+ template <typename T>
+ struct value_type
+ {
+ typedef mlc_typedef(T, value_type) V;
+ typedef typename mlc::if_< mlc_is_found(V), V, T >::ret ret;
+ };
+ struct protected_ {
+ typedef mlc_ret(value_type<T1>) V1;
+ typedef mlc_ret(value_type<T2>) V2;
+ typedef xtd_binop_trait(xtd::op_<name>, V1, V2) ret;
+ };
+ };
+
+
+
+ // Unary ops.
+ //---------------------------
+
+
+ // Op -.
+ template <typename P>
+ xtd_op_uminus_trait(P) operator - (const value::abstract::proxy<P>& val);
+ // Op not.
+ template <typename P>
+ xtd_op_lnot_trait(P) operator not (const value::abstract::proxy<P>& val);
+
+ // FIXME: To be continued.
+
+
+
+ // Binary ops.
+ //---------------------------
+
+ // Op +.
+ template <typename P, typename V>
+ xtd_op_plus_trait(P, V) operator + (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_plus_trait(V, P) operator + (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op -.
+ template <typename P, typename V>
+ xtd_op_minus_trait(P, V) operator - (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_minus_trait(V, P) operator - (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op *.
+ template <typename P, typename V>
+ xtd_op_mult_trait(P, V) operator * (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_mult_trait(V, P) operator * (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op /.
+ template <typename P, typename V>
+ xtd_op_div_trait(P, V) operator / (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_div_trait(V, P) operator / (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op %.
+ template <typename P, typename V>
+ xtd_op_mod_trait(P, V) operator % (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_mod_trait(V, P) operator % (const V& lhs, const
value::abstract::proxy<P>& rhs);
+
+ // Op ==.
+ template <typename P, typename V>
+ xtd_op_eq_trait(P, V) operator == (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_eq_trait(V, P) operator == (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op !=.
+ template <typename P, typename V>
+ xtd_op_neq_trait(P, V) operator != (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_neq_trait(V, P) operator != (const V& lhs, const
value::abstract::proxy<P>& rhs);
+
+ // Op <.
+ template <typename P, typename V>
+ xtd_op_less_trait(P, V) operator < (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_less_trait(V, P) operator < (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op <=.
+ template <typename P, typename V>
+ xtd_op_leq_trait(P, V) operator <= (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_leq_trait(V, P) operator <= (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op >=.
+ template <typename P, typename V>
+ xtd_op_geq_trait(P, V) operator >= (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_geq_trait(V, P) operator >= (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op >.
+ template <typename P, typename V>
+ xtd_op_greater_trait(P, V) operator > (const value::abstract::proxy<P>&
lhs, const V& rhs);
+ template <typename V, typename P>
+ xtd_op_greater_trait(V, P) operator > (const V& lhs, const
value::abstract::proxy<P>& rhs);
+
+ // Op and.
+ template <typename P, typename V>
+ xtd_op_land_trait(P, V) operator and (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_land_trait(V, P) operator and (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op or.
+ template <typename P, typename V>
+ xtd_op_lor_trait(P, V) operator or (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_lor_trait(V, P) operator or (const V& lhs, const
value::abstract::proxy<P>& rhs);
+ // Op xor.
+ template <typename P, typename V>
+ xtd_op_lxor_trait(P, V) operator xor (const value::abstract::proxy<P>& lhs,
const V& rhs);
+ template <typename V, typename P>
+ xtd_op_lxor_trait(V, P) operator xor (const V& lhs, const
value::abstract::proxy<P>& rhs);
+
+ // FIXME: To be continued.
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+
+ // Unary ops.
+ //---------------------------
+
+
+ // Op -.
+ template <typename P>
+ xtd_op_uminus_trait(P) operator - (const value::abstract::proxy<P>& val)
+ {
+ return - val.exact().value();
+ }
+
+ // Op not.
+
+ template <typename P>
+ xtd_op_lnot_trait(P)
+ operator not (const value::abstract::proxy<P>& val)
+ {
+ return not val.exact().value();
+ }
+
+
+ // FIXME: To be continued.
+
+
+
+ // Binary ops.
+ //---------------------------
+
+ // Op +.
+
+ template <typename P, typename V>
+ xtd_op_plus_trait(P, V)
+ operator + (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() + rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_plus_trait(V, P)
+ operator + (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs + rhs.exact().value();
+ }
+
+ // Op -.
+
+ template <typename P, typename V>
+ xtd_op_minus_trait(P, V)
+ operator - (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() - rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_minus_trait(V, P)
+ operator - (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs - rhs.exact().value();
+ }
+
+ // Op *.
+
+ template <typename P, typename V>
+ xtd_op_mult_trait(P, V)
+ operator * (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() * rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_mult_trait(V, P)
+ operator * (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs * rhs.exact().value();
+ }
+
+ // Op /.
+
+ template <typename P, typename V>
+ xtd_op_div_trait(P, V)
+ operator / (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() / rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_div_trait(V, P)
+ operator / (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs / rhs.exact().value();
+ }
+
+ // Op %.
+
+ template <typename P, typename V>
+ xtd_op_mod_trait(P, V)
+ operator % (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() % rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_mod_trait(V, P)
+ operator % (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs % rhs.exact().value();
+ }
+
+
+ // Op ==.
+
+ template <typename P, typename V>
+ xtd_op_eq_trait(P, V)
+ operator == (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() == rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_eq_trait(V, P)
+ operator == (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs == rhs.exact().value();
+ }
+
+
+ // Op !=.
+
+ template <typename P, typename V>
+ xtd_op_neq_trait(P, V)
+ operator != (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() != rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_neq_trait(V, P)
+ operator != (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs != rhs.exact().value();
+ }
+
+
+ // Op <.
+
+ template <typename P, typename V>
+ xtd_op_less_trait(P, V)
+ operator < (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() < rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_less_trait(V, P)
+ operator < (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs < rhs.exact().value();
+ }
+
+ // Op <=.
+
+ template <typename P, typename V>
+ xtd_op_leq_trait(P, V)
+ operator <= (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() <= rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_leq_trait(V, P)
+ operator <= (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs <= rhs.exact().value();
+ }
+
+ // Op >=.
+
+ template <typename P, typename V>
+ xtd_op_geq_trait(P, V)
+ operator >= (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() >= rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_geq_trait(V, P)
+ operator >= (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs >= rhs.exact().value();
+ }
+
+ // Op >.
+
+ template <typename P, typename V>
+ xtd_op_greater_trait(P, V)
+ operator > (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() > rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_greater_trait(V, P)
+ operator > (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs > rhs.exact().value();
+ }
+
+
+ // Op and.
+
+ template <typename P, typename V>
+ xtd_op_land_trait(P, V)
+ operator and (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() and rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_land_trait(V, P)
+ operator and (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs and rhs.exact().value();
+ }
+
+ // Op or.
+
+ template <typename P, typename V>
+ xtd_op_lor_trait(P, V)
+ operator or (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() or rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_lor_trait(V, P)
+ operator or (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs or rhs.exact().value();
+ }
+
+ // Op xor.
+
+ template <typename P, typename V>
+ xtd_op_lxor_trait(P, V)
+ operator xor (const value::abstract::proxy<P>& lhs, const V& rhs)
+ {
+ return lhs.exact().value() xor rhs;
+ }
+
+ template <typename V, typename P>
+ xtd_op_lxor_trait(V, P)
+ operator xor (const V& lhs, const value::abstract::proxy<P>& rhs)
+ {
+ return lhs xor rhs.exact().value();
+ }
+
+ // FIXME: To be continued.
+
+# endif
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_VALUE_PROXY_HH
Index: oln/value/rw_counter.hh
===================================================================
--- oln/value/rw_counter.hh (revision 0)
+++ oln/value/rw_counter.hh (revision 0)
@@ -0,0 +1,241 @@
+// 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_RW_COUNTER_HH
+# define OLN_CORE_VALUE_RW_COUNTER_HH
+
+# include <iostream>
+# include <map>
+# include <oln/value/proxy.hh>
+# include <oln/core/abstract/image/all.hh>
+
+
+namespace oln
+{
+
+
+ namespace value
+ {
+
+
+ struct counter
+ {
+ typedef std::map<void*, unsigned> map_t;
+
+ // read-write call
+ static unsigned& n_readwrite_calls(const oln::type& ima)
+ {
+ static map_t n;
+ return n[(void*)(&ima)];
+ }
+ // read-only call
+ static unsigned& n_readonly_calls(const oln::type& ima)
+ {
+ static map_t n;
+ return n[(void*)(&ima)];
+ }
+ // read (effective)
+ static unsigned& n_reads(const oln::type& ima)
+ {
+ static map_t n;
+ return n[(void*)(&ima)];
+ }
+ // write (effective)
+ static unsigned& n_writes(const oln::type& ima)
+ {
+ static map_t n;
+ return n[(void*)(&ima)];
+ }
+
+ static void print(const oln::type& ima)
+ {
+ std::cout << "n_readwrite_calls = " << n_readwrite_calls(ima)
<< std::endl
+ << "n_readonly_calls = " << n_readonly_calls(ima) <<
std::endl
+ << "n_reads = " << n_reads(ima) <<
std::endl
+ << "n_writes = " << n_writes(ima) <<
std::endl;
+ }
+ };
+
+
+ template <typename I>
+ class rw_counter : public abstract::proxy< rw_counter<I> >
+ {
+ public:
+
+ typedef oln_value(I) value_type;
+
+ // Ctor.
+ rw_counter(oln::abstract::mutable_image<I>& ima,
+ const oln_psite(I)& p);
+
+ // Read.
+ template <typename V>
+ operator V() const;
+
+ // Explicit read.
+ oln_rvalue(I) value() const;
+
+ // Write.
+ template <typename V>
+ rw_counter<I>& operator=(const V& value);
+
+ protected:
+ I& ima_;
+ const oln_psite(I)& p_;
+ };
+
+
+ template <typename I>
+ std::ostream& operator<<(std::ostream& ostr, const
rw_counter<I>& proxy);
+
+
+ template <typename I>
+ class ro_counter : public abstract::proxy< ro_counter<I> >
+ {
+ public:
+
+ typedef oln_value(I) value_type;
+
+ // Ctor.
+ ro_counter(const oln::abstract::image<I>& ima,
+ const oln_psite(I)& p);
+
+ // Read.
+ template <typename V>
+ operator V() const;
+
+ // Explicit read.
+ oln_rvalue(I) value() const;
+
+ protected:
+ const I& ima_;
+ const oln_psite(I)& p_;
+ };
+
+
+ template <typename I>
+ std::ostream& operator<<(std::ostream& ostr, const
ro_counter<I>& proxy);
+
+
+
+# ifndef OLN_INCLUDE_ONLY
+
+ // Ctor.
+ template <typename I>
+ rw_counter<I>::rw_counter(oln::abstract::mutable_image<I>& ima,
+ const oln_psite(I)& p)
+ : ima_(ima.exact()),
+ p_(p)
+ {
+ ++counter::n_readwrite_calls(ima_);
+ }
+
+ // Read.
+ template <typename I>
+ template <typename V>
+ rw_counter<I>::operator V() const
+ {
+ ++counter::n_reads(ima_);
+ V tmp = ima_(p_);
+ return tmp;
+ }
+
+ // Explicit read.
+ template <typename I>
+ oln_rvalue(I)
+ rw_counter<I>::value() const
+ {
+ ++counter::n_reads(ima_);
+ return ima_(p_);
+ }
+
+ // Write.
+
+ template <typename I>
+ template <typename V>
+ rw_counter<I>&
+ rw_counter<I>::operator=(const V& value)
+ {
+ ima_(p_) = value;
+ ++counter::n_writes(ima_);
+ return *this;
+ }
+
+ // Op <<.
+ template <typename I>
+ std::ostream& operator<<(std::ostream& ostr,
+ const rw_counter<I>& proxy)
+ {
+ return ostr << proxy.value();
+ }
+
+
+ // Ctor.
+ template <typename I>
+ ro_counter<I>::ro_counter(const oln::abstract::image<I>& ima,
+ const oln_psite(I)& p)
+ : ima_(ima.exact()),
+ p_(p)
+ {
+ ++counter::n_readonly_calls(ima_);
+ }
+
+ // Read.
+ template <typename I>
+ template <typename V>
+ ro_counter<I>::operator V() const
+ {
+ ++counter::n_reads(ima_);
+ V tmp = ima_(p_);
+ return tmp;
+ }
+
+ // Explicit read.
+ template <typename I>
+ oln_rvalue(I)
+ ro_counter<I>::value() const
+ {
+ ++counter::n_reads(ima_);
+ return ima_(p_);
+ }
+
+ // Op <<.
+ template <typename I>
+ std::ostream& operator<<(std::ostream& ostr,
+ const ro_counter<I>& proxy)
+ {
+ return ostr << proxy.value();
+ }
+
+# endif
+
+ } // end of namespace oln::value
+
+} // end of namespace oln
+
+
+#endif // ! OLN_CORE_VALUE_RW_COUNTER_HH