
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update the trait system and some value types. New files. * mln/trait/promote.hh: Move built-in defs into... * mln/value/builtin/promotions.hh: ...this new file. Complete definitions. * mln/trait/solve.hh: Update; now handle priorities in the binary case. * mln/trait/op/postdec.hh: New. * mln/trait/op/div.hh: New. * mln/trait/op/predec.hh: New. * mln/trait/op/neq.hh: New. * mln/trait/op/eq.hh: New. * mln/trait/op/uplus.hh: New. * mln/trait/op/mod.hh: New. * mln/trait/op/postinc.hh: New. * mln/trait/op/preinc.hh: New. * mln/trait/op/all.hh: Update. * mln/trait/op/times.hh, * mln/trait/op/plus.hh, * mln/trait/op/minus.hh, * mln/trait/op/uminus.hh: Remove "default is promotion". * mln/trait/value_.hh (value_integer_): Move into... * mln/value/builtin/integers.hh: ...this new file. * mln/value/concept/built_in.hh: New. * mln/value/concept/data.hh: New. * mln/value/equiv.hh: New. * mln/value/builtin/ops.hh: New. * mln/value/builtin/symbolics.hh: New. * mln/value/builtin/floatings.hh: New. * mln/value/builtin/all.hh: New. * mln/value/ops.hh: New. * tests/value_equiv.cc: New. Propagate. * mln/core/macros.hh (mln_equiv_): New. * mln/core/point.hh (h_vec): Change operator into... (to_h_vec): ...this new method. * mln/core/category.hh: Typo. * mln/core/ops.hh: Add traits. (operator+, operator-): New unary ops. (operator+=, -=, *=, /=, %=): New ops. * mln/core/concept/object.hh: Include metal/ret.hh. * mln/core/concept/value.hh (to_equiv): New in doc. * mln/literal/ops.hh (operators): New. * mln/metal/mat.hh: Remove unuseful include. * mln/metal/ret.hh: New. * mln/metal/math/pow.hh: Clean-up. * mln/metal/math/max.hh: New. * mln/metal/math/all.hh: Update. * mln/metal/math/sqrt.hh: Clean-up. * mln/metal/vec.hh: Add traits. (operator!=, +=, -=): Remove; obsolete. (operator=): New overload for literal zero. (operator*): Change sig. (operator<<): Merge both versions. (vprod): Precise return type. * mln/value/proxy.hh: Fix guard. * mln/value/graylevel.hh: Add traits; add doc. (operator=): Remove; obsolete. (operator=): Update. * mln/value/cast.hh: Typo. * mln/value/gray.hh: Re-write. (unsigned long): Turn into long so that we can have temporary negative values. * mln/value/rgb8.hh: Include int_u8. * mln/value/float01_.hh: Change equiv from int_u to float. * mln/value/scalar.hh (to_equiv): New. (scalar): Make it generic. * mln/value/builtin.hh: Remove. * mln/value/quat.hh: Add traits. (scal, vect): Rename as... (s, v): ...these. (operator): New. Clean-up code. * mln/value/int_s.hh (operator-): Remove; obsolete. Remove traits; obsolete. * mln/value/internal/value_like.hh: . * mln/value/int_u.hh: Remove traits; obsolete. (operator>>): New. * mln/value/concept/symbolic.hh, * mln/value/concept/floating.hh, * mln/value/concept/structured.hh, * mln/value/concept/scalar.hh, * mln/value/concept/integer.hh, * mln/value/concept/vectorial.hh (category): Fix missing. * mln/value/concept/all.hh: Update. * mln/value/concept/scalar.hh (operators): Remove; obsolete. (operator++, --): New. * mln/value/float01.hh: Change doc. * mln/value/rgb.hh: Change inheritance from Structured to Vectorial. Inherit also from value_like_. (red, green, blue): New mutable versions. (operator>>): New. (rgb): Remove ctors from scalars. (operator+=, -=, =): Remove; obsolete. (operator+, -): Remove versions with scalars. (operators): Move out of the class. (operator/): Fix sig. (buffer): Remove; useless. (nbits): Fix. Set equiv and interop to metal::vec. * mln/value/float01_f.hh (operator=): New overload for float. Add/fix doc. * mln/convert/to_rgb.hh: Typo. * mln/io/pnm/save_header.hh, * mln/io/pnm/save.hh, * mln/io/pnm/load.hh: Fix rgb read. * img/lena.ppm: Fix; now we have colors! * tests/value_quat.cc, * tests/metal_vec.cc, * tests/trait_op_uminus.cc, * tests/border_resize_sub_image.cc, * tests/rle_image.cc, * tests/h_vec.cc, * tests/io_ppm.cc, * tests/value_rgb8.cc, * tests/trait_op_plus.cc, * tests/value_int_u8.cc, * tests/value_graylevel.cc: Update. img/lena.ppm | 0 mln/convert/to_rgb.hh | 4 mln/core/category.hh | 1 mln/core/concept/object.hh | 4 mln/core/concept/value.hh | 6 mln/core/macros.hh | 1 mln/core/ops.hh | 301 +++++++++++++++++++++----- mln/core/point.hh | 12 - mln/io/pnm/load.hh | 10 mln/io/pnm/save.hh | 2 mln/io/pnm/save_header.hh | 6 mln/literal/ops.hh | 175 ++++++++++++++- mln/metal/mat.hh | 1 mln/metal/math/all.hh | 1 mln/metal/math/max.hh | 77 ++++++ mln/metal/math/pow.hh | 5 mln/metal/math/sqrt.hh | 5 mln/metal/ret.hh | 43 +++ mln/metal/vec.hh | 223 +++++-------------- mln/trait/op/all.hh | 16 + mln/trait/op/div.hh | 60 +++++ mln/trait/op/eq.hh | 68 ++++++ mln/trait/op/minus.hh | 10 mln/trait/op/mod.hh | 60 +++++ mln/trait/op/neq.hh | 60 +++++ mln/trait/op/plus.hh | 10 mln/trait/op/postdec.hh | 64 +++++ mln/trait/op/postinc.hh | 64 +++++ mln/trait/op/predec.hh | 64 +++++ mln/trait/op/preinc.hh | 64 +++++ mln/trait/op/times.hh | 10 mln/trait/op/uminus.hh | 9 mln/trait/op/uplus.hh | 64 +++++ mln/trait/promote.hh | 68 ------ mln/trait/solve.hh | 439 +++++++++++++++++++++++++++------------ mln/trait/value_.hh | 26 -- mln/value/builtin/all.hh | 45 +++ mln/value/builtin/floatings.hh | 90 +++++++ mln/value/builtin/integers.hh | 109 +++++++++ mln/value/builtin/ops.hh | 415 ++++++++++++++++++++++++++++++++++++ mln/value/builtin/promotions.hh | 204 ++++++++++++++++++ mln/value/builtin/symbolics.hh | 71 ++++++ mln/value/cast.hh | 1 mln/value/concept/all.hh | 3 mln/value/concept/built_in.hh | 70 ++++++ mln/value/concept/data.hh | 75 ++++++ mln/value/concept/floating.hh | 16 - mln/value/concept/integer.hh | 13 - mln/value/concept/scalar.hh | 86 ------- mln/value/concept/structured.hh | 16 - mln/value/concept/symbolic.hh | 19 - mln/value/concept/vectorial.hh | 14 - mln/value/equiv.hh | 157 +++++++++++++ mln/value/float01.hh | 5 mln/value/float01_.hh | 16 - mln/value/float01_f.hh | 16 - mln/value/gray.hh | 223 ++++++++++++++----- mln/value/graylevel.hh | 269 +++++++++++++++++++---- mln/value/int_s.hh | 37 --- mln/value/int_u.hh | 59 +---- mln/value/internal/value_like.hh | 12 - mln/value/ops.hh | 167 ++++++++++++++ mln/value/proxy.hh | 2 mln/value/quat.hh | 372 ++++++++++++++++++++++----------- mln/value/rgb.hh | 309 +++++++++------------------ mln/value/rgb8.hh | 1 mln/value/scalar.hh | 29 +- tests/border_resize_sub_image.cc | 7 tests/h_vec.cc | 2 tests/io_ppm.cc | 7 tests/metal_vec.cc | 10 tests/rle_image.cc | 2 tests/trait_op_plus.cc | 1 tests/trait_op_uminus.cc | 14 - tests/value_equiv.cc | 58 +++++ tests/value_graylevel.cc | 40 ++- tests/value_int_u8.cc | 1 tests/value_quat.cc | 10 tests/value_rgb8.cc | 19 - 79 files changed, 3895 insertions(+), 1230 deletions(-) Index: tests/value_quat.cc --- tests/value_quat.cc (revision 1381) +++ tests/value_quat.cc (working copy) @@ -47,14 +47,14 @@ std::cout << q2 << std::endl; std::cout << q3 << std::endl; - std::cout << q1.scal() << std::endl; + std::cout << q1.s() << std::endl; - q1.set_scal(2.6); + q1.s() = 2.6; std::cout << q1 << std::endl; - std::cout << q1.vect() << std::endl; + std::cout << q1.v() << std::endl; - q2.set_vect(make::vec(1.4, 5.9, 3.1)); + q2.v() = make::vec(1.4, 5.9, 3.1); std::cout << q2 << std::endl; std::cout << q2 * q3 << std::endl; @@ -66,7 +66,7 @@ std::cout << q2.conj() << std::endl; std::cout << q2.inv() << std::endl; - std::cout << norm::l2(q2) << ' ' << norm::l2(q2.inv()) << std::endl; + std::cout << norm::l2(q2.to_vec()) << ' ' << norm::l2(q2.inv().to_vec()) << std::endl; std::cout << q2.inv().inv() << std::endl; } Index: tests/value_equiv.cc --- tests/value_equiv.cc (revision 0) +++ tests/value_equiv.cc (revision 0) @@ -0,0 +1,58 @@ +// 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. + +/*! \file tests/value_equiv.cc + * + * \brief Tests on mln::value::equiv. + * + * \todo Rename "::to_equiv()" as "::to_equiv_()". + */ + +#include <mln/value/int_u8.hh> +#include <mln/value/equiv.hh> + + +int main() +{ + using namespace mln; + + value::int_u8 i = 51; + + { + const unsigned& u = i.to_equiv(); + mln_assertion(u = 51); + } + { + const unsigned& u = value::equiv(i); + mln_assertion(u = 51); + } + { + const unsigned& u = value::equiv( value::scalar(i) ); + mln_assertion(u = 51); + } + +} Index: tests/metal_vec.cc --- tests/metal_vec.cc (revision 1381) +++ tests/metal_vec.cc (working copy) @@ -31,6 +31,8 @@ */ #include <mln/metal/vec.hh> +#include <mln/value/int_u8.hh> + int main() { @@ -40,4 +42,12 @@ metal::vec<3,float> v_f = make::vec(2.6, 1.9, 5.2); std::cout << v_int + v_f << std::endl; + std::cout << v_f / 3 << std::endl; + + { +// value::int_u8 i = 3; +// std::cout << value::scalar(i) * v_f << std::endl; + // FIXME: Read FIXME in metal::vec::operator* and set up a test! + } + } Index: tests/trait_op_uminus.cc --- tests/trait_op_uminus.cc (revision 1381) +++ tests/trait_op_uminus.cc (working copy) @@ -106,24 +106,24 @@ using namespace mln; // { -// mln_trait_op_uminus_(test) tmp; // bool if precise +// mln_trait_op_uminus_(test) tmp; /* bool if precise */ // bool* b = &tmp; // *b = true; // } // { -// mln_trait_op_uminus_(test) tmp; // int if no precise def and both sub and top defs +// mln_trait_op_uminus_(test) tmp; /* int if no precise def and both sub and top defs */ // void* v = tmp; // } // { -// mln_trait_op_uminus_(test) tmp; float if only top def +// mln_trait_op_uminus_(test) tmp; /* float if only top def */ // void* v = tmp; // } - { - mln_trait_op_uminus_(test) tmp; // test if no def here (default is id, given for Object) - tmp.is_test(); - } +// { +// mln_trait_op_uminus_(test) tmp; // test if no def here (default is id, given for Object) +// tmp.is_test(); +// } } Index: tests/border_resize_sub_image.cc --- tests/border_resize_sub_image.cc (revision 1381) +++ tests/border_resize_sub_image.cc (working copy) @@ -70,9 +70,6 @@ mln_assertion( sub.has (point2d(2,2)) = false && sub.owns_(point2d(2,2)) = false ); - - - - /// Cannot resize a subimage => compilation error. - border::resize (sub, new_border); + // A subimage has no border so it cannot be resized => we get a compilation error as expected. + // border::resize(sub, new_border); } Index: tests/rle_image.cc --- tests/rle_image.cc (revision 1381) +++ tests/rle_image.cc (working copy) @@ -29,7 +29,7 @@ * * \brief Tests on mln::rle_image. */ -1 + #include <mln/core/image2d.hh> #include <mln/core/rle_image.hh> #include <mln/core/rle_encode.hh> Index: tests/h_vec.cc --- tests/h_vec.cc (revision 1381) +++ tests/h_vec.cc (working copy) @@ -62,7 +62,7 @@ point3d k; run_in_3d(k); - run_in_3d_h(k); + run_in_3d_h(k.to_h_vec()); { metal::vec<3,float> v; Index: tests/io_ppm.cc --- tests/io_ppm.cc (revision 1381) +++ tests/io_ppm.cc (working copy) @@ -31,7 +31,6 @@ */ #include <mln/core/image2d.hh> - #include <mln/value/rgb8.hh> #include <mln/io/ppm/load.hh> @@ -44,11 +43,7 @@ { using namespace mln; using value::rgb8; - using value::int_u8; - - image2d<rgb8> - lena = io::ppm::load("../img/lena.ppm"); + image2d<rgb8> lena = io::ppm::load("../img/lena.ppm"); io::ppm::save(lena, "out.ppm"); - } Index: tests/value_rgb8.cc --- tests/value_rgb8.cc (revision 1381) +++ tests/value_rgb8.cc (working copy) @@ -31,9 +31,9 @@ */ #include <mln/value/rgb8.hh> - #include <mln/literal/all.hh> + int main() { using namespace mln; @@ -48,23 +48,24 @@ v.red() = 0; v.green() = 1; v.blue() = 2; - value::int_u8_x3_t t = {0,1,2}; - rgb8 w( t ); + rgb8 c(0, 1, 2); - std::cout << w << std::endl; + std::cout << c << std::endl; std::cout << v << std::endl; - mln_assertion(w = w); - mln_assertion(w = v); + mln_assertion(c = c); + mln_assertion(c = v); v.green () = 255; std::cout << v << std::endl; - mln_assertion(v != w); + + mln_assertion(v != c); rgb<20> b = blue; std::cout << b << std::endl; - rgb<20> c = white; - std::cout << c << std::endl; + rgb<20> w = white; + std::cout << w << std::endl; + mln_assertion(b != w); } } Index: tests/trait_op_plus.cc --- tests/trait_op_plus.cc (revision 1381) +++ tests/trait_op_plus.cc (working copy) @@ -33,6 +33,7 @@ #include <mln/core/concept/image.hh> #include <mln/value/concept/all.hh> #include <mln/trait/op/plus.hh> +#include <mln/value/builtin/all.hh> namespace mln Index: tests/value_int_u8.cc --- tests/value_int_u8.cc (revision 1381) +++ tests/value_int_u8.cc (working copy) @@ -187,4 +187,5 @@ test_interop(int_u8, char, %, 4, 20); test_interop(int_u8, unsigned char, %, 4, 20); } + } Index: tests/value_graylevel.cc --- tests/value_graylevel.cc (revision 1381) +++ tests/value_graylevel.cc (working copy) @@ -32,12 +32,12 @@ * */ +#include <mln/value/graylevel.hh> +#include <mln/value/int_u8.hh> #include <mln/literal/black.hh> - #include <mln/literal/white.hh> -#include <mln/value/graylevel.hh> int main() @@ -47,6 +47,9 @@ using mln::literal::white; using mln::literal::black; + gl8 a = 255; + gl8 b = 255; + // Constructions { gl8 x; @@ -55,8 +58,12 @@ gl8 b(12); mln_assertion(a = b); - gl16 c = 2335; - gl8 d = c; +// gl16 c = 2335; +// gl8 d = c; +// mln_assertion(c = d); + + gl8 d = 250; + gl16 c = d; mln_assertion(c = d); gl8 e = gray(white); @@ -72,8 +79,8 @@ // Literals { - gl8 a = white; - gl16 b = white; + gl8 a(white); + gl16 b(white); mln_assertion(a = b); mln_assertion(a.value() = float(255)); @@ -102,9 +109,9 @@ mln_assertion(a.value() = float(0)); mln_assertion(b.value() = float(0)); - c = (black + black) / 2; - mln_assertion(c = black); - mln_assertion(c.value() = float(0)); +// c = (black + black) / 2; +// mln_assertion(c = black); +// mln_assertion(c.value() = float(0)); } // Assigment @@ -209,12 +216,12 @@ a = b; std::cout << "a.value() = " << int(a.value()) << std::endl; - std::cout << "should be " << (b.value() / 257) << std::endl; + std::cout << "should be " << (b.value() / 256) << std::endl; a = 42; a = a - b; - std::cout << int(a.value()) << ":" << (42 - b.value() / 257) << std::endl; - mln_assertion(a.value() = float((42 - b.value() / 257) )); + std::cout << int(a.value()) << ":" << (42 - b.value() / 256) << std::endl; + mln_assertion(a.value() = float((42 - b.value() / 256) )); a = 42; b = 16969; a -= b; @@ -274,8 +281,6 @@ } - - // Multiplication { gl8 a; @@ -357,10 +362,11 @@ } + // Not exhaustive - // gl8 a = white; - // gl16 b = white; + // gl8 a(white); + // gl16 b(white); // mln_assertion(a = b); // // mln_assertion(-a = -b); @@ -386,5 +392,5 @@ // mln_assertion(c.value() = float(255)); // } - // gray g = black; + // gray g(black); } Index: mln/trait/promote.hh --- mln/trait/promote.hh (revision 1381) +++ mln/trait/promote.hh (working copy) @@ -40,6 +40,7 @@ # define mln_trait_promote(T, U) typename mln::trait::promote< T , U >::ret +# define mln_trait_promote_(T, U) mln::trait::promote< T , U >::ret @@ -60,8 +61,9 @@ }; - /// Default case when the same type is involved twice: return this - /// type. + /// Default case when one type is involved twice: the promotion + /// type is the same as the input type (so actually there is no + /// promotion). template <typename T> struct set_binary_< promote, Object, T, Object, T > { @@ -69,68 +71,6 @@ }; - // Definitions for some built-ins. - - template <> - struct set_precise_binary_< promote, int, float > - { - typedef float ret; - }; - - template <> - struct set_precise_binary_< promote, float, int > - { - typedef float ret; - }; - - template <> - struct set_precise_binary_< promote, int, double > - { - typedef double ret; - }; - - template <> - struct set_precise_binary_< promote, double, int > - { - typedef double ret; - }; - - template <> - struct set_precise_binary_< promote, float, unsigned > - { - typedef float ret; - }; - - template <> - struct set_precise_binary_< promote, unsigned, float > - { - typedef float ret; - }; - - template <> - struct set_precise_binary_< promote, unsigned, double > - { - typedef double ret; - }; - - template <> - struct set_precise_binary_< promote, double, unsigned > - { - typedef double ret; - }; - - template <> - struct set_precise_binary_< promote, float, double > - { - typedef double ret; - }; - - template <> - struct set_precise_binary_< promote, double, float > - { - typedef double ret; - }; - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/solve.hh --- mln/trait/solve.hh (revision 1381) +++ mln/trait/solve.hh (working copy) @@ -39,6 +39,18 @@ # include <mln/core/category.hh> # include <mln/metal/equal.hh> # include <mln/metal/if.hh> +# include <mln/metal/ret.hh> + + +// FIXME: Just for the record (use it...) + +# ifndef MLN_DEBUG_TRAITS +# endif // ! MLN_DEBUG_TRAITS + + +# define mln_trait_unary(Name, T) typename mln::trait::solve_unary< Name, T >::ret + +# define mln_trait_binary(Name, T1, T2) typename mln::trait::solve_binary< Name, T1, T2 >::ret @@ -48,12 +60,51 @@ namespace trait { + /// Flag type for a not found trait. + struct not_found {}; /// Flag type for an undefined trait. - struct undefined; + struct undefined {}; + + /// Flag type for a trait that is multiply undefined. + struct multiply_defined {}; + + + + // Utility meta-function: from a category (meta) and a type, get the super category. + + namespace internal + { + + template < template <class> class Category, typename T, + typename Super_Category > + struct helper_super_category_; + + template < template <class> class Category, typename T, + template <class> class Super_Category > + struct helper_super_category_< Category, T, + Super_Category<void> > + { + typedef Super_Category<void> ret; // One super category: keep it. + }; + + template < template <class> class Category, typename T > + struct helper_super_category_< Category, T, + void* > // Meaning: several super categories exist, depending on T. + { + typedef typename mln::category< T >::super ret; // Specific call depending on T. + }; + + + template < template <class> class Category, typename T > + struct super_category_ // Entry. + { + typedef typename helper_super_category_< Category, T, + typename Category<void>::super >::ret ret; + }; + + } // end of namespace mln::trait::internal - /// Flag type for a trait multiply undefined. - struct multiply_defined; // Unary case. @@ -69,109 +120,133 @@ template < template <class> class Name, template <class> class Category_T, typename T > - struct set_unary_; // Fwd decl. - + struct set_unary_ + { + typedef undefined ret; + }; template < template <class> class Name, typename T > struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance. { - typedef undefined ret; + typedef not_found ret; }; + namespace internal { + // Fwd decls. template < template <class> class Name, - typename Super_Category_T, typename T > - struct set_unary_super_; + template <class> class Category_T, typename T > + struct get_unary_; + + + template < typename user_ret, /* != not_found and != undefined */ + template <class> class Name, + template <class> class Category_T, typename T > + struct helper_get_unary_ + { + typedef user_ret ret; // The user has defined 'ret' so we return it. + }; + template < template <class> class Name, - template <class> class Super_Category_T, typename T > - struct set_unary_super_< Name, Super_Category_T<void>, T > - : - public set_unary_< Name, Super_Category_T, T > + template <class> class Category_T, typename T > + struct helper_get_unary_< /* user_ret = */ not_found, + Name, Category_T, T > { + typedef not_found ret; // End of search due to a blocker; 'ret' is not found. }; - template < template <class> class Category, typename T, - typename Super_Category > - struct super_category_; + template < template <class> class Name, typename Super_Category, typename T > + struct helper_get_unary_rec_; - template < template <class> class Category, typename T, - template <class> class Super_Category > - struct super_category_< Category, T, - Super_Category<void> > - { - typedef Super_Category<void> ret; // One super category: keep it. + template < template <class> class Name, template <class> class Super_Category_T, typename T > + struct helper_get_unary_rec_< Name, Super_Category_T<void>, T > { + typedef typename get_unary_<Name, Super_Category_T, T>::ret ret; }; - template < template <class> class Category, typename T > - struct super_category_< Category, T, - void* > // Meaning: several super categories exist, depending on T. + template < template <class> class Name, + template <class> class Category_T, typename T > + struct helper_get_unary_< /* user_ret = */ undefined, + Name, Category_T, T > { - typedef typename mln::category< T >::super ret; // Specific call depending on T. + typedef typename internal::super_category_< Category_T, T >::ret super; + typedef typename helper_get_unary_rec_<Name, super, T>::ret ret; // No user ret definition => Recursion. }; - } // end of namespace mln::trait::internal - template < template <class> class Name, template <class> class Category_T, typename T > - struct set_unary_ - : - internal::set_unary_super_< Name, - typename internal::super_category_< Category_T, T, - typename Category_T<void>::super >::ret, - T > + struct get_unary_ { + typedef typename mln::trait::set_unary_<Name, Category_T, T>::ret user_ret; // First get 'user_ret' + typedef helper_get_unary_<user_ret, Name, Category_T, T> helper; // Set the helper to make a decision. + typedef mlc_ret(helper) ret; // Return. }; - namespace internal + template < typename precise_ret, + template <class> class Name, + template <class> class Category_T, typename T > + struct helper_choose_unary_wrt_ /* precise_ret != undefined */ { + typedef precise_ret ret; // -> A precise ret has been defined so it is it. + }; + + template < template <class> class Name, + template <class> class Category_T, typename T > + struct helper_choose_unary_wrt_< /* precise_ret = */ undefined, + Name, Category_T, T > + { + typedef typename get_unary_<Name, Category_T, T>::ret ret; // -> Go up into the category inheritance + // to fetch a ret from 'set_unary_'s. + }; template < template <class> class Name, template <class> class Category_T, typename T > struct helper_choose_unary_ { - typedef typename set_unary_<Name, Category_T,T>::ret category_ret; typedef typename set_precise_unary_<Name, T>::ret precise_ret; - typedef mlc_if( mlc_equal(precise_ret, - undefined), - category_ret, - precise_ret ) ret; + typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */ + Name, Category_T, T> helper; + typedef mlc_ret(helper) ret; }; + template < template <class> class Name, typename Category_T_void, typename T > - struct helper_solve_unary_; + struct helper_solve_unary_; // This helper changes the category plain type into the category meta type. template < template <class> class Name, - template <class> class Category_T, typename T > - struct helper_solve_unary_< Name, - Category_T<void>, T > : helper_choose_unary_< Name, - Category_T, T > + template <class> class Category_T, typename void_T, typename T > + struct helper_solve_unary_< Name, Category_T<void_T>, T > + : + helper_choose_unary_< Name, Category_T, T > // FIXME: typedef! { + // FIXME: Check that void_T is 'void' or 'void*'. }; - template < template <class> class Name, - template <class> class Category_T, typename T > - struct helper_solve_unary_< Name, - Category_T<void*>, T > : helper_choose_unary_< Name, - Category_T, T > - { - }; + // FIXME: Remove below. + +// template < template <class> class Name, +// template <class> class Category_T, typename T > +// struct helper_solve_unary_< Name, Category_T<void*>, T > +// : +// helper_choose_unary_< Name, Category_T, T > // FIXME: typedef! +// {}; } // end of namespace mln::trait::internal + // FIXME: Postfix solve_unary with a '-'(?) template < template <class> class Name, typename T > struct solve_unary : internal::helper_solve_unary_< Name, - typename mln::category<T>::ret, T > + typename mln::category<T>::ret, T > // FIXME: typedef! { }; @@ -188,11 +263,13 @@ typedef undefined ret; }; - template < template <class, class> class Name, template <class> class Category_L, typename L, template <class> class Category_R, typename R > - struct set_binary_; // Fwd decl. + struct set_binary_ + { + typedef undefined ret; + }; template < template <class, class> class Name, @@ -200,149 +277,263 @@ template <class> class Category_R, typename R > struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker. { - typedef undefined ret; + typedef not_found ret; }; - template < template <class, class> class Name, template <class> class Category_L, typename L, typename R > struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker. { - typedef undefined ret; + typedef not_found ret; }; - template < template <class, class> class Name, typename L, typename R > struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker. { - typedef undefined ret; + typedef not_found ret; }; + namespace internal { - // Nota bene: Seq means "super or equal". - template < template <class, class> class Name, - typename Seq_Category_L, typename L, - typename Seq_Category_R, typename R > - struct set_binary_super_; + // triplet_ret_ - template < template <class, class> class Name, - template <class> class Seq_Category_L, typename L, - template <class> class Seq_Category_R, typename R > - struct set_binary_super_< Name, - Seq_Category_L<void>, L, - Seq_Category_R<void>, R > - : - public virtual set_binary_< Name, - Seq_Category_L, L, - Seq_Category_R, R > + template < unsigned i_L_, unsigned i_R_, typename ret_ > + struct triplet_ { + typedef ret_ ret; }; - template < typename L_ret, typename R_ret > - struct merge_binary_ret_ + + // merge_triplets_ + + template < typename L_trp, typename R_trp > + struct merge_triplets_; + + template < unsigned L_i_L, unsigned L_i_R, typename L_ret, + unsigned R_i_L, unsigned R_i_R, typename R_ret > + struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>, + triplet_<R_i_L, R_i_R, R_ret> > { - typedef multiply_defined ret; + typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L; + typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R; + typedef metal::or_<take_L, take_R> ok; + typedef typename metal::if_< metal::and_<ok, take_L>, + triplet_<L_i_L, L_i_R, L_ret>, + typename metal::if_< metal::and_<ok, take_R>, + triplet_<R_i_L, R_i_R, R_ret>, + triplet_<0,0, not_found> >::ret >::ret ret; }; - template < typename LR_ret > - struct merge_binary_ret_< LR_ret, LR_ret > + template < unsigned i_L, unsigned i_R, typename LR_ret > + struct merge_triplets_< triplet_<i_L, i_R, LR_ret>, + triplet_<i_L, i_R, LR_ret> > { - typedef LR_ret ret; + typedef triplet_<i_L, i_R, LR_ret> ret; }; - template < typename L_ret > - struct merge_binary_ret_< L_ret, undefined > + + template < unsigned L_i_L, unsigned L_i_R, unsigned L_i_max, + unsigned R_i_L, unsigned R_i_R, unsigned R_i_max > + // L_i_max and R_i_max differ + struct helper_merge_triplets_same_ret_ { - typedef L_ret ret; + // The winning couple between L_* and R_* is the one which + // maximum index is the smallest; for instance, with: + // left branch giving L_i_L = 5 and L_i_R = 1 so L_i_max = 5 + // right branch giving L_i_L = 3 and L_i_R = 4 so R_i_max = 4 + // the right branch wins. + enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L), + i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) }; }; - template < typename R_ret > - struct merge_binary_ret_< undefined, R_ret > + template < unsigned L_i_L, unsigned L_i_R, unsigned i_max, + unsigned R_i_L, unsigned R_i_R > + // L_i_max is equal to R_i_max + struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max, + R_i_L, R_i_R, i_max > { - typedef R_ret ret; + // The winning couple is the one with the minimum index. + enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R), + R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R), + i_L = (L_i_min < R_i_min ? L_i_L : R_i_L), + i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) }; }; - template <> - struct merge_binary_ret_< undefined, undefined > + + template < unsigned L_i_L, unsigned L_i_R, typename LR_ret, + unsigned R_i_L, unsigned R_i_R > + struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>, + triplet_<R_i_L, R_i_R, LR_ret> > { - typedef undefined ret; + typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L : L_i_R), + R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper; + typedef triplet_<helper::i_L, helper::i_R, LR_ret> ret; }; - } // end of namespace mln::trait::internal + template < unsigned L_i_L, unsigned L_i_R, typename L_ret > + struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>, + triplet_< 0, 0, not_found> > + { + typedef triplet_<L_i_L, L_i_R, L_ret> ret; + }; + + template < unsigned R_i_L, unsigned R_i_R, typename R_ret > + struct merge_triplets_< triplet_< 0, 0, not_found>, + triplet_<R_i_L, R_i_R, R_ret> > + { + typedef triplet_<R_i_L, R_i_R, R_ret> ret; + }; + + template <> // To disambiguate. + struct merge_triplets_< triplet_<0, 0, not_found>, + triplet_<0, 0, not_found> > + { + typedef triplet_<0u,0u, not_found> ret; + }; + + // Fwd decl. template < template <class, class> class Name, - template <class> class Category_L, typename L, - template <class> class Category_R, typename R > - struct set_binary_ + unsigned i_L, template <class> class Category_L, typename L, + unsigned i_R, template <class> class Category_R, typename R > + struct get_binary_; + + + template < typename user_ret, /* != not_found and != undefined */ + template <class, class> class Name, + unsigned i_L, template <class> class Category_L, typename L, + unsigned i_R, template <class> class Category_R, typename R > + struct helper_get_binary_ + { + typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined 'ret' so we return it. + }; + + template < template <class, class> class Name, + unsigned i_L, template <class> class Category_L, typename L, + unsigned i_R, template <class> class Category_R, typename R > + struct helper_get_binary_< /* user_ret = */ not_found, + Name, i_L, Category_L, L, i_R, Category_R, R > + { + typedef triplet_< 0, 0, not_found > ret; // End of search due to a blocker; 'ret' is not found. + }; + + + template < template <class, class> class Name, // Nota bene: Seq means "super or equal". + unsigned i_L, typename Seq_Category_L, typename L, + unsigned i_R, typename Seq_Category_R, typename R > + struct helper_get_binary_rec_; + + template < template <class, class> class Name, + unsigned i_L, template <class> class Seq_Category_L, typename L, + unsigned i_R, template <class> class Seq_Category_R, typename R > + struct helper_get_binary_rec_< Name, i_L, Seq_Category_L<void>, L, i_R, Seq_Category_R<void>, R > { - // Construct a treillis in a static recursive way! + typedef typename get_binary_<Name, i_L, Seq_Category_L, L, i_R, Seq_Category_R, R>::ret ret; + }; - typedef typename internal::set_binary_super_< Name, - typename internal::super_category_< Category_L, - L, - typename Category_L<void>::super >::ret, - L, - Category_R<void>, - R >::ret - L_ret; - - typedef typename internal::set_binary_super_< Name, - Category_L<void>, - L, - typename internal::super_category_< Category_R, - R, - typename Category_R<void>::super >::ret, - R >::ret - R_ret; - typedef typename internal::merge_binary_ret_< L_ret, R_ret >::ret ret; - // FIXME: Do we need to handle this search with a priority? + template < template <class, class> class Name, + unsigned i_L, template <class> class Category_L, typename L, + unsigned i_R, template <class> class Category_R, typename R > + struct helper_get_binary_< /* user_ret = */ undefined, + Name, i_L,Category_L, L, i_R,Category_R, R > + { + // No user definition for 'ret' so treillis construction in a static recursive way. + + // FIXME: We *do* need to handle this search with a priority! // FIXME: for a result can be found in both branches... + + typedef typename super_category_< Category_L, L >::ret Super_Category_L; + typedef typename super_category_< Category_R, R >::ret Super_Category_R; + + typedef helper_get_binary_rec_< Name, + i_L + 1, Super_Category_L, L, + i_R, Category_R<void>, R > L_branch; + typedef mlc_ret(L_branch) L_trp; + + typedef helper_get_binary_rec_< Name, + i_L, Category_L<void>, L, + i_R + 1, Super_Category_R, R > R_branch; + typedef mlc_ret(R_branch) R_trp; + + typedef typename merge_triplets_< L_trp, R_trp >::ret ret; }; - namespace internal + template < template <class, class> class Name, + unsigned i_L, template <class> class Category_L, typename L, + unsigned i_R, template <class> class Category_R, typename R > + struct get_binary_ + { + typedef typename mln::trait::set_binary_<Name, Category_L,L, + Category_R,R>::ret user_ret; // First get 'user_ret' + typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L, + i_R,Category_R,R> helper; // Set the helper to make a decision. + typedef mlc_ret(helper) ret; // Return a triplet. + }; + + + template < typename precise_ret, + template <class, class> class Name, + template <class> class Category_L, typename L, + template <class> class Category_R, typename R > + struct helper_choose_binary_wrt_ /* precise_ret != undefined */ { + typedef precise_ret ret; // -> A precise ret has been defined so it is it. + }; + + template < template <class, class> class Name, + template <class> class Category_L, typename L, + template <class> class Category_R, typename R > + struct helper_choose_binary_wrt_< /* precise_ret = */ undefined, + Name, Category_L, L, Category_R, R > + { + typedef typename get_binary_< Name, + 0, Category_L, L, + 0, Category_R, R >::ret triplet; // Browse upwards the category inheritance + typedef mlc_ret(triplet) ret; // to fetch ret from 'get_binary_'s. + }; + template < template <class, class> class Name, template <class> class Category_L, typename L, template <class> class Category_R, typename R > struct helper_choose_binary_ { - typedef typename set_binary_<Name, Category_L,L, Category_R,R>::ret category_ret; - typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; - typedef mlc_if( mlc_equal(precise_ret, - undefined), - category_ret, - precise_ret ) ret; + typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined or not (?) */ + typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R> helper; + typedef mlc_ret(helper) ret; }; + template < template <class, class> class Name, typename Category_L_void, typename L, typename Category_R_void, typename R > struct helper_solve_binary_; template < template <class, class> class Name, - template <class> class Category_L, typename L, - template <class> class Category_R, typename R > + template <class> class Category_L, typename void_L, typename L, + template <class> class Category_R, typename void_R, typename R > struct helper_solve_binary_< Name, - Category_L<void>, L, - Category_R<void>, R > : helper_choose_binary_< Name, + Category_L<void_L>, L, + Category_R<void_R>, R > : helper_choose_binary_< Name, Category_L, L, Category_R, R > { + // FIXME: Check that void_L and void_R are 'void' or 'void*'. }; } // end of namespace mln::trait::internal + // FIXME: Postfix solve_binary with a '-'(?) template < template <class, class> class Name, typename L, typename R > Index: mln/trait/value_.hh --- mln/trait/value_.hh (revision 1381) +++ mln/trait/value_.hh (working copy) @@ -36,6 +36,7 @@ # include <iostream> # include <string> +# include <mln/metal/int.hh> # include <mln/metal/math/pow.hh> # include <mln/metal/if.hh> @@ -89,31 +90,6 @@ }; - template <unsigned n_bits, int card_ = 1> - struct value_integer_ - { - typedef metal::math::pow_int<2, n_bits> pow_; - - typedef metal::int_<n_bits> nbits; - typedef trait::value::nature::integer nature; - typedef trait::value::kind::data kind; - typedef metal::int_<pow_::value> card; - typedef mln_value_quant_from_card(card) quant; - typedef float sum; - }; - - template <unsigned n_bits> - struct value_integer_< n_bits, 0 > - { - typedef metal::int_<n_bits> nbits; - typedef trait::value::nature::integer nature; - typedef value::kind::data kind; - typedef metal::int_<0> card; - typedef value::quant::high quant; - typedef float sum; - }; - - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/op/times.hh --- mln/trait/op/times.hh (revision 1381) +++ mln/trait/op/times.hh (working copy) @@ -60,16 +60,6 @@ } // end of namespace mln::trait::op - - /// Default definition of op::times is given by the promote trait. - template <typename L, typename R> - struct set_binary_< op::times, Object, L, Object, R > - : - public promote< L, R > - { - }; - - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/op/postdec.hh --- mln/trait/op/postdec.hh (revision 0) +++ mln/trait/op/postdec.hh (revision 0) @@ -0,0 +1,64 @@ +// 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 MLN_TRAIT_OP_POSTDEC_HH +# define MLN_TRAIT_OP_POSTDEC_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_postdec(T) typename mln::trait::op::postdec< T >::ret +# define mln_trait_op_postdec_(T) mln::trait::op::postdec< T >::ret + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Object; + + + namespace trait + { + + namespace op + { + + template <typename T> + struct postdec : public solve_unary<postdec, T> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_POSTDEC_HH Index: mln/trait/op/div.hh --- mln/trait/op/div.hh (revision 0) +++ mln/trait/op/div.hh (revision 0) @@ -0,0 +1,60 @@ +// 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 MLN_TRAIT_OP_DIV_HH +# define MLN_TRAIT_OP_DIV_HH + +# include <mln/trait/promote.hh> + + +# define mln_trait_op_div(L, R) typename mln::trait::op::div< L , R >::ret +# define mln_trait_op_div_(L, R) mln::trait::op::div< L , R >::ret + + + +namespace mln +{ + + namespace trait + { + + namespace op + { + + template <typename L, typename R> + struct div : public solve_binary<div, L, R> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_DIV_HH Index: mln/trait/op/predec.hh --- mln/trait/op/predec.hh (revision 0) +++ mln/trait/op/predec.hh (revision 0) @@ -0,0 +1,64 @@ +// 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 MLN_TRAIT_OP_PREDEC_HH +# define MLN_TRAIT_OP_PREDEC_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_predec(T) typename mln::trait::op::predec< T >::ret +# define mln_trait_op_predec_(T) mln::trait::op::predec< T >::ret + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Object; + + + namespace trait + { + + namespace op + { + + template <typename T> + struct predec : public solve_unary<predec, T> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_PREDEC_HH Index: mln/trait/op/plus.hh --- mln/trait/op/plus.hh (revision 1381) +++ mln/trait/op/plus.hh (working copy) @@ -60,16 +60,6 @@ } // end of namespace mln::trait::op - - /// Default definition of op::plus is given by the promote trait. - template < typename L, typename R > - struct set_binary_< op::plus, Object, L, Object, R > - : - public promote< L, R > - { - }; - - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/op/neq.hh --- mln/trait/op/neq.hh (revision 0) +++ mln/trait/op/neq.hh (revision 0) @@ -0,0 +1,60 @@ +// 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 MLN_TRAIT_OP_NEQ_HH +# define MLN_TRAIT_OP_NEQ_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_neq(L, R) typename mln::trait::op::neq< L , R >::ret +# define mln_trait_op_neq_(L, R) mln::trait::op::neq< L , R >::ret + + + +namespace mln +{ + + namespace trait + { + + namespace op + { + + template <typename L, typename R> + struct neq : public solve_binary<neq, L, R> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_NEQ_HH Index: mln/trait/op/eq.hh --- mln/trait/op/eq.hh (revision 0) +++ mln/trait/op/eq.hh (revision 0) @@ -0,0 +1,68 @@ +// 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 MLN_TRAIT_OP_EQ_HH +# define MLN_TRAIT_OP_EQ_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_eq(L, R) typename mln::trait::op::eq< L , R >::ret +# define mln_trait_op_eq_(L, R) mln::trait::op::eq< L , R >::ret + + + +namespace mln +{ + + namespace trait + { + + namespace op + { + + template <typename L, typename R> + struct eq : public solve_binary<eq, L, R> + { + }; + + } // end of namespace mln::trait::op + + +// /// Default definition of op::eq is 'bool'. +// template <typename L, typename R> +// struct set_binary_< op::eq, Object, L, Object, R > +// { +// typedef bool ret; +// }; + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_EQ_HH Index: mln/trait/op/all.hh --- mln/trait/op/all.hh (revision 1381) +++ mln/trait/op/all.hh (working copy) @@ -49,9 +49,23 @@ # include <mln/trait/op/plus.hh> -# include <mln/trait/op/times.hh> # include <mln/trait/op/minus.hh> +# include <mln/trait/op/times.hh> +# include <mln/trait/op/div.hh> +# include <mln/trait/op/mod.hh> + +# include <mln/trait/op/uplus.hh> # include <mln/trait/op/uminus.hh> +# include <mln/trait/op/preinc.hh> +# include <mln/trait/op/postinc.hh> +# include <mln/trait/op/predec.hh> +# include <mln/trait/op/postdec.hh> + +# include <mln/trait/op/eq.hh> +# include <mln/trait/op/neq.hh> + +// FIXME: eq, less, ... + and, xor, ... + #endif // ! MLN_TRAIT_OP_ALL_HH Index: mln/trait/op/uplus.hh --- mln/trait/op/uplus.hh (revision 0) +++ mln/trait/op/uplus.hh (revision 0) @@ -0,0 +1,64 @@ +// 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 MLN_TRAIT_OP_UPLUS_HH +# define MLN_TRAIT_OP_UPLUS_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_uplus(T) typename mln::trait::op::uplus< T >::ret +# define mln_trait_op_uplus_(T) mln::trait::op::uplus< T >::ret + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Object; + + + namespace trait + { + + namespace op + { + + template <typename T> + struct uplus : public solve_unary<uplus, T> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_UPLUS_HH Index: mln/trait/op/minus.hh --- mln/trait/op/minus.hh (revision 1381) +++ mln/trait/op/minus.hh (working copy) @@ -60,16 +60,6 @@ } // end of namespace mln::trait::op - - /// Default definition of op::minus is given by the promote trait. - template <typename L, typename R> - struct set_binary_< op::minus, Object, L, Object, R > - : - public promote< L, R > - { - }; - - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/op/mod.hh --- mln/trait/op/mod.hh (revision 0) +++ mln/trait/op/mod.hh (revision 0) @@ -0,0 +1,60 @@ +// 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 MLN_TRAIT_OP_MOD_HH +# define MLN_TRAIT_OP_MOD_HH + +# include <mln/trait/promote.hh> + + +# define mln_trait_op_mod(L, R) typename mln::trait::op::mod< L , R >::ret +# define mln_trait_op_mod_(L, R) mln::trait::op::mod< L , R >::ret + + + +namespace mln +{ + + namespace trait + { + + namespace op + { + + template <typename L, typename R> + struct mod : public solve_binary<mod, L, R> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_MOD_HH Index: mln/trait/op/postinc.hh --- mln/trait/op/postinc.hh (revision 0) +++ mln/trait/op/postinc.hh (revision 0) @@ -0,0 +1,64 @@ +// 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 MLN_TRAIT_OP_POSTINC_HH +# define MLN_TRAIT_OP_POSTINC_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_postinc(T) typename mln::trait::op::postinc< T >::ret +# define mln_trait_op_postinc_(T) mln::trait::op::postinc< T >::ret + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Object; + + + namespace trait + { + + namespace op + { + + template <typename T> + struct postinc : public solve_unary<postinc, T> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_POSTINC_HH Index: mln/trait/op/uminus.hh --- mln/trait/op/uminus.hh (revision 1381) +++ mln/trait/op/uminus.hh (working copy) @@ -63,15 +63,6 @@ } // end of namespace mln::trait::op - - /// Default definition of op::uminus is the input type itself. - template <typename T> - struct set_unary_< op::uminus, Object, T > - { - typedef T ret; - }; - - } // end of namespace mln::trait } // end of namespace mln Index: mln/trait/op/preinc.hh --- mln/trait/op/preinc.hh (revision 0) +++ mln/trait/op/preinc.hh (revision 0) @@ -0,0 +1,64 @@ +// 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 MLN_TRAIT_OP_PREINC_HH +# define MLN_TRAIT_OP_PREINC_HH + +# include <mln/trait/solve.hh> + + +# define mln_trait_op_preinc(T) typename mln::trait::op::preinc< T >::ret +# define mln_trait_op_preinc_(T) mln::trait::op::preinc< T >::ret + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Object; + + + namespace trait + { + + namespace op + { + + template <typename T> + struct preinc : public solve_unary<preinc, T> + { + }; + + } // end of namespace mln::trait::op + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_TRAIT_OP_PREINC_HH Index: mln/core/macros.hh --- mln/core/macros.hh (revision 1381) +++ mln/core/macros.hh (working copy) @@ -78,6 +78,7 @@ /// Shortcut to access the equivalent type associated to T. # define mln_equiv(T) typename T::equiv +# define mln_equiv_(T) T::equiv // f Index: mln/core/point.hh --- mln/core/point.hh (revision 1381) +++ mln/core/point.hh (working copy) @@ -149,8 +149,8 @@ operator typename internal::point_to_<M, C>::metal_vec () const; operator metal::vec<M::dim, float> () const; - /// Hook to homogene coordinate. - operator typename internal::point_to_<M, C>::h_vec () const; + /// Transform to point in homogene coordinate system. + h_vec<M::dim, C> to_h_vec() const; protected: metal::vec<M::dim, C> coord_; @@ -303,9 +303,13 @@ } template <typename M, typename C> - point_<M,C>::operator typename internal::point_to_<M, C>::h_vec () const + h_vec<M::dim, C> point_<M,C>::to_h_vec() const { - return coord_.to_h_vec(); + h_vec<M::dim, C> tmp; + for (unsigned i = 0; i < dim; ++i) + tmp[i] = coord_[i]; + tmp[M::dim] = 1; + return tmp; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/category.hh --- mln/core/category.hh (revision 1381) +++ mln/core/category.hh (working copy) @@ -29,6 +29,7 @@ # define MLN_CORE_CATEGORY_HH /*! \file mln/core/category.hh + * * \brief Definition of the category holder type. */ Index: mln/core/ops.hh --- mln/core/ops.hh (revision 1381) +++ mln/core/ops.hh (working copy) @@ -29,18 +29,71 @@ # define MLN_CORE_OPS_HH /*! \file mln/core/ops.hh - * \brief Definitions of some operators. + * + * \brief Definitions of some default implementations for operators. + * + * \todo Complete those definitions (...) + Overload for const (?) */ # include <mln/core/concept/object.hh> -# include <mln/core/exact.hh> -# include <mln/value/builtin.hh> +# include <mln/metal/converts_to.hh> # include <mln/trait/op/all.hh> + namespace mln { + // Fwd decls. + namespace literal { struct zero_t; struct one_t; } + + + namespace trait + { + + // For unary operators. + + + /// Default definition of op::uplus trait. + template <typename O> + struct set_unary_< op::uplus, Object,O > { typedef O ret; }; + + /// Default definition of op::uminus trait. + template <typename O> + struct set_unary_< op::uminus, Object,O > { typedef mln_trait_op_minus(O, O) ret; }; + + /// Default definition of op::preinc trait. + template <typename O> + struct set_unary_< op::preinc, Object,O > { typedef O& ret; }; + + /// Default definition of op::preinc trait. + template <typename O> + struct set_unary_< op::predec, Object,O > { typedef O& ret; }; + + /// Default definition of op::postinc trait. + template <typename O> + struct set_unary_< op::postinc, Object,O > { typedef O ret; }; + + /// Default definition of op::postinc trait. + template <typename O> + struct set_unary_< op::postdec, Object,O > { typedef O ret; }; + + + + // For binary operators. + + template <typename O1, typename O2> + struct set_binary_< op::eq, Object,O1, Object,O2 > { typedef bool ret; }; + + template <typename O1, typename O2> + struct set_binary_< op::neq, Object,O1, Object,O2 > { typedef bool ret; }; + + // FIXME: Same for the other definitions below... + + + } // end of mln::trait + + /*! \brief General definition of the "not equal to" operator. * @@ -52,7 +105,8 @@ * in milena when applying on a couple of mln::Object. */ template <typename O1, typename O2> - bool operator!=(const Object<O1>& lhs, const Object<O2>& rhs); + mln_trait_op_neq(O1, O2) + operator!=(const Object<O1>& lhs, const Object<O2>& rhs); /*! \brief General definition of the "greater than" operator. @@ -112,95 +166,190 @@ O operator--(Object<O>& rhs, int); - // Operator +. - - // FIXME HERE + /* \brief Default definition of the pre-incrementation operator. + * + * It relies on "+ literal::one". + */ + template <typename O> + O& operator++(Object<O>& rhs); -// namespace trait { -// template < typename L, typename R > -// struct set_binary_< op::plus, Built_In, L, Object, R > -// { -// typedef mln_trait_op_plus(R, L) -// }; + /* \brief Default definition of the pre-decrementation operator. + * + * It relies on "- literal::one". + */ + template <typename O> + O& operator--(Object<O>& rhs); -// } - // FIXME: Doc! + /* \brief Default definitions of the "unary plus" operator. + * + * \param[in] rhs An object + * \return A copy of \p rhs. + */ template <typename O> - mln_trait_op_plus(O, int) - operator+(int lhs, const Object<O>& rhs) - { - return exact(rhs) + lhs; - } + O operator+(const Object<O>& rhs); + - // FIXME: Doc! + /* \brief Default definition of the "unary minus" operator. + * + * \param[in] rhs An object + * \return 0 - \p rhs. + * + * It relies on "O(literal::zero) - rhs". + */ template <typename O> - mln_trait_op_plus(O, unsigned) - operator+(unsigned lhs, const Object<O>& rhs) + mln_trait_op_minus(O, O) + operator-(const Object<O>& rhs); + + + /* \brief Default definition of the "plus equal" operator. + * + * \param[in,out] lhs The target object. + * \param[in] rhs The auxiliary object. + * \return The target object \p lhs once modified. + * + * It relies on "lhs = L(lhs) + rhs". + */ + template <typename L, typename R> + L& + operator+=(Object<L>& lhs, const Object<R>& rhs); + + + /* \brief Default definition of the "minus equal" operator. + * + * \param[in,out] lhs The target object. + * \param[in] rhs The auxiliary object. + * \return The target object \p lhs once modified. + * + * It relies on "lhs = L(lhs) - rhs". + */ + template <typename L, typename R> + L& + operator-=(Object<L>& lhs, const Object<R>& rhs); + + + /* \brief Default definition of the "times equal" operator. + * + * \param[in,out] lhs The target object. + * \param[in] rhs The auxiliary object. + * \return The target object \p lhs once modified. + * + * It relies on "lhs = L(lhs) * rhs". + */ + template <typename L, typename R> + L& + operator*=(Object<L>& lhs, const Object<R>& rhs); + + + /* \brief Default definition of the "div equal" operator. + * + * \param[in,out] lhs The target object. + * \param[in] rhs The auxiliary object. + * \return The target object \p lhs once modified. + * + * It relies on "lhs = L(lhs) / rhs". + */ + template <typename L, typename R> + L& + operator/=(Object<L>& lhs, const Object<R>& rhs); + + + /* \brief Default definition of the "mod equal" operator. + * + * \param[in,out] lhs The target object. + * \param[in] rhs The auxiliary object. + * \return The target object \p lhs once modified. + * + * It relies on "lhs = L(lhs) % rhs". + */ + template <typename L, typename R> + L& + operator%=(Object<L>& lhs, const Object<R>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + // Plus equal. + + template <typename L, typename R> + L& + operator+=(Object<L>& lhs, const Object<R>& rhs) { - return exact(rhs) + lhs; + typedef mln_trait_op_plus(L, R) P; + mlc_converts_to(P, L)::check(); + return exact(lhs) = exact(lhs) + exact(rhs); } - // FIXME: Doc! - template <typename O> - mln_trait_op_plus(O, float) - operator+(float lhs, const Object<O>& rhs) + // Minus equal. + + template <typename L, typename R> + L& + operator-=(Object<L>& lhs, const Object<R>& rhs) { - return exact(rhs) + lhs; + typedef mln_trait_op_minus(L, R) M; + mlc_converts_to(M, L)::check(); + return exact(lhs) = exact(lhs) - exact(rhs); } - // FIXME: Doc! - template <typename O> - mln_trait_op_plus(O, double) - operator+(double lhs, const Object<O>& rhs) + // Times equal. + + template <typename L, typename R> + L& + operator*=(Object<L>& lhs, const Object<R>& rhs) { - return exact(rhs) + lhs; + typedef mln_trait_op_times(L, R) T; + mlc_converts_to(T, L)::check(); + return exact(lhs) = exact(lhs) * exact(rhs); } + // Div equal. - // Operator *. - - // FIXME: Doc! - template <typename O> - mln_trait_op_times(O, unsigned) - operator*(unsigned lhs, const Object<O>& rhs) + template <typename L, typename R> + L& + operator/=(Object<L>& lhs, const Object<R>& rhs) { - return exact(rhs) * lhs; + typedef mln_trait_op_div(L, R) D; + mlc_converts_to(D, L)::check(); + return exact(lhs) = exact(lhs) / exact(rhs); } - // FIXME: Doc! - template <typename O> - mln_trait_op_times(O, int) - operator*(int lhs, const Object<O>& rhs) + // Mod equal. + + template <typename L, typename R> + L& + operator%=(Object<L>& lhs, const Object<R>& rhs) { - // FIXME HERE: Activate: std::cout << "call(int * Object)" << std::endl; - // FIXME HERE: Change below to '* value::scalar(lhs)': - return exact(rhs) * lhs; + typedef mln_trait_op_mod(L, R) M; + mlc_converts_to(M, L)::check(); + return exact(lhs) = exact(lhs) % exact(rhs); } - // FIXME: Doc! + // Unary plus. + template <typename O> - mln_trait_op_times(O, float) - operator*(float lhs, const Object<O>& rhs) + O + operator+(const Object<O>& rhs) { - return exact(rhs) * lhs; + return exact(rhs); // Cpy. } - // FIXME: Doc! + // Unary minus. + template <typename O> - mln_trait_op_times(O, double) - operator*(double lhs, const Object<O>& rhs) + mln_trait_op_minus(O, O) + operator-(const Object<O>& rhs) { - return exact(rhs) * lhs; + mlc_converts_to(literal::zero_t, O)::check(); + literal::zero_t* p_zero; + return O(*p_zero) - exact(rhs); } - - -# ifndef MLN_INCLUDE_ONLY + // Post-incrementation. template <typename O> - O operator++(Object<O>& rhs, int) + O + operator++(Object<O>& rhs, int) { O tmp(exact(rhs)); // Copy. ++exact(rhs); // Pre-inc. @@ -208,8 +357,11 @@ return tmp; } + // Post-decrementation. + template <typename O> - O operator--(Object<O>& rhs, int) + O + operator--(Object<O>& rhs, int) { O tmp(exact(rhs)); // Copy. --exact(rhs); // Pre-dec. @@ -217,8 +369,33 @@ return tmp; } + // Pre-decrementation. + + template <typename O> + O& + operator--(Object<O>& rhs) + { + literal::one_t* p_one; + exact(rhs) -= *p_one; + return exact(rhs); + } + + // Pre-incrementation. + + template <typename O> + O& + operator++(Object<O>& rhs) + { + literal::one_t* p_one; + exact(rhs) += *p_one; + return exact(rhs); + } + + // Not equal to. + template <typename O1, typename O2> - bool operator!=(const Object<O1>& lhs, const Object<O2>& rhs) + mln_trait_op_neq(O1, O2) + operator!=(const Object<O1>& lhs, const Object<O2>& rhs) { return ! (exact(lhs) = exact(rhs)); } Index: mln/core/concept/object.hh --- mln/core/concept/object.hh (revision 1381) +++ mln/core/concept/object.hh (working copy) @@ -43,6 +43,7 @@ # include <mln/trace/all.hh> # include <mln/metal/is_a.hh> # include <mln/metal/is.hh> +# include <mln/metal/ret.hh> /*! \namespace mln @@ -108,8 +109,7 @@ # include <mln/core/exact.hh> -//# include <mln/literal/zero.hh> -# include <mln/core/ops.hh> // FIXME: Read FIXME in mln/metal/binary_arith_trait.hh! +# include <mln/core/ops.hh> #endif // ! MLN_CORE_CONCEPT_OBJECT_HH Index: mln/core/concept/value.hh --- mln/core/concept/value.hh (revision 1381) +++ mln/core/concept/value.hh (working copy) @@ -63,6 +63,8 @@ /* typedef enc; // encoding type typedef equiv; // equivalent type + + equiv to_equiv() const; // go to equivalent value */ protected: @@ -78,6 +80,9 @@ { typedef mln_enc(E) enc; typedef mln_equiv(E) equiv; + // FIXME HERE +// equiv (E::*m)() const = & E::to_equiv; +// m = 0; } # endif // ! MLN_INCLUDE_ONLY @@ -86,7 +91,6 @@ # include <mln/value/cast.hh> -# include <mln/value/builtin.hh> #endif // ! MLN_CORE_CONCEPT_VALUE_HH Index: mln/literal/ops.hh --- mln/literal/ops.hh (revision 1381) +++ mln/literal/ops.hh (working copy) @@ -33,52 +33,195 @@ */ # include <mln/core/concept/literal.hh> +# include <mln/trait/all.hh> +# include <mln/metal/equal.hh> +# include <mln/metal/converts_to.hh> namespace mln { + // Arithmetical operators. + + template <typename O, typename L> + mln_trait_op_plus(O, O) + operator+(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + mln_trait_op_plus(O, O) + operator+(const Literal<L>& lhs, const Object<O>& rhs); + + template <typename O, typename L> + mln_trait_op_minus(O, O) + operator-(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + mln_trait_op_minus(O, O) + operator-(const Literal<L>& lhs, const Object<O>& rhs); + + template <typename O, typename L> + mln_trait_op_times(O, O) + operator*(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + mln_trait_op_times(O, O) + operator*(const Literal<L>& lhs, const Object<O>& rhs); + + template <typename O, typename L> + mln_trait_op_div(O, O) + operator/(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + mln_trait_op_div(O, O) + operator/(const Literal<L>& lhs, const Object<O>& rhs); + + template <typename O, typename L> + mln_trait_op_mod(O, O) + operator%(const Object<O>& lhs, const Literal<L>& rhs); + + template <typename L, typename O> + mln_trait_op_mod(O, O) + operator%(const Literal<L>& lhs, const Object<O>& rhs); + + + // Operator equal. + template <typename O, typename L> - bool operator=(const Object<O>& lhs, const Literal<L>& rhs); + mln_trait_op_eq(O, O) + operator=(const Object<O>& lhs, const Literal<L>& rhs); template <typename L, typename O> - bool operator=(const Literal<L>& lhs, const Object<O>& rhs); + mln_trait_op_eq(O, O) + operator=(const Literal<L>& lhs, const Object<O>& rhs); template <typename L1, typename L2> bool operator=(const Literal<L1>& lhs, const Literal<L2>& rhs); - template <typename L> - bool operator=(const Literal<L>& lhs, const Literal<L>& rhs); - - // FIXME: Add other operators... + // FIXME: ... # ifndef MLN_INCLUDE_ONLY + // FIXME: Static assertion code de-activated because when O's ctor + // is explicit from literal the metal program does not compile... + + + // Op + + template <typename O, typename L> - bool operator=(const Object<O>& lhs, const Literal<L>& rhs) + mln_trait_op_plus(O, O) + operator+(const Object<O>& lhs, const Literal<L>& rhs) { - return exact(lhs) = O(exact(rhs)); + // mlc_converts_to(L, O)::check(); + return exact(lhs) + O(exact(rhs)); } template <typename L, typename O> - bool operator=(const Literal<L>& lhs, const Object<O>& rhs) + mln_trait_op_plus(O, O) + operator+(const Literal<L>& lhs, const Object<O>& rhs) { - return rhs = lhs; + // mlc_converts_to(L, O)::check(); + return O(exact(lhs)) + exact(rhs); } - template <typename L1, typename L2> - bool operator=(const Literal<L1>&, const Literal<L2>&) + // Op - + + template <typename O, typename L> + mln_trait_op_minus(O, O) + operator-(const Object<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) - O(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_minus(O, O) + operator-(const Literal<L>& lhs, const Object<O>& rhs) + { + // mlc_converts_to(L, O)::check(); + return O(exact(lhs)) - exact(rhs); + } + + // Op * + + template <typename O, typename L> + mln_trait_op_times(O, O) + operator*(const Object<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) * O(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_times(O, O) + operator*(const Literal<L>& lhs, const Object<O>& rhs) + { + // mlc_converts_to(L, O)::check(); + return O(exact(lhs)) * exact(rhs); + } + + // Op / + + template <typename O, typename L> + mln_trait_op_div(O, O) + operator/(const Object<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) / O(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_div(O, O) + operator/(const Literal<L>& lhs, const Object<O>& rhs) + { + // mlc_converts_to(L, O)::check(); + return O(exact(lhs)) / exact(rhs); + } + + // Op % + + template <typename O, typename L> + mln_trait_op_mod(O, O) + operator%(const Object<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) % O(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_mod(O, O) + operator%(const Literal<L>& lhs, const Object<O>& rhs) { - return false; + // mlc_converts_to(L, O)::check(); + return O(exact(lhs)) % exact(rhs); } - template <typename L> - bool operator=(const Literal<L>&, const Literal<L>&) + + // Op = + + template <typename O, typename L> + mln_trait_op_eq(O, O) + operator=(const Object<O>& lhs, const Literal<L>& rhs) + { + // mlc_converts_to(L, O)::check(); + return exact(lhs) = O(exact(rhs)); + } + + template <typename L, typename O> + mln_trait_op_eq(O, O) + operator=(const Literal<L>& lhs, const Object<O>& rhs) + { + // mlc_converts_to(L, O)::check(); + return rhs = lhs; + } + + template <typename L1, typename L2> + bool + operator=(const Literal<L1>&, const Literal<L2>&) { - return true; + return mlc_equal(L1, L2)::value; } # endif // ! MLN_INCLUDE_ONLY Index: mln/metal/mat.hh --- mln/metal/mat.hh (revision 1381) +++ mln/metal/mat.hh (working copy) @@ -41,7 +41,6 @@ # include <mln/core/contract.hh> # include <mln/trait/all.hh> # include <mln/value/props.hh> -# include <mln/value/concept/all.hh> # include <mln/metal/vec.hh> Index: mln/metal/ret.hh --- mln/metal/ret.hh (revision 0) +++ mln/metal/ret.hh (revision 0) @@ -0,0 +1,43 @@ +// 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 MLN_METAL_RET_HH +# define MLN_METAL_RET_HH + +/*! \file mln/metal/ret.hh + * + * \brief Definition of a macro to access 'ret'. + */ + + +// FIXME: Doc! + +# define mlc_ret(T) typename T::ret +# define mlc_ret_(T) T::ret + + +#endif // ! MLN_METAL_RET_HH Index: mln/metal/math/pow.hh --- mln/metal/math/pow.hh (revision 1381) +++ mln/metal/math/pow.hh (working copy) @@ -94,10 +94,9 @@ struct pow; template <int x, int n> - struct pow< int_<x>, int_<n> > : pow_int<x, n> + struct pow< int_<x>, int_<n> > { - typedef pow_int<x, n> super_; - typedef int_<super_::value> ret; + typedef int_< pow_int<x, n>::value > ret; }; Index: mln/metal/math/max.hh --- mln/metal/math/max.hh (revision 0) +++ mln/metal/math/max.hh (revision 0) @@ -0,0 +1,77 @@ +// 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 MLN_METAL_MATH_MAX_HH +# define MLN_METAL_MATH_MAX_HH + +/*! \file mln/metal/math/max.hh + * + * \brief Definition of the 'max' static function. + */ + +# include <mln/metal/bool.hh> +# include <mln/metal/int.hh> + + +namespace mln +{ + + namespace metal + { + + namespace math + { + + // max_int<x, y> + + template <int x, int y> + struct max_int + { + enum { value = (x > y ? x : y) }; + }; + + + // max<X, Y> + + template <typename X, typename Y> + struct max; + + template <int x, int y> + struct max< int_<x>, int_<y> > + { + typedef int_< max_int<x, y>::value > ret; + }; + + + } // end of namespace mln::metal::math + + } // end of namespace mln::metal + +} // end of namespace mln + + +#endif // ! MLN_METAL_MATH_MAX_HH Index: mln/metal/math/all.hh --- mln/metal/math/all.hh (revision 1381) +++ mln/metal/math/all.hh (working copy) @@ -55,6 +55,7 @@ # include <mln/metal/math/pow.hh> # include <mln/metal/math/sqrt.hh> +# include <mln/metal/math/max.hh> // ... Index: mln/metal/math/sqrt.hh --- mln/metal/math/sqrt.hh (revision 1381) +++ mln/metal/math/sqrt.hh (working copy) @@ -96,10 +96,9 @@ struct sqrt; template <int n> - struct sqrt< int_<n> > : sqrt_int<n> + struct sqrt< int_<n> > { - typedef sqrt_int<n> super_; - typedef int_<super_::value> ret; + typedef int_< sqrt_int<n>::value > ret; }; Index: mln/metal/vec.hh --- mln/metal/vec.hh (revision 1381) +++ mln/metal/vec.hh (working copy) @@ -38,10 +38,13 @@ # include <cmath> # include <mln/core/concept/object.hh> + # include <mln/trait/all.hh> # include <mln/value/props.hh> # include <mln/fun/i2v/all_to.hh> -# include <mln/value/concept/all.hh> +# include <mln/debug/format.hh> + +# include <mln/value/ops.hh> // FIXME: Document. @@ -150,7 +153,10 @@ vec(); + /// \{ Constructors/assignments with literal zero. vec(const literal::zero_t&); + vec& operator=(const literal::zero_t&); + /// \} vec(const vec<n, T>& rhs); @@ -171,7 +177,7 @@ void set_all(const T& val); - T sprod(const vec<n, T>& rhs) const; + T sprod(const vec<n, T>& rhs) const; // FIXME: Return is not T. unsigned size() const; @@ -194,50 +200,40 @@ namespace trait { - // promote + // For unary traits. - template <unsigned n, typename T, typename U> - struct set_precise_binary_<promote, metal::vec<n, T>, metal::vec<n, U> > + template < template <class> class Name, + unsigned n, typename T > + struct set_precise_unary_< Name, metal::vec<n, T> > { - typedef metal::vec<n, mln_trait_promote(T, U)> ret; + typedef mln_trait_unary(Name, T) V; + typedef metal::vec<n, V> ret; }; + // For binary traits. - // vec + vec - - template <unsigned n, typename T, typename U> - struct set_precise_binary_<op::plus, metal::vec<n, T>, metal::vec<n, U> > + template < template <class, class> class Name, + unsigned n, typename T, + typename U > + struct set_precise_binary_< Name, + metal::vec<n, T>, metal::vec<n, U> > { - typedef metal::vec<n, mln_trait_op_plus(T, U)> ret; + typedef mln_trait_binary(Name, T, U) V; + typedef metal::vec<n, V> ret; }; - // FIXME: + vec ! - - // vec - vec - - template <unsigned n, typename T, typename U> - struct set_precise_binary_<op::minus, metal::vec<n, T>, metal::vec<n, U> > + template < template <class, class> class Name, + unsigned n, typename T, + typename S > + struct set_precise_binary_< Name, + metal::vec<n, T>, mln::value::scalar_<S> > { - typedef metal::vec<n, mln_trait_op_minus(T, U)> ret; + typedef mln_trait_binary(Name, T, S) V; + typedef metal::vec<n, V> ret; }; - // - vec + // FIXME: What about scalar * vec!!! - template <unsigned n, typename T> - struct set_precise_unary_<op::uminus, metal::vec<n, T> > - { - typedef metal::vec<n, mln_trait_op_uminus(T)> ret; - }; - - // vec * s - - template <unsigned n, typename T, typename S> - struct set_precise_binary_<op::times, metal::vec<n, T>, S > - { - typedef metal::vec<n, mln_trait_op_times(T, S)> ret; - }; - - // FIXME: vec / s } // end of namespace mln::trait @@ -266,52 +262,33 @@ template <unsigned n, typename T, typename U> bool operator=(const vec<n,T>& lhs, const vec<n,U>& rhs); - template <unsigned n, typename T, typename U> - bool operator!=(const vec<n,T>& lhs, const vec<n,U>& rhs); - // + template <unsigned n, typename T, typename U> - vec<n,T>& - operator+=(vec<n,T>& lhs, const vec<n,U>& rhs); - - template <unsigned n, typename T, typename U> vec<n, mln_trait_op_plus(T,U)> operator+(const vec<n,T>& lhs, const vec<n,U>& rhs); // - template <unsigned n, typename T, typename U> - vec<n,T>& - operator-=(vec<n,T>& lhs, const vec<n,U>& rhs); - - template <unsigned n, typename T, typename U> vec<n, mln_trait_op_minus(T,U)> operator-(const vec<n,T>& lhs, const vec<n,U>& rhs); - template <unsigned n, typename T> - vec<n, mln_trait_op_uminus(T)> - operator-(const vec<n,T>& lhs); +// template <unsigned n, typename T> +// vec<n, mln_trait_op_uminus(T)> +// operator-(const vec<n,T>& lhs); // * template <unsigned n, typename T, typename S> - vec<n,T>& - operator*=(vec<n,T>& lhs, const S& s); - - template <unsigned n, typename T, typename S> vec<n, mln_trait_op_times(T,S)> - operator*(const vec<n,T>& lhs, const S& s); + operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s); // / template <unsigned n, typename T, typename S> - vec<n,T>& - operator/=(vec<n,T>& lhs, const S& s); - - template <unsigned n, typename T, typename S> - vec<n, mln_trait_op_times(T,S)> // FIXME: Use div instead! - operator/(const vec<n,T>& lhs, const S& s); + vec<n, mln_trait_op_div(T, S)> + operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s); // << @@ -319,14 +296,6 @@ std::ostream& operator<<(std::ostream& ostr, const vec<n,T>& v); - template <unsigned n> - std::ostream& - operator<<(std::ostream& ostr, const vec<n,unsigned char>& v); - - template <unsigned n> - std::ostream& - operator<<(std::ostream& ostr, const vec<n,signed char>& v); - // vprod // FIXME: Generalize... template <typename T, typename U> @@ -348,6 +317,14 @@ } template <unsigned n, typename T> + vec<n,T>& + vec<n,T>::operator=(const literal::zero_t&) + { + this->set_all(0); + return *this; + } + + template <unsigned n, typename T> vec<n,T>::vec(const vec<n,T>& rhs) : super_() { @@ -422,7 +399,6 @@ return *this; } - template <unsigned n, typename T> template <typename F> vec<n, T>::vec(const Function_i2v<F>& f_) @@ -433,6 +409,7 @@ data_[i] = f(i); } + template <unsigned n, typename T> const vec<n, T> vec<n, T>::zero = all_to(0); @@ -451,25 +428,9 @@ return true; } - template <unsigned n, typename T, typename U> - bool operator!=(const vec<n,T>& lhs, const vec<n,U>& rhs) - { - return not (lhs = rhs); - } - - // + template <unsigned n, typename T, typename U> - vec<n,T>& - operator+=(vec<n,T>& lhs, const vec<n,U>& rhs) - { - for (unsigned i = 0; i < n; ++i) - lhs[i] += rhs[i]; - return lhs; - } - - template <unsigned n, typename T, typename U> vec<n, mln_trait_op_plus(T,U)> operator+(const vec<n,T>& lhs, const vec<n,U>& rhs) { @@ -479,19 +440,9 @@ return tmp; } - // - template <unsigned n, typename T, typename U> - vec<n,T>& - operator-=(vec<n,T>& lhs, const vec<n,U>& rhs) - { - for (unsigned i = 0; i < n; ++i) - lhs[i] -= rhs[i]; - return lhs; - } - - template <unsigned n, typename T, typename U> vec<n, mln_trait_op_minus(T,U)> operator-(const vec<n,T>& lhs, const vec<n,U>& rhs) { @@ -501,63 +452,41 @@ return tmp; } - template <unsigned n, typename T> - vec<n, mln_trait_op_uminus(T)> - operator-(const vec<n,T>& lhs) - { - vec<n, mln_trait_op_uminus(T)> tmp; - for (unsigned i = 0; i < n; ++i) - tmp[i] = - lhs[i]; - return tmp; - } - - // * template <unsigned n, typename T, typename S> - vec<n,T>& - operator*=(vec<n,T>& lhs, const S& s) - { - for (unsigned i = 0; i < n; ++i) - lhs[i] *= s; - return lhs; - } - - template <unsigned n, typename T, typename S> vec<n, mln_trait_op_times(T,S)> - operator*(const vec<n,T>& lhs, const S& s) + operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s) { + // FIXME: We made a choice here but is it correct? + // FIXME: We "un-scalar" s so that the scalar status do not propagate. + + // Think of the case: vec<mat> v * scalar(vec w) s + // It gives: for all i, v[i] * w so the i-th mat * vec w -> vec + // The result is a vec<vec> + + // If we really want to propage the "scalar" status then + // we shall allow for scalar(scalar(..)) !!! => FIXME + vec<n, mln_trait_op_times(T,S)> tmp; for (unsigned i = 0; i < n; ++i) - tmp[i] = lhs[i] * s; + tmp[i] = lhs[i] * s.to_equiv(); return tmp; } - // / template <unsigned n, typename T, typename S> - vec<n,T>& - operator/=(vec<n,T>& lhs, const S& s) + vec<n, mln_trait_op_div(T, S)> + operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s) { mln_precondition(s != 0); + vec<n, mln_trait_op_div(T, S)> tmp; for (unsigned i = 0; i < n; ++i) - lhs[i] /= s; - return lhs; - } - - template <unsigned n, typename T, typename S> - vec<n, mln_trait_op_times(T,S)> // FIXME: Use div. - operator/(const vec<n,T>& lhs, const S& s) - { - mln_precondition(s != 0); - vec<n, mln_trait_op_times(T,S)> tmp; - for (unsigned i = 0; i < n; ++i) - tmp[i] = lhs[i] / s; + tmp[i] = lhs[i] / s.to_equiv(); return tmp; } - // << template <unsigned n, typename T> @@ -566,51 +495,31 @@ { ostr << '('; for (unsigned i = 0; i < n; ++i) - ostr << v[i] << (i = n - 1 ? ")" : ", "); - return ostr; - } - - template <unsigned n> - std::ostream& - operator<<(std::ostream& ostr, const vec<n,unsigned char>& v) - { - ostr << '('; - for (unsigned i = 0; i < n; ++i) - ostr << (unsigned int)(v[i]) << (i = n - 1 ? ")" : ", "); - return ostr; - } - - template <unsigned n> - std::ostream& - operator<<(std::ostream& ostr, const vec<n,signed char>& v) - { - ostr << '('; - for (unsigned i = 0; i < n; ++i) - ostr << (signed int)(v[i]) << (i = n - 1 ? ")" : ", "); + ostr << debug::format(v[i]) << (i = n - 1 ? ")" : ", "); return ostr; } // vprod template <typename T, typename U> - vec<3, mln_trait_op_times(T,U)> // typename binary_arith_trait<T, U>::ret> + vec<3, mln_trait_op_times(T,U)> // FIXME: typename binary_arith_trait<T, U>::ret> vprod(const vec<3, T>& lhs, const vec<3, U>& rhs) { - vec<3, T> tmp; // FIXME typename binary_arith_trait<T, U>::ret> tmp; + vec<3, mln_trait_op_times(T,U)> tmp; // FIXME: Likewise. tmp[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1]; tmp[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2]; tmp[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0]; return tmp; } - - # endif // MLN_INCLUDE_ONLY } // end of namespace mln::metal } // end of namespace mln + # include <mln/make/vec.hh> + #endif // ! MLN_METAL_VEC_HH Index: mln/value/proxy.hh --- mln/value/proxy.hh (revision 1381) +++ mln/value/proxy.hh (working copy) @@ -332,4 +332,4 @@ } // end of namespace mln -#endif // ! MLN_VALUE_INT_U_HH +#endif // ! MLN_VALUE_PROXY_HH Index: mln/value/graylevel.hh --- mln/value/graylevel.hh (revision 1381) +++ mln/value/graylevel.hh (working copy) @@ -35,6 +35,8 @@ # include <iostream> +# include <mln/value/ops.hh> + # include <mln/core/contract.hh> # include <mln/metal/math/pow.hh> # include <mln/metal/bexpr.hh> @@ -55,13 +57,97 @@ struct medium_gray_t; struct white_t; } + namespace value + { + class gray; + template <unsigned n> struct graylevel; + struct float01_f; + } /// \} - namespace value + + + namespace trait { + // FIXME: Change into + // - for op::plus: mln::value::graylevel<1 + (n > m ? n : m)> + // - for op::times: mln::value::graylevel<n + m> + // - ... - /// Fwd decl. - class gray; + template < unsigned n, unsigned m > + struct set_precise_binary_< op::plus, mln::value::graylevel<n>, mln::value::graylevel<m> > + { + typedef mln::value::gray ret; + }; + + template < unsigned n, unsigned m > + struct set_precise_binary_< op::minus, mln::value::graylevel<n>, mln::value::graylevel<m> > + { + typedef mln::value::gray ret; + }; + + template < unsigned n, unsigned m > + struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::graylevel<m> > + { + typedef mln::value::gray ret; + }; + + + template < unsigned n, typename I > + struct set_binary_< op::times, + mln::value::Integer, mln::value::graylevel<n>, + mln::value::Integer, I > + { + typedef mln::value::gray ret; + }; + + template < typename I, unsigned n > + struct set_binary_< op::times, + mln::value::Integer, I, + mln::value::Integer, mln::value::graylevel<n> > + { + typedef mln::value::gray ret; + }; + + + template < unsigned n, typename F > + struct set_binary_< op::times, + mln::value::Integer, mln::value::graylevel<n>, + mln::value::Floating, F > + { + typedef float ret; + }; + + template < typename F, unsigned n > + struct set_binary_< op::times, + mln::value::Floating, F, + mln::value::Integer, mln::value::graylevel<n> > + { + typedef float ret; + }; + + + template < unsigned n, typename S > + struct set_precise_binary_< op::times, mln::value::graylevel<n>, mln::value::scalar_<S> > + { + typedef mln_value_equiv(S) E; + typedef mlc_equal(E, float) is_float; // FIXME: Or double... + typedef mlc_if(is_float, float, mln::value::gray) ret; + }; + + template < unsigned n, typename S > + struct set_precise_binary_< op::div, mln::value::graylevel<n>, mln::value::scalar_<S> > + { + typedef mln_trait_op_times(mln::value::graylevel<n>, + mln::value::scalar_<S>) ret; + }; + + } // end of namespace mln::trait + + + + namespace value + { /// General gray-level class on n bits. template <unsigned n> @@ -74,35 +160,60 @@ gray, // Interoperation. graylevel<n> > // Exact. { - /// Ctor. + /// Constructor without argument. graylevel(); - /// Ctor. - explicit graylevel(int val); - /// \{ Ctors with literals. - graylevel(const literal::black_t&); - graylevel(const literal::medium_gray_t&); - graylevel(const literal::white_t&); - /// \} - - /// Ctor with gray. - graylevel(const gray&); - - /// Access to std type. - mln_enc(int_u<n>) value() const; + /// Constructor from int. + graylevel(int val); /// Assigment with int. graylevel<n>& operator=(int val); + + /// Constructor from gray. + graylevel(const gray& rhs); + /// Assigment with gray. - graylevel<n>& operator=(const gray&); + graylevel<n>& operator=(const gray& rhs); + + + /// Copy constructor. + graylevel(const graylevel<n>& rhs); + + /// Assigment. + graylevel<n>& operator=(const graylevel<n>& rhs); + + + /// Constructor from any graylevel. + template <unsigned m> + graylevel(const graylevel<m>& rhs); + + /// Assigment with any graylevel. + template <unsigned m> + graylevel<n>& operator=(const graylevel<m>& rhs); + + + /// Ctors with literals. + /// \{ + graylevel(const literal::black_t&); + graylevel(const literal::medium_gray_t&); + graylevel(const literal::white_t&); + /// \} - /// \{ Assigment with literals. + /// Assigment with literals. + /// \{ graylevel<n>& operator=(const literal::white_t&); graylevel<n>& operator=(const literal::medium_gray_t&); graylevel<n>& operator=(const literal::black_t&); /// \} + + + /// Access to std type. + unsigned value() const; + + /// Conversion to float between 0 and 1. + float to_float() const; }; @@ -130,17 +241,38 @@ typedef graylevel<32> gl32; - template <unsigned n, unsigned m> - bool operator=(const graylevel<n>& lhs, const graylevel<m>& rhs); template <unsigned n, unsigned m> - gray operator+(const graylevel<n>& lhs, const graylevel<m>& rhs); + gray + operator+(const graylevel<n>& lhs, const graylevel<m>& rhs); template <unsigned n, unsigned m> - gray operator-(const graylevel<n>& lhs, const graylevel<m>& rhs); + gray + operator-(const graylevel<n>& lhs, const graylevel<m>& rhs); template <unsigned n, unsigned m> - gray operator*(const graylevel<n>& lhs, const graylevel<m>& rhs); + gray + operator*(const graylevel<n>& lhs, const graylevel<m>& rhs); + + // With Integer. + + template <unsigned n, typename I> + gray + operator*(const graylevel<n>& lhs, const Integer<I>& rhs); + + template <typename I, unsigned n> + gray + operator*(const Integer<I>& lhs, const graylevel<n>& rhs); + + // With Floating. + + template <unsigned n, typename F> + float + operator*(const graylevel<n>& lhs, const Floating<F>& rhs); + + template <typename F, unsigned n> + float + operator*(const Floating<F>& lhs, const graylevel<n>& rhs); @@ -149,11 +281,13 @@ // Graylevel<n>. + template <unsigned n> graylevel<n>::graylevel() { } + template <unsigned n> graylevel<n>::graylevel(int val) { @@ -163,6 +297,17 @@ } template <unsigned n> + graylevel<n>& + graylevel<n>::operator=(int val) + { + mln_precondition(val >= 0); + mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>))); + this->v_ = val; + return *this; + } + + + template <unsigned n> graylevel<n>::graylevel(const gray& g) { gray tmp = g.to_nbits(n); @@ -170,47 +315,49 @@ } template <unsigned n> - graylevel<n>::graylevel(const literal::black_t&) + graylevel<n>& + graylevel<n>::operator=(const gray& g) { - this->v_ = 0; + gray tmp = g.to_nbits(n); + this->v_ = tmp.value(); + return *this; } template <unsigned n> - graylevel<n>::graylevel(const literal::medium_gray_t&) + graylevel<n>::graylevel(const graylevel<n>& rhs) { - this->v_ = metal::math::pow_int<2, n - 1>::value; + this->v_ = rhs.v_; } template <unsigned n> - graylevel<n>::graylevel(const literal::white_t&) + graylevel<n>& + graylevel<n>::operator=(const graylevel<n>& rhs) { - this->v_ = mln_max(mln_enc(int_u<n>)); + this->v_ = rhs.v_; + return *this; } template <unsigned n> - mln_enc(int_u<n>) - graylevel<n>::value() const + template <unsigned m> + graylevel<n>::graylevel(const graylevel<m>& rhs) { - return this->v_; + *this = gray(rhs).to_nbits(n); } template <unsigned n> + template <unsigned m> graylevel<n>& - graylevel<n>::operator=(int val) + graylevel<n>::operator=(const graylevel<m>& rhs) { - mln_precondition(val >= 0); - mln_precondition(unsigned(val) <= mln_max(mln_enc(int_u<n>))); - this->v_ = val; + *this = gray(rhs).to_nbits(n); return *this; } + template <unsigned n> - graylevel<n>& - graylevel<n>::operator=(const gray& g) + graylevel<n>::graylevel(const literal::black_t&) { - gray tmp = g.to_nbits(n); - this->v_ = tmp.value(); - return *this; + this->v_ = 0; } template <unsigned n> @@ -222,6 +369,12 @@ } template <unsigned n> + graylevel<n>::graylevel(const literal::medium_gray_t&) + { + this->v_ = metal::math::pow_int<2, n - 1>::value; + } + + template <unsigned n> graylevel<n>& graylevel<n>::operator=(const literal::medium_gray_t&) { @@ -230,6 +383,12 @@ } template <unsigned n> + graylevel<n>::graylevel(const literal::white_t&) + { + this->v_ = mln_max(mln_enc(int_u<n>)); + } + + template <unsigned n> graylevel<n>& graylevel<n>::operator=(const literal::white_t&) { @@ -237,20 +396,34 @@ return *this; } + template <unsigned n> - std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g) + unsigned + graylevel<n>::value() const { - return ostr << g.value(); + return this->v_; } - template <unsigned n, unsigned m> - bool operator=(const graylevel<n>& lhs, const graylevel<m>& rhs) + template <unsigned n> + float + graylevel<n>::to_float() const { - return gray(lhs) = gray(rhs); + static const float denom = float(metal::math::pow_int<2, n>::value) - 1.f; + return float(this->v_) / denom; } -# endif // ! MLN_INCLUDE_ONLY + // Operators. + + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const graylevel<n>& g) + { + return ostr << g.value() << "/gl" << n; // FIXME: Be more explicit! + } + + // The remaining operators are in mln/value/gray.hh. + +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value Index: mln/value/cast.hh --- mln/value/cast.hh (revision 1381) +++ mln/value/cast.hh (working copy) @@ -29,6 +29,7 @@ # define MLN_VALUE_CAST_HH /*! \file mln/value/cast.hh + * * \brief Definition of the mln::value::cast routine. */ Index: mln/value/ops.hh --- mln/value/ops.hh (revision 0) +++ mln/value/ops.hh (revision 0) @@ -0,0 +1,167 @@ +// 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 MLN_VALUE_OPS_HH +# define MLN_VALUE_OPS_HH + +/*! \file mln/value/ops.hh + * + * \brief Definitions of operators for value types. + */ + +# include <mln/trait/op/all.hh> +# include <mln/value/builtin/all.hh> +# include <mln/value/concept/all.hh> +# include <mln/value/equiv.hh> +# include <mln/literal/zero.hh> +# include <mln/literal/one.hh> +# include <mln/metal/ret.hh> + + + +// FIXME: In the definitions below, is that equiv or interop? + + + +namespace mln +{ + + namespace trait + { + + // Unary traits for any Scalar type. + + template < template <class> class Name, + typename V > + struct set_unary_< Name, mln::value::Scalar, V > + { + typedef mln_trait_unary(Name, mln_value_equiv(V)) ret; + }; + + // Binary traits for any Scalar type. + + template < template <class, class> class Name, + typename Vl, typename Vr > + struct set_binary_< Name, mln::value::Scalar, Vl, mln::value::Scalar, Vr > + { + typedef mln_trait_binary(Name, mln_value_equiv(Vl), mln_value_equiv(Vr)) ret; + }; + + } // end of namespace mln::trait + + + // Arithmetical binary operators. + + template <typename Vl, typename Vr> + mln_trait_op_plus(Vl, Vr) + operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs); + + template <typename Vl, typename Vr> + mln_trait_op_minus(Vl, Vr) + operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs); + + template <typename Vl, typename Vr> + mln_trait_op_times(Vl, Vr) + operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs); + + template <typename Vl, typename Vr> + mln_trait_op_div(Vl, Vr) + operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs); + + template <typename Vl, typename Vr> + mln_trait_op_mod(Vl, Vr) + operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs); + + + // Arithmetical unary operators. + + template <typename S> + mln_trait_op_uminus(S) + operator - (const value::scalar_<S>& rhs); // Overload of op-(Object) in core/ops. + // FIXME: It is dedicated to value::scalar_ so move elsewhere? + + + + // Logical operators. + + // FIXME: ... + + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename Vl, typename Vr> + mln_trait_op_plus(Vl, Vr) + operator + (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs) + { + return value::equiv(lhs) + value::equiv(rhs); + } + + template <typename Vl, typename Vr> + mln_trait_op_minus(Vl, Vr) + operator - (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs) + { + return value::equiv(lhs) - value::equiv(rhs); + } + + template <typename Vl, typename Vr> + mln_trait_op_times(Vl, Vr) + operator * (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs) + { + return value::equiv(lhs) * value::equiv(rhs); + } + + template <typename Vl, typename Vr> + mln_trait_op_div(Vl, Vr) + operator / (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs) + { + return value::equiv(lhs) / value::equiv(rhs); + } + + template <typename Vl, typename Vr> + mln_trait_op_mod(Vl, Vr) + operator % (const value::Scalar<Vl>& lhs, const value::Scalar<Vr>& rhs) + { + return value::equiv(lhs) % value::equiv(rhs); + } + + template <typename S> + mln_trait_op_uminus(S) + operator - (const value::scalar_<S>& rhs) + { + return - rhs.to_equiv(); + } + + // ... + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_VALUE_OPS_HH Index: mln/value/gray.hh --- mln/value/gray.hh (revision 1381) +++ mln/value/gray.hh (working copy) @@ -49,6 +49,18 @@ /// \} + namespace trait + { + + template < template <class, class> class Name > + struct set_precise_binary_< Name, mln::value::gray, mln::value::gray > + { + typedef mln::value::gray ret; + }; + + } // end of namespace mln::trait + + namespace value { @@ -60,18 +72,18 @@ public: /// Encoding associated type. - typedef unsigned long enc; + typedef long enc; /// Equivalent associated type. - typedef unsigned long equiv; + typedef long equiv; /// Constructor without argument. gray(); /// \{ Constructors/assignments with literals. - gray(const literal::white_t&); + explicit gray(const literal::white_t&); gray& operator=(const literal::white_t&); - gray(const literal::black_t&); + explicit gray(const literal::black_t&); gray& operator=(const literal::black_t&); /// \} @@ -85,10 +97,10 @@ /// \} /// Ctor. - gray(unsigned nbits, unsigned long val); + gray(unsigned nbits, long val); /// Access to std type. - unsigned long value() const; + long value() const; /// Access to the encoding size. unsigned nbits() const; @@ -108,9 +120,12 @@ unsigned nbits_; /// Value. - unsigned long val_; + long val_; }; + + // Operators. + std::ostream& operator<<(std::ostream& ostr, const gray& g); bool operator=(const gray& lhs, const gray& rhs); @@ -129,42 +144,6 @@ # ifndef MLN_INCLUDE_ONLY - template <unsigned N, unsigned M> - gray operator+(const graylevel<N>& lhs, const graylevel<M>& rhs) - { - return gray(lhs) + gray(rhs); - } - - template <unsigned N, unsigned M> - gray operator-(const graylevel<N>& lhs, const graylevel<M>& rhs) - { - return gray(lhs) - gray(rhs); - } - - template <unsigned N> - gray operator*(int s, const graylevel<N>& rhs) - { - mln_precondition(s >= 0); - gray tmp(N, s * rhs.value()); - return tmp; - } - - template <unsigned N> - gray operator*(const graylevel<N>& lhs, int s) - { - mln_precondition(s >= 0); - gray tmp(N, lhs.value() * s); - return tmp; - } - - template <unsigned N> - gray operator/(const graylevel<N>& lhs, int s) - { - mln_precondition(s > 0); - gray tmp(N, lhs.value() / s); - return tmp; - } - // Gray. gray::gray() @@ -214,13 +193,13 @@ return *this; } - gray::gray(unsigned nbits, unsigned long val) + gray::gray(unsigned nbits, long val) : nbits_(nbits), val_(val) { } - unsigned long gray::value() const + long gray::value() const { mln_invariant(nbits_ != 0); return val_; @@ -234,7 +213,7 @@ namespace internal { - unsigned long two_pow_(unsigned n) + long two_pow_(unsigned n) { if (n = 0) return 1; @@ -242,13 +221,13 @@ return 2 * two_pow_(n - 1); } - unsigned long two_pow_n_minus_1(unsigned n) + long two_pow_n_minus_1(unsigned n) { return two_pow_(n) - 1; } template <unsigned n_dest> - unsigned long convert(unsigned n_src, unsigned long val) + long convert(unsigned n_src, long val) { if (n_dest = n_src) return val; @@ -301,11 +280,12 @@ return tmp; } - // operators + + // Operators. std::ostream& operator<<(std::ostream& ostr, const gray& g) { - return ostr << g.value() << '/' << g.nbits() << "nbits"; + return ostr << g.value() << "g/" << g.nbits() << "bits"; } bool operator=(const gray& lhs, const gray& rhs) @@ -352,7 +332,7 @@ mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0); if (lhs.nbits() > rhs.nbits()) { - unsigned long l = rhs.to_nbits(lhs.nbits()).value(); + long l = rhs.to_nbits(lhs.nbits()).value(); assert(lhs.value() >= l); gray tmp(lhs.nbits(), lhs.value() - l); @@ -360,7 +340,7 @@ } else { - unsigned long l = lhs.to_nbits(rhs.nbits()).value(); + long l = lhs.to_nbits(rhs.nbits()).value(); assert(l >= rhs.value()); gray tmp(rhs.nbits(), l - rhs.value()); @@ -368,27 +348,160 @@ } } + gray operator*(const gray& lhs, const gray& rhs) + { + // FIXME: The formula below is wrong but we do not mind, + // the exact computation being too heavy for a such light + // operator. + gray tmp(lhs.nbits() + rhs.nbits(), + (lhs.value() + 1) * (rhs.value() + 1) - 1); + return tmp; + } + gray operator*(int s, const gray& rhs) { - mln_precondition(s >= 0); gray tmp(rhs.nbits(), rhs.value() * s); return tmp; } gray operator*(const gray& lhs, int s) { - mln_precondition(s >= 0); gray tmp(lhs.nbits(), lhs.value() * s); return tmp; } gray operator/(const gray& lhs, int s) { - mln_precondition(s > 0); + mln_precondition(s != 0); gray tmp(lhs.nbits(), lhs.value() / s); return tmp; } + + // Graylevel operators. + + // Op gl + gl + + template <unsigned n, unsigned m> + gray + operator+(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return gray(lhs) + gray(rhs); + } + + // Op gl - gl + + template <unsigned n, unsigned m> + gray + operator-(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return gray(lhs) - gray(rhs); + } + + // Op gl * gl + + template <unsigned n, unsigned m> + gray + operator*(const graylevel<n>& lhs, const graylevel<m>& rhs) + { + return gray(lhs) * gray(rhs); + } + + // Op symm gl * Int + + template <unsigned n, typename I> + gray + operator*(const graylevel<n>& lhs, const Integer<I>& rhs) + { + return gray(lhs) * int(exact(rhs)); + } + + template <typename I, unsigned n> + gray + operator*(const Integer<I>& lhs, const graylevel<n>& rhs) + { + return gray(rhs) * int(exact(lhs)); + } + + // Op symm gl * Float + + template <unsigned n, typename F> + float + operator*(const graylevel<n>& lhs, const Floating<F>& rhs) + { + return lhs.to_float() * exact(rhs); + } + + template <typename F, unsigned n> + float + operator*(const Floating<F>& lhs, const graylevel<n>& rhs) + { + return rhs.to_float() * exact(lhs); + } + + + + // Op * scalar + + namespace internal + { + + template <typename ret> + struct helper_gray_op_; + + template <> + struct helper_gray_op_< gray > + { + template <unsigned n, typename S> + static gray times(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + gray tmp(n, lhs.value() * rhs.to_equiv()); + return tmp; + } + template <unsigned n, typename S> + static gray div(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + gray tmp(n, lhs.value() / rhs.to_equiv()); + return tmp; + } + }; + + template <> + struct helper_gray_op_< float > + { + template <unsigned n, typename S> + static float times(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + float tmp(lhs.to_float() * float(rhs.to_equiv())); + return tmp; + } + template <unsigned n, typename S> + static float div(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + float tmp(lhs.to_float() / float(rhs.to_equiv())); + return tmp; + } + }; + + } // end of namespace mln::value::internal + + template <unsigned n, typename S> + mln_trait_op_times(graylevel<n>, scalar_<S>) + operator*(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + typedef mln_trait_op_times(graylevel<n>, scalar_<S>) ret; + return internal::helper_gray_op_<ret>::times(lhs, rhs); + } + + template <unsigned n, typename S> + mln_trait_op_div(graylevel<n>, scalar_<S>) + operator/(const graylevel<n>& lhs, const scalar_<S>& rhs) + { + mln_precondition(rhs.to_equiv() != 0); + typedef mln_trait_op_div(graylevel<n>, scalar_<S>) ret; + return internal::helper_gray_op_<ret>::div(lhs, rhs); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value Index: mln/value/rgb8.hh --- mln/value/rgb8.hh (revision 1381) +++ mln/value/rgb8.hh (working copy) @@ -35,6 +35,7 @@ */ # include <mln/value/rgb.hh> +# include <mln/value/int_u8.hh> namespace mln Index: mln/value/float01_.hh --- mln/value/float01_.hh (revision 1381) +++ mln/value/float01_.hh (working copy) @@ -55,34 +55,34 @@ class float01; - /// General float01_ class on n bits. + /// General class for the interval [0,1] of |R made discrete (quantized with n bits). template <unsigned n> struct float01_ : public Floating< float01_<n> >, - public internal::value_like_< int_u<n>, // Equivalent. // FIXME: Why not float01? + public internal::value_like_< float, // Equivalent. // FIXME: Why not float01? mln_enc(int_u<n>), // Encoding. float, // Interoperation. float01_<n> > // Exact. { - /// Ctor. + /// Constructor without argument. float01_(); - /// Ctor. + /// Constructor from a float. float01_(float val); + /// Assigment from a float. + float01_<n>& operator=(float val); + /// Access to std type. float value() const; /// Set value to the \p val th position in the quantized interval. void set_ind(unsigned long val); - /// Float convertion. + /// Conversion to a float. operator float() const; - - /// Float assigment. - float01_<n>& operator=(float val); }; Index: mln/value/scalar.hh --- mln/value/scalar.hh (revision 1381) +++ mln/value/scalar.hh (working copy) @@ -38,7 +38,6 @@ # include <mln/metal/if.hh> - namespace mln { @@ -61,26 +60,29 @@ scalar_(); /// Ctor. - scalar_(const T& val); + explicit scalar_(const T& val); - /// Conversion. + /// Conversion. FIXME: Is-it useful? operator T() const; + /// Access to the scalar value. + T to_equiv() const; + protected: T val_; // FIXME: const&? }; - - template <typename T> - class scalar_< scalar_<T> >; // Safety. - + template <typename T> class scalar_< scalar_<T> >; // Safety: this type should not exist! + /// Print a scalar \p s in an output stream \p ostr. template <typename T> std::ostream& operator<<(std::ostream& ostr, const scalar_<T>& s); + // Routine scalar(T) -> scalar_<T>. + namespace internal { @@ -101,6 +103,7 @@ + # ifndef MLN_INCLUDE_ONLY // scalar_<T>. @@ -122,12 +125,19 @@ return val_; } + template <typename T> + T + scalar_<T>::to_equiv() const + { + return val_; + } + // Operator. template <typename T> std::ostream& operator<<(std::ostream& ostr, const scalar_<T>& s) { - return ostr << T(s); + return ostr << s.to_equiv(); } // Routine. @@ -136,7 +146,8 @@ typename internal::helper_scalar_<T>::ret scalar(const T& s) { - return s; + typename internal::helper_scalar_<T>::ret tmp(s); + return tmp; } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/quat.hh --- mln/value/quat.hh (revision 1381) +++ mln/value/quat.hh (working copy) @@ -35,88 +35,169 @@ # include <cmath> +# include <mln/value/ops.hh> + +# include <mln/value/concept/vectorial.hh> +# include <mln/value/internal/value_like.hh> +# include <mln/value/props.hh> + # include <mln/metal/vec.hh> # include <mln/norm/l2.hh> -# include <mln/value/props.hh> -# include <mln/value/concept/vectorial.hh> + namespace mln { - namespace value + // Fwd decls. + namespace value { class quat; } + namespace literal { struct zero_t; struct one_t; } + + + namespace trait { - //FIXME doesn't compile - class quat :// public Vectorial< quat >, - public metal::vec<4, float> + // quat OP quat + + template <> + struct set_precise_binary_< op::plus, mln::value::quat, mln::value::quat > { - typedef metal::vec<4, float> super_; - using super_::data_; + typedef mln::value::quat ret; + }; + + template <> + struct set_precise_binary_< op::minus, mln::value::quat, mln::value::quat > + { + typedef mln::value::quat ret; + }; + + template <> + struct set_precise_binary_< op::times, mln::value::quat, mln::value::quat > + { + typedef mln::value::quat ret; + }; + + // quat OP scalar + + template < typename S > + struct set_precise_binary_< op::times, mln::value::quat, mln::value::scalar_<S> > + { + typedef mln::value::quat ret; + }; + + template < typename S > + struct set_precise_binary_< op::div, mln::value::quat, mln::value::scalar_<S> > + { + typedef mln::value::quat ret; + }; + + } // end of namespace mln::trait - public: - /// Encoding associated type. - typedef float enc; - /// Equivalent associated type. - typedef float equiv[4]; + namespace value + { + + // FIXME doesn't compile - // ctors + class quat + : + public Vectorial< quat > + , + public internal::value_like_< metal::vec<4, float>, // Equivalent. + metal::vec<4, float>, // Encoding. + metal::vec<4, float>, // Interoperation. + quat > // Exact. + { + public: + /// Constructor without argument. quat(); + + /// Constructor with components. quat(float s, float x, float y, float z); - template <typename T> - quat(float s, const metal::vec<3,T>& v); + /// Constructor from a scalar and a 3D vector. + quat(float s, const metal::vec<3,float>& v); - template <typename T> - quat(const metal::vec<4,T>& v); - // accessors/modifiers as a 'scalar+metal::vec<3>' + /// Constructor from a 4D vector. + quat(const metal::vec<4,float>& v); - float scal() const; - void set_scal(float s); + /// Assignment from a 4D vector. + quat& operator=(const metal::vec<4,float>& v); + + + /// \{ Constructors/assignments with literals zero and one. + quat(const literal::zero_t&); + quat& operator=(const literal::zero_t&); + quat(const literal::one_t&); + quat& operator=(const literal::one_t&); + /// \} - metal::vec<3,float> vect() const; - void set_vect(float x, float y, float z); - template <typename T> - void set_vect(const metal::vec<3,T>& v); - // multiplication + /// Explicit conversion to a 4D metal::vec. + const metal::vec<4,float>& to_vec() const; - quat operator*(const quat& rhs) const; - // tests + /// Give the scalar part. + float s() const; + /// Access to the scalar part. + float& s(); + + const metal::vec<3,float>& v() const; + metal::vec<3,float>& v(); + + void set_v(float x, float y, float z); + + /// Scalar product. + float sprod(const quat& rhs) const; + + /// Test if it is a unit quaternion. bool is_unit() const; + + /// Test if the quaternion is null. bool is_null() const; - // conjugate and invert + /// Test if it is a pure quaternion. + bool is_pure() const; + /// Give the conjugate. quat conj() const; - quat inv() const; - // transform into unit quaternion + /// Give the invert. + quat inv() const; // FIXME: Rename inv as invert. + /// Transform into unit quaternion. quat& set_unit(); + + /// Transform into unit quaternion. template <typename T> void set_unit(float theta, const metal::vec<3,T>& uv); // only for unit quaternions described by theta and uv such as: // q = ( cos(theta), sin(theta) * uv ) - template <typename T> - quat(unsigned one, float theta, const metal::vec<3, T>& uv); + quat(unsigned one, float theta, const metal::vec<3,float>& uv); float theta() const; void set_theta(float theta); - metal::vec<3, float> uvect() const; - template <typename T> - void set_uvect(const metal::vec<3,T>& uv); - + metal::vec<3,float> uv() const; + void set_uv(const metal::vec<3,float>& uv); }; + + // Operators. + + std::ostream& operator<<(std::ostream& ostr, const quat& q); + + quat operator+(const quat& lhs, const quat& rhs); + quat operator-(const quat& lhs, const quat& rhs); + quat operator*(const quat& lhs, const quat& rhs); + template <typename S> quat operator*(const quat& lhs, const value::scalar_<S>& rhs); + template <typename S> quat operator/(const quat& lhs, const value::scalar_<S>& rhs); + // overloaded math procs quat log(const quat& q); @@ -126,14 +207,17 @@ bool about_equal(const T& f, const T& q); bool about_equal(const quat& p, const quat& q); + // Misc. bool interpol_ok(const quat& p, const quat& q, float h); + // Linear Quaternion Interpolation. quat lerp(const quat& p, const quat& q, float h); + // Spherical Linear Quaternion Interpolation. quat slerp(const quat& p, const quat& q, float h); @@ -146,10 +230,11 @@ quat slerp_5(const quat& p, const quat& q, float h); -# ifndef MLN_INCLUDE_ONLY - //ctors +# ifndef MLN_INCLUDE_ONLY + + // Constructors. quat::quat() { @@ -157,121 +242,135 @@ quat::quat(float s, float x, float y, float z) { - set_scal(s); - set_vect(x, y, z); + v_[0] = s; + set_v(x, y, z); } - template <typename T> - quat::quat(float s, const metal::vec<3,T>& v) + quat::quat(float s, const metal::vec<3,float>& v) { - set_scal(s); - set_vect(v); + v_[0] = s; + this->v() = v; } - template <typename T> - quat::quat(const metal::vec<4,T>& v) - : metal::vec<4,float>(v) + quat::quat(const metal::vec<4,float>& v) { + this->v_ = v; } + quat& + quat::operator=(const metal::vec<4,float>& v) + { + this->v_ = v; + return *this; + } - // accessors/modifiers as a 'scalar+vec<3>' + // With literals. - float quat::scal() const + quat::quat(const literal::zero_t&) { - return data_[0]; + v_.set_all(0); } - - void quat::set_scal(float s) + quat& + quat::operator=(const literal::zero_t&) { - data_[0] = s; + v_.set_all(0); + return *this; } + quat::quat(const literal::one_t&) + { + s() = 1; + v().set_all(0); + } - metal::vec<3, float> quat::vect() const + quat& + quat::operator=(const literal::one_t&) { - return make::vec(data_[1], data_[2], data_[3]); + s() = 1; + v().set_all(0); + return *this; } - void quat::set_vect(float x, float y, float z) + const metal::vec<4,float>& + quat::to_vec() const { - data_[1] = x; - data_[2] = y; - data_[3] = z; + return this->v_; } - template <typename T> - void quat::set_vect(const metal::vec<3,T>& v) + float + quat::s() const { - set_vect(v[0], v[1], v[2]); + return this->v_[0]; } - - // multiplication - - - quat quat::operator*(const quat& rhs) const + float& + quat::s() { - float - s1 = scal(), - s2 = rhs.scal(); - - metal::vec<3,float> - v1 = vect(), - v2 = rhs.vect(); + return this->v_[0]; + } - return quat(s1 * s2 - v1.sprod(v2), - metal::vprod(v1, v2) - + s1 * v2 + s2 * v1); + const metal::vec<3, float>& + quat::v() const + { + return *(const metal::vec<3, float>*)(const void*)(& this->v_[1]); + // return make::vec(this->v_[1], this->v_[2], this->v_[3]); } + metal::vec<3, float>& + quat::v() + { + return *(metal::vec<3, float>*)(void*)(& this->v_[1]); + } - // tests + void quat::set_v(float x, float y, float z) + { + this->v_[1] = x; + this->v_[2] = y; + this->v_[3] = z; + } + float + quat::sprod(const quat& rhs) const + { + return v_.sprod(rhs.to_vec()); + } bool quat::is_unit() const { - return about_equal(norm::l2(*this), 1.f); + return about_equal(norm::l2(v_), 1.f); } - bool quat::is_null() const { - return about_equal(norm::l2(*this), 0.f); + return about_equal(norm::l2(v_), 0.f); } - - // conjugate and invert - + bool quat::is_pure() const + { + return about_equal(v_[0], 0.f); + } quat quat::conj() const { - return quat(scal(), - vect()); + return quat(s(), - v()); } - quat quat::inv() const { assert(! is_null()); - float f = norm::l2(*this); - - return conj() / (f * f); + float f = norm::l2(v_); + return conj().to_vec() / (f * f); } - - // transform into unit quaternion - - quat& quat::set_unit() { - normalize(); + v_.normalize(); return *this; } - template <typename T> void quat::set_unit(float theta, const metal::vec<3,T>& uv) { @@ -281,67 +380,106 @@ && theta < pi + props<float>::epsilon()); mln_precondition(about_equal(norm::l2(uv), 1.f)); - data_[0] = cos(theta); + this->v_[0] = cos(theta); float sint = sin(theta); - data_[1] = uv[0] * sint; - data_[2] = uv[1] * sint; - data_[3] = uv[2] * sint; + this->v_[1] = uv[0] * sint; + this->v_[2] = uv[1] * sint; + this->v_[3] = uv[2] * sint; } // only for unit quaternions described by theta and uv such as: // q = ( cos(theta), sin(theta) * uv ) - - template <typename T> - quat::quat(unsigned one, float theta, const metal::vec<3,T>& uv) + quat::quat(unsigned one, float theta, const metal::vec<3,float>& uv) { mln_precondition(one = 1); set_unit(theta, uv); } - float quat::theta() const { mln_precondition(is_unit()); - return acos(scal()); + return acos(s()); } - void quat::set_theta(float theta) { mln_precondition(is_unit()); - set_unit(theta, uvect()); + set_unit(theta, uv()); } - metal::vec<3, float> quat::uvect() const + metal::vec<3, float> quat::uv() const { mln_precondition(is_unit()); - metal::vec<3, float> v = vect(); - return v.normalize(); + metal::vec<3, float> w = v(); + return w.normalize(); } - template <typename T> - void quat::set_uvect(const metal::vec<3,T>& uv) + void quat::set_uv(const metal::vec<3,float>& uv) { mln_precondition(is_unit()); set_unit(theta(), uv); } - // overloaded math procs + // Operators. + + std::ostream& operator<<(std::ostream& ostr, const quat& q) + { + return ostr << q.to_vec(); + } + + quat operator+(const quat& lhs, const quat& rhs) + { + quat tmp(lhs.to_vec() + rhs.to_vec()); + return tmp; + } + quat operator-(const quat& lhs, const quat& rhs) + { + quat tmp(lhs.to_vec() - rhs.to_vec()); + return tmp; + } + + quat operator*(const quat& lhs, const quat& rhs) + { + quat tmp(lhs.s() * rhs.s() - lhs.v().sprod(rhs.v()), + metal::vprod(lhs.v(), rhs.v()) + lhs.s() * rhs.v() + rhs.s() * lhs.v()); + return tmp; + } + + template <typename S> + quat operator*(const quat& lhs, const value::scalar_<S>& rhs) + { + mlc_converts_to(S, float)::check(); + quat tmp(lhs.to_vec() * float(rhs)); + return tmp; + } + + template <typename S> + quat operator/(const quat& lhs, const value::scalar_<S>& rhs_) + { + mlc_converts_to(S, float)::check(); + float rhs = float(rhs_); + mln_precondition(rhs != 0.f); + quat tmp(lhs.to_vec() / rhs); + return tmp; + } + + + // overloaded math procs quat log(const quat& q) { mln_precondition(q.is_unit()); - return quat(0.f, q.theta() * q.uvect()); + return quat(0.f, q.theta() * q.uv()); } quat exp(const quat& q) { - mln_precondition(about_equal(q.scal(), 0.f)); - metal::vec<3, float> v = q.vect(); + mln_precondition(about_equal(q.s(), 0.f)); + metal::vec<3, float> v = q.v(); float theta = norm::l2(v); mln_precondition(!about_equal(theta, 0.f)); metal::vec<3, float> uv = v / theta; @@ -365,7 +503,7 @@ bool about_equal(const quat& p, const quat& q) { - return about_equal<float>(norm::l2(p - q), 0); + return about_equal<float>(norm::l2(p.to_vec() - q.to_vec()), 0); } // Misc. Index: mln/value/int_s.hh --- mln/value/int_s.hh (revision 1381) +++ mln/value/int_s.hh (working copy) @@ -33,6 +33,8 @@ * \brief Define a generic class for signed integers. */ +# include <mln/value/ops.hh> + # include <mln/metal/math/pow.hh> # include <mln/value/internal/value_like.hh> # include <mln/value/concept/integer.hh> @@ -56,34 +58,11 @@ namespace trait { - // promote - - template <unsigned n> - struct set_precise_binary_< promote, mln::value::int_s<n>, int > - { - typedef int ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, int, mln::value::int_s<n> > - { - typedef int ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, mln::value::int_s<n>, float > - { - typedef float ret; - }; - template <unsigned n> - struct set_precise_binary_< promote, float, mln::value::int_s<n> > + struct value_< mln::value::int_s<n> > : mln::trait::value_integer_<n> { - typedef float ret; }; - // FIXME: Is that all? (No!) - } // end of namespace mln::trait @@ -125,9 +104,6 @@ /// Assignment from an integer. int_s<n>& operator=(int i); - /// Negation. - int_s<n> operator-() const; - /// Zero value. static const int_s<n> zero; @@ -232,13 +208,6 @@ } template <unsigned n> - int_s<n> - int_s<n>::operator-() const - { - return - this->v_; - } - - template <unsigned n> const int_s<n> int_s<n>::zero = 0; template <unsigned n> Index: mln/value/internal/value_like.hh --- mln/value/internal/value_like.hh (revision 1381) +++ mln/value/internal/value_like.hh (working copy) @@ -75,11 +75,15 @@ V to_equiv() const; /// Explicit convertion towards encoding type. - C to_enc() const; + const C& to_enc() const; /// Explicit convertion towards interoperation type. N to_interop() const; + + // Handle to encoding value. + C& handle_() { return v_; } + protected: enc v_; /// The encoding value. }; @@ -113,7 +117,7 @@ } template <typename V, typename C, typename N, typename E> - C + const C& value_like_<V,C,N,E>::to_enc() const { return v_; @@ -130,14 +134,14 @@ bool operator=(const value_like_<V,C,N,E>& lhs, const value_like_<V,C,N,E>& rhs) { - return lhs.to_interop() = rhs.to_interop(); + return lhs.to_enc() = rhs.to_enc(); } template <typename V, typename C, typename N, typename E> bool operator<(const value_like_<V,C,N,E>& lhs, const value_like_<V,C,N,E>& rhs) { - return lhs.to_interop() < rhs.to_interop(); + return lhs.to_interop() < rhs.to_interop(); // FIXME HERE: Why interop? } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/int_u.hh --- mln/value/int_u.hh (revision 1381) +++ mln/value/int_u.hh (working copy) @@ -33,6 +33,8 @@ * \brief Define a generic class for unsigned integers. */ +# include <mln/value/ops.hh> + # include <mln/metal/math/pow.hh> # include <mln/value/internal/value_like.hh> # include <mln/value/internal/encoding.hh> @@ -43,6 +45,7 @@ # include <mln/debug/format.hh> + namespace mln { @@ -55,58 +58,18 @@ namespace trait { - // promote - - template <unsigned n> - struct set_precise_binary_< promote, mln::value::int_u<n>, int > - { - typedef int ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, int, mln::value::int_u<n> > - { - typedef int ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, mln::value::int_u<n>, unsigned > - { - typedef unsigned ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, unsigned, mln::value::int_u<n> > - { - typedef unsigned ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, mln::value::int_u<n>, float > - { - typedef float ret; - }; - - template <unsigned n> - struct set_precise_binary_< promote, float, mln::value::int_u<n> > - { - typedef float ret; - }; - - // FIXME: Is that all? (No!) - template <unsigned n> - struct value_< mln::value::int_u<n> > : mln::trait::value_integer_<8> + struct value_< mln::value::int_u<n> > : mln::trait::value_integer_<n> { }; } // end of namespace mln::trait + namespace value { - /*! \brief Unsigned integer value class. * * The parameter is \c n the number of encoding bits. @@ -151,7 +114,6 @@ }; - // Safety. template <> struct int_u<0>; template <> struct int_u<1>; @@ -183,6 +145,11 @@ std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i); + // FIXME: Doc! + template <unsigned n> + std::istream& operator>>(std::istream& istr, int_u<n>& i); + + # ifndef MLN_INCLUDE_ONLY template <unsigned n> @@ -256,6 +223,12 @@ return ostr << debug::format(i.to_equiv()); // FIXME: is to_equiv OK? } + template <unsigned n> + std::istream& operator>>(std::istream& istr, int_u<n>& i) + { + return istr >> i.handle_(); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value Index: mln/value/equiv.hh --- mln/value/equiv.hh (revision 0) +++ mln/value/equiv.hh (revision 0) @@ -0,0 +1,157 @@ +// 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 MLN_VALUE_EQUIV_HH +# define MLN_VALUE_EQUIV_HH + +/*! \file mln/value/equiv.hh + * + * \brief The mln::equiv routine. + */ + +# include <mln/core/concept/value.hh> + + +# define mln_value_equiv(V) typename mln::value::internal::equiv_<V>::ret + + + +namespace mln +{ + + namespace value + { + + // Fwd decl. + namespace internal { template <typename T> struct equiv_; } + + + + /// Access to the equivalent value. + template <typename V> + typename internal::equiv_<V>::ret + equiv(const mln::Value<V>& v); + + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + typedef char yes_; + struct no_ { char dummy[2]; }; + + template <typename T> + struct make_ + { + static T* ptr(); + }; + + + // Fwd decl. + template <unsigned id, typename T> + struct equiv_ret_; + + // Fwd decl. + template <typename V> + const typename internal::equiv_<V>::ret& + run_equiv_(const V& v); + + + template <typename V, typename T> + const typename internal::equiv_<V>::ret& + run_equiv_(const Value<V>* v, const T*) + { + return run_equiv_(exact(v)->to_equiv()); // Rec. + } + + template <typename V> + const V& + run_equiv_(const void*, const V* v) + { + return *v; // Stop rec. + } + + template <typename V> + const typename internal::equiv_<V>::ret& + run_equiv_(const V& v) + { + return run_equiv_(&v, &v); + } + + + template <typename T> + struct equiv_ret_< 1, T > // Rec. + { + typedef typename T::equiv V; + typedef typename equiv_<V>::ret ret; + }; + + template <typename T> + struct equiv_ret_< 2, T > // Stop rec. + { + typedef T ret; + }; + + template <typename V> + yes_ equiv_selector_(Value<V>*); + + no_ equiv_selector_(void*); + + template <typename T> + struct equiv_ + { + enum { id = sizeof(equiv_selector_(make_<T>::ptr())) }; + typedef typename equiv_ret_<id, T>::ret ret; + + static ret run(const T& t) + { + return ret::run(t); + } + }; + + } // end of namespace mln::value::internal + + + + template <typename V> + typename internal::equiv_<V>::ret + equiv(const mln::Value<V>& v) + { + return internal::run_equiv_(exact(v)); + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_EQUIV_HH Index: mln/value/concept/symbolic.hh --- mln/value/concept/symbolic.hh (revision 1381) +++ mln/value/concept/symbolic.hh (working copy) @@ -39,26 +39,21 @@ namespace mln { - // Fwd decls. - template <typename E> struct Value; - namespace value - { - template <typename E> struct Symbolic; - } + // Fwd decl. + namespace value { template <typename E> struct Symbolic; } + namespace trait { - // FIXME + // FIXME... } // end of namespace mln::trait + namespace value { - // Fwd decl. - template <typename E> struct Symbolic; - // Category flag type. template <> struct Symbolic<void> @@ -69,6 +64,7 @@ template <typename E> struct Symbolic : public Value<E> { + typedef Symbolic<void> category; }; } // end of namespace mln::value @@ -76,7 +72,4 @@ } // end of namespace mln -# include <mln/value/concept/all.hh> - - #endif // ! MLN_VALUE_CONCEPT_SYMBOLIC_HH Index: mln/value/concept/floating.hh --- mln/value/concept/floating.hh (revision 1381) +++ mln/value/concept/floating.hh (working copy) @@ -30,7 +30,7 @@ /*! \file mln/value/concept/floating.hh * - * \brief Define a generic class for float values. + * \brief Define a generic class for floating values. */ # include <mln/value/concept/scalar.hh> @@ -40,16 +40,16 @@ { // Fwd decl. - namespace value - { - template <typename E> struct Floating; - } + namespace value { template <typename E> struct Floating; } + namespace trait { - // FIXME + // FIXME... + } // end of namespace mln::trait + namespace value { @@ -63,6 +63,7 @@ template <typename E> struct Floating : public Scalar<E> { + typedef Floating<void> category; }; } // end of namespace mln::value @@ -70,7 +71,4 @@ } // end of namespace mln -# include <mln/value/concept/all.hh> - - #endif // ! MLN_VALUE_CONCEPT_FLOATING_HH Index: mln/value/concept/structured.hh --- mln/value/concept/structured.hh (revision 1381) +++ mln/value/concept/structured.hh (working copy) @@ -40,24 +40,20 @@ { // Fwd decl. - namespace value - { - template <typename E> struct Structured; - } + namespace value { template <typename E> struct Structured; } namespace trait { - // FIXME + + // FIXME... + } // end of namespace mln::trait namespace value { - // Fwd decl. - template <typename E> struct Structured; - // Category flag type. template <> struct Structured<void> @@ -68,6 +64,7 @@ template <typename E> struct Structured : public Value<E> { + typedef Structured<void> category; }; } // end of namespace mln::value @@ -75,7 +72,4 @@ } // end of namespace mln -# include <mln/value/concept/all.hh> - - #endif // ! MLN_VALUE_CONCEPT_STRUCTURED_HH Index: mln/value/concept/scalar.hh --- mln/value/concept/scalar.hh (revision 1381) +++ mln/value/concept/scalar.hh (working copy) @@ -40,24 +40,13 @@ namespace mln { - // Fwd decls. - template <typename E> struct Value; - namespace value - { - template <typename E> struct Scalar; - } - - namespace trait - { - // FIXME - } // end of namespace mln::trait - namespace value { // Fwd decl. template <typename E> struct Scalar; + // Category flag type. template <> struct Scalar<void> @@ -68,95 +57,36 @@ template <typename E> struct Scalar : public Value<E> { + typedef Scalar<void> category; }; } // end of namespace mln::value - /// Pre-incrementation. + /// Pre-incrementation for any scalar type. template <typename S> S& operator++(value::Scalar<S>& rhs); - - /// Pre-decrementation. + /// Pre-decrementation for any scalar type. template <typename S> S& operator--(value::Scalar<S>& rhs); - - template <typename S> - S& operator*=(value::Scalar<S>& lhs, typename S::interop i); - - template <typename S> - S& operator/=(value::Scalar<S>& lhs, typename S::interop i); - - template <typename S> - S& operator+=(value::Scalar<S>& lhs, typename S::interop i); - - template <typename S> - S& operator-=(value::Scalar<S>& lhs, typename S::interop i); - - template <typename S> - S& operator%=(value::Scalar<S>& lhs, typename S::interop i); - - - # ifndef MLN_INCLUDE_ONLY template <typename S> S& operator++(value::Scalar<S>& rhs) { - exact(rhs) += S(literal::one); - return exact(rhs); + mlc_converts_to(literal::one_t, S)::check(); + return exact(rhs) += S(literal::one); } template <typename S> S& operator--(value::Scalar<S>& rhs) { - exact(rhs) -= S(literal::one); - return exact(rhs); - } - - template <typename S> - S& operator*=(value::Scalar<S>& lhs_, typename S::interop i) - { - S& lhs = exact(lhs_); - lhs = lhs * i; - return lhs; - } - - template <typename S> - S& operator/=(value::Scalar<S>& lhs_, typename S::interop i) - { - S& lhs = exact(lhs_); - lhs = lhs / i; - return lhs; - } - - template <typename S> - S& operator+=(value::Scalar<S>& lhs_, typename S::interop i) - { - S& lhs = exact(lhs_); - lhs = lhs + i; - return lhs; - } - - template <typename S> - S& operator-=(value::Scalar<S>& lhs_, typename S::interop i) - { - S& lhs = exact(lhs_); - lhs = lhs - i; - return lhs; - } - - - template <typename S> - S& operator%=(value::Scalar<S>& lhs_, typename S::interop i) - { - S& lhs = exact(lhs_); - lhs = lhs % i; - return lhs; + mlc_converts_to(literal::one_t, S)::check(); + return exact(rhs) -= S(literal::one); } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/concept/built_in.hh --- mln/value/concept/built_in.hh (revision 0) +++ mln/value/concept/built_in.hh (revision 0) @@ -0,0 +1,70 @@ +// 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 MLN_VALUE_CONCEPT_BUILT_IN_HH +# define MLN_VALUE_CONCEPT_BUILT_IN_HH + +/*! \file mln/value/concept/built_in.hh + * + * \brief Define a generic class for built-in values. + */ + +# include <mln/core/category.hh> + + +namespace mln +{ + + // Fwd decl. + namespace value { template <typename E> struct Built_In; } + + + namespace trait + { + // FIXME... + + } // end of namespace mln::trait + + + namespace value + { + + // Category flag type. + template <> + struct Built_In<void> // No inheritance here since this category is special (on the side). + { + // Every builtin belongs to a sub-category of Value but we do not know which one. + // FIXME HERE FIRST: was void* below + typedef Unknown<void> super; + }; + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_CONCEPT_BUILT_IN_HH Index: mln/value/concept/vectorial.hh --- mln/value/concept/vectorial.hh (revision 1381) +++ mln/value/concept/vectorial.hh (working copy) @@ -40,15 +40,13 @@ { // Fwd decl. - namespace value - { - template <typename E> struct Vectorial; - } + namespace value { template <typename E> struct Vectorial; } + namespace trait { - // FIXME + // FIXME... } // end of namespace mln::trait @@ -56,9 +54,6 @@ namespace value { - // Fwd decl. - template <typename E> struct Vectorial; - // Category flag type. template <> struct Vectorial<void> @@ -76,7 +71,4 @@ } // end of namespace mln -# include <mln/value/concept/all.hh> - - #endif // ! MLN_VALUE_CONCEPT_VECTORIAL_HH Index: mln/value/concept/all.hh --- mln/value/concept/all.hh (revision 1381) +++ mln/value/concept/all.hh (working copy) @@ -30,7 +30,7 @@ /*! \file mln/value/concept/all.hh * - * \brief FIXME + * \brief File that includes every sub-concept of the Value concept. */ # include <mln/value/concept/integer.hh> @@ -38,6 +38,7 @@ # include <mln/value/concept/vectorial.hh> # include <mln/value/concept/structured.hh> # include <mln/value/concept/symbolic.hh> +# include <mln/value/concept/data.hh> #endif // ! MLN_VALUE_CONCEPT_ALL_HH Index: mln/value/concept/data.hh --- mln/value/concept/data.hh (revision 0) +++ mln/value/concept/data.hh (revision 0) @@ -0,0 +1,75 @@ +// 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 MLN_VALUE_CONCEPT_DATA_HH +# define MLN_VALUE_CONCEPT_DATA_HH + +/*! \file mln/value/concept/data.hh + * + * \brief Define a generic class for data values. + */ + +# include <mln/core/concept/value.hh> + + +namespace mln +{ + + // Fwd decl. + namespace value { template <typename E> struct Data; } + + + namespace trait + { + + // FIXME... + + } // end of namespace mln::trait + + + namespace value + { + + // Category flag type. + template <> + struct Data<void> + { + typedef Value<void> super; + }; + + template <typename E> + struct Data : public Value<E> + { + typedef Data<void> category; + }; + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_CONCEPT_DATA_HH Index: mln/value/concept/integer.hh --- mln/value/concept/integer.hh (revision 1381) +++ mln/value/concept/integer.hh (working copy) @@ -40,15 +40,14 @@ { // Fwd decl. - namespace value - { - template <typename E> struct Integer; - } + namespace value { template <typename E> struct Integer; } namespace trait { - // FIXME + + // FIXME... + } // end of namespace mln::trait @@ -65,6 +64,7 @@ template <typename E> struct Integer : public Scalar<E> { + typedef Integer<void> category; }; } // end of namespace mln::value @@ -72,7 +72,4 @@ } // end of namespace mln -# include <mln/value/concept/all.hh> - - #endif // ! MLN_VALUE_CONCEPT_INTEGER_HH Index: mln/value/float01.hh --- mln/value/float01.hh (revision 1381) +++ mln/value/float01.hh (working copy) @@ -52,9 +52,8 @@ class float01; - /// General float01_ class where n bits is not know at compile-time. - /// This class is used for exchange between float01_ types purpose. - + /// Class for floating values restricted to the interval [0..1] + /// and discretized with n bits. class float01 : public Floating<float01> { public: Index: mln/value/builtin/ops.hh --- mln/value/builtin/ops.hh (revision 0) +++ mln/value/builtin/ops.hh (revision 0) @@ -0,0 +1,415 @@ +// 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 MLN_VALUE_BUILTIN_OPS_HH +# define MLN_VALUE_BUILTIN_OPS_HH + +/*! \file mln/value/builtin/ops.hh + * + * \brief Definitions of binary operators when lhs is a built-in and + * rhs is an mln object. + */ + +# include <mln/value/scalar.hh> +# include <mln/trait/op/all.hh> +# include <mln/value/builtin/promotions.hh> + + +// The call "built-in (op) Object" inverts the couple of arguments; so +// it results in the effective call: "Object (op) built-in." In the +// definitions of objects, we do not have to handle the possible calls +// "built-in (op) Object". Furthermore, the built-in value is wrapped +// into a value::scalar_ (which is a value::Scalar); as a consequence, +// the definition of an object should only handle the single case +// "Object (op) Scalar". +// +// For instance: +// an expression such as " int * Image<I> " +// is transformed into " I * scalar_<int> " +// with the corresponding return type. + + + +// Operators "object OP built-in" => "object OP scalar". +// and "object OP= built-in" => "object OP= scalar". + +# define mln_internal_decl_op_obj_bi_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Object<O>& lhs, const Builtin & rhs); \ + \ + template <typename O> \ + O& \ + operator Symb##= (Object<O>& lhs, const Builtin & rhs); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_def_op_obj_bi_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Object<O>& lhs, const Builtin & rhs) \ + { \ + return exact(lhs) Symb value::scalar(rhs); \ + } \ + \ + template <typename O> \ + O& \ + operator Symb##= (Object<O>& lhs, const Builtin & rhs) \ + { \ + return exact(lhs) Symb##= value::scalar(rhs); \ + } \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +// Operator "built-in OP object" => "object OP scalar" iff OP commutes. + +# define mln_internal_decl_bi_op_obj_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + +# define mln_internal_def_bi_op_obj_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (O, value::scalar_< Builtin >) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs) \ + { \ + return exact(rhs) Symb value::scalar(lhs); \ + } \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + + +# define mln_internal_op_obj_builtins_(De, Symb, Name) \ + \ + mln_internal_##De##_op_obj_bi_(Symb, Name, signed char); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned char); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, signed short); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned short); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, signed int); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned int); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, signed long); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, unsigned long); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, float); \ + mln_internal_##De##_op_obj_bi_(Symb, Name, double); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_builtins_op_obj_(De, Symb, Name) \ + \ + mln_internal_##De##_bi_op_obj_(Symb, Name, signed char); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned char); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, signed short); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned short); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, signed int); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned int); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, signed long); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, unsigned long); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, float); \ + mln_internal_##De##_bi_op_obj_(Symb, Name, double); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + + +// Operator "Builtin minus Object" is a special case. + + +# define mln_internal_decl_bi_minus_obj_(Builtin) \ + \ + template <typename O> \ + mln_trait_op_minus(Builtin, O) \ + operator - (const Builtin & lhs, const Object<O>& rhs); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_def_bi_minus_obj_(Builtin) \ + \ + template <typename O> \ + mln_trait_op_minus(Builtin, O) \ + operator - (const Builtin & lhs, const Object<O>& rhs) \ + { \ + return (- exact(rhs)) + value::scalar(lhs); \ + } \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_builtins_minus_obj_(De) \ + \ + mln_internal_##De##_bi_minus_obj_( signed char); \ + mln_internal_##De##_bi_minus_obj_(unsigned char); \ + mln_internal_##De##_bi_minus_obj_( signed short); \ + mln_internal_##De##_bi_minus_obj_(unsigned short); \ + mln_internal_##De##_bi_minus_obj_( signed int); \ + mln_internal_##De##_bi_minus_obj_(unsigned int); \ + mln_internal_##De##_bi_minus_obj_( signed long); \ + mln_internal_##De##_bi_minus_obj_(unsigned long); \ + mln_internal_##De##_bi_minus_obj_(float); \ + mln_internal_##De##_bi_minus_obj_(double); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + + +// Operator "Builtin 'div or mod' Object" is a special case. + + +# define mln_internal_decl_bi_dvmd_obj_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (value::scalar_< Builtin >, O) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_def_bi_dvmd_obj_(Symb, Name, Builtin) \ + \ + template <typename O> \ + mln_trait_op_##Name (value::scalar_< Builtin >, O) \ + operator Symb (const Builtin & lhs, const Object<O>& rhs) \ + { std::cout << "hop" << std::endl; \ + return value::scalar(lhs) / exact(rhs); \ + } \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_builtins_dvmd_obj_(De, Symb, Name) \ + \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed char); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned char); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed short); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned short); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed int); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned int); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, signed long); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, unsigned long); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, float); \ + mln_internal_##De##_bi_dvmd_obj_(Symb, Name, double); \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + +// FIXME: What about pointers, arrays, bool, etc. + +// FIXME: Mod is not defined for float and double... + + + + + + +# define mln_internal_set_builtin_trait_is_promotion_(Name) \ + \ + template <typename Bl, typename Br> \ + struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \ + { \ + typedef mln_trait_promote(Bl, Br) ret; \ + }; \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_set_builtin_trait_is_bool_(Name) \ + \ + template <typename Bl, typename Br> \ + struct set_binary_< Name, mln::value::Built_In, Bl, mln::value::Built_In, Br > \ + { \ + typedef bool ret; \ + }; \ + \ + struct m_a_c_r_o__e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + +namespace mln +{ + + namespace trait + { + + // A couple of builtins => promotion. + + mln_internal_set_builtin_trait_is_promotion_(op::plus); + mln_internal_set_builtin_trait_is_promotion_(op::minus); + mln_internal_set_builtin_trait_is_promotion_(op::times); + mln_internal_set_builtin_trait_is_promotion_(op::div); + mln_internal_set_builtin_trait_is_promotion_(op::mod); + + // FIXME: other (such as plus_eq)... + + + template< template <class> class Name, + typename B > + struct set_unary_< Name, + mln::value::Built_In, B > + { + typedef B ret; // FIXME: Wrong! + }; + + + // Operators "Object OP Built_In" => "Object OP scalar_" + + template <typename O, typename B> + struct set_binary_< op::plus, mln::Object, O, mln::value::Built_In, B > + { + typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret; + }; + + template <typename O, typename B> + struct set_binary_< op::minus, mln::Object, O, mln::value::Built_In, B > + { + typedef mln_trait_op_minus(O, mln::value::scalar_<B>) ret; + }; + + template <typename O, typename B> + struct set_binary_< op::times, mln::Object, O, mln::value::Built_In, B > + { + typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret; + }; + + template <typename O, typename B> + struct set_binary_< op::div, mln::Object, O, mln::value::Built_In, B > + { + typedef mln_trait_op_div(O, mln::value::scalar_<B>) ret; + }; + + template <typename O, typename B> + struct set_binary_< op::mod, mln::Object, O, mln::value::Built_In, B > + { + typedef mln_trait_op_mod(O, mln::value::scalar_<B>) ret; + }; + + + // 'Op+' is commutative so "o + b" => "o + scalar(b)". + + template <typename B, typename O> + struct set_binary_< op::plus, mln::value::Built_In, B, mln::Object, O > + { + typedef mln_trait_op_plus(O, mln::value::scalar_<B>) ret; + }; + + // Likewise for 'Op*'. + + template <typename B, typename O> + struct set_binary_< op::times, mln::value::Built_In, B, mln::Object, O > + { + typedef mln_trait_op_times(O, mln::value::scalar_<B>) ret; + }; + + + // 'Op-' is tricky for "b - o" => "(-o) + scalar(b)". + + template <typename B, typename O> + struct set_binary_< op::minus, mln::value::Built_In, B, mln::Object, O > + { + typedef mln_trait_op_uminus(O) minus_O; + typedef mln_trait_op_plus(minus_O, mln::value::scalar_<B>) ret; + }; + + + // 'Op/' for "b / o" => "scalar(b) / o". + + template <typename B, typename O> + struct set_binary_< op::div, mln::value::Built_In, B, mln::Object, O > + { + typedef mln_trait_op_div(mln::value::scalar_<B>, O) ret; + }; + + // Likewise for 'Op%'. + + template <typename B, typename O> + struct set_binary_< op::mod, mln::value::Built_In, B, mln::Object, O > + { + typedef mln_trait_op_mod(mln::value::scalar_<B>, O) ret; + }; + + + } // end of namespace mln::trait + + + mln_internal_op_obj_builtins_(decl, +, plus); + mln_internal_op_obj_builtins_(decl, -, minus); + mln_internal_op_obj_builtins_(decl, *, times); + mln_internal_op_obj_builtins_(decl, /, div); + mln_internal_op_obj_builtins_(decl, %, mod); + + // Op+ and op* respectively commute: + mln_internal_builtins_op_obj_(decl, +, plus); + mln_internal_builtins_op_obj_(decl, *, times); + + // Op "builtin - object" is special: + mln_internal_builtins_minus_obj_(decl); + + + // Ops "bi / obj" and "bi % obj" + mln_internal_builtins_dvmd_obj_(decl, /, div); + mln_internal_builtins_dvmd_obj_(decl, %, mod); + + +# ifndef MLN_INCLUDE_ONLY + + mln_internal_op_obj_builtins_(def, +, plus); + mln_internal_op_obj_builtins_(def, -, minus); + mln_internal_op_obj_builtins_(def, *, times); + mln_internal_op_obj_builtins_(def, /, div); + mln_internal_op_obj_builtins_(def, %, mod); + + // Op+ and op* respectively commute: + mln_internal_builtins_op_obj_(def, +, plus); + mln_internal_builtins_op_obj_(def, *, times); + + // Op "builtin - object" is special: + mln_internal_builtins_minus_obj_(def); + + // Ops "bi / obj" and "bi % obj" + mln_internal_builtins_dvmd_obj_(def, /, div); + mln_internal_builtins_dvmd_obj_(def, %, mod); + + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_VALUE_BUILTIN_OPS_HH Index: mln/value/builtin/symbolics.hh --- mln/value/builtin/symbolics.hh (revision 0) +++ mln/value/builtin/symbolics.hh (revision 0) @@ -0,0 +1,71 @@ +// 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 MLN_VALUE_BUILTIN_SYMBOLICS_HH +# define MLN_VALUE_BUILTIN_SYMBOLICS_HH + +/*! \file mln/value/builtin/symbolics.hh + * + * \brief Some definitions about built-in symbolic types. + */ + +# include <mln/value/concept/built_in.hh> +# include <mln/value/concept/symbolic.hh> +# include <mln/trait/value_.hh> + + +namespace mln +{ + + + template <> + struct category< bool > + { + typedef value::Built_In<void*> ret; + typedef value::Symbolic<void> super; + }; + + + namespace trait + { + + template <> + struct value_< bool> + { + typedef metal::int_<1> nbits; + typedef value::nature::symbolic nature; + typedef value::kind::binary kind; + typedef value::quant::low quant; + typedef metal::int_<2> card; + }; + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_VALUE_BUILTIN_SYMBOLICS_HH Index: mln/value/builtin/floatings.hh --- mln/value/builtin/floatings.hh (revision 0) +++ mln/value/builtin/floatings.hh (revision 0) @@ -0,0 +1,90 @@ +// 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 MLN_VALUE_BUILTIN_FLOATINGS_HH +# define MLN_VALUE_BUILTIN_FLOATINGS_HH + +/*! \file mln/value/builtin/floatings.hh + * + * \brief Some definitions about built-in floating types. + */ + +# include <mln/value/concept/built_in.hh> +# include <mln/value/concept/floating.hh> +# include <mln/trait/value_.hh> + + +namespace mln +{ + + + template <> + struct category< float > + { + typedef value::Built_In<void*> ret; + typedef value::Floating<void> super; + }; + + template <> + struct category< double > + { + typedef value::Built_In<void*> ret; + typedef value::Floating<void> super; + }; + + + namespace trait + { + + template <> + struct value_< float > + { + typedef metal::int_<8*sizeof(float)> nbits; + typedef value::nature::floating nature; + typedef value::kind::data kind; + typedef metal::int_<0> card; + typedef value::quant::high quant; + typedef float sum; + }; + + template <> + struct value_< double > + { + typedef metal::int_<8*sizeof(double)> nbits; + typedef value::nature::floating nature; + typedef value::kind::data kind; + typedef metal::int_<0> card; + typedef value::quant::high quant; + typedef double sum; + }; + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_VALUE_BUILTIN_FLOATINGS_HH Index: mln/value/builtin/all.hh --- mln/value/builtin/all.hh (revision 0) +++ mln/value/builtin/all.hh (revision 0) @@ -0,0 +1,45 @@ +// 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 MLN_VALUE_BUILTIN_ALL_HH +# define MLN_VALUE_BUILTIN_ALL_HH + +/*! \file mln/value/builtin/all.hh + * + * \brief File that includes all materials related to built-in types. + */ + + +# include <mln/value/builtin/symbolics.hh> +# include <mln/value/builtin/integers.hh> +# include <mln/value/builtin/floatings.hh> + +# include <mln/value/builtin/promotions.hh> +# include <mln/value/builtin/ops.hh> + + +#endif // ! MLN_VALUE_BUILTIN_ALL_HH Index: mln/value/builtin/promotions.hh --- mln/value/builtin/promotions.hh (revision 0) +++ mln/value/builtin/promotions.hh (revision 0) @@ -0,0 +1,204 @@ +// 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 MLN_VALUE_BUILTIN_PROMOTIONS_HH +# define MLN_VALUE_BUILTIN_PROMOTIONS_HH + +/*! \file mln/value/builtin/promotions.hh + * + * \brief Definitions of promotions between built-in types. + */ + +# include <mln/trait/promote.hh> +# include <mln/metal/ret.hh> + + +# define mln_internal_set_promotion_(Builtin1, Builtin2, Result) \ + \ + template<> \ + struct set_precise_binary_< promote, Builtin1, Builtin2 > \ + { \ + typedef Result ret; \ + }; \ + \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n \ + + +# define mln_internal_set_promotion_auto_(From, To) \ + \ + mln_internal_set_promotion_(From, To, To); \ + mln_internal_set_promotion_(To, From, To); \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_set_promotion_twice_(From, To) \ + \ + mln_internal_set_promotion_(From, From, To); \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_set_promotion_bi_(From1, From2, To) \ + \ + mln_internal_set_promotion_(From1, From2, To); \ + mln_internal_set_promotion_(From2, From1, To); \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_set_uminus_bi_(Builtin, Result) \ + \ + template<> \ + struct set_precise_unary_< op::uminus, Builtin > \ + { \ + typedef Result ret; \ + }; \ + \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + +# define mln_internal_set_uplus_bi_(Builtin) \ + \ + template<> \ + struct set_precise_unary_< op::uplus, Builtin > \ + { \ + typedef Builtin ret; \ + }; \ + \ + struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_u_m_n + + + +namespace mln +{ + + // Fwd decl. + namespace value { template <typename B> struct Built_In; } + + + namespace trait + { + + // Builtin binary traits. + + + mln_internal_set_promotion_bi_(unsigned char, signed char, int); + mln_internal_set_promotion_bi_(unsigned short, signed char, int); + mln_internal_set_promotion_bi_(unsigned int, signed char, int); + mln_internal_set_promotion_bi_(unsigned long, signed char, long); + + mln_internal_set_promotion_bi_(unsigned short, signed short, int); + mln_internal_set_promotion_bi_(unsigned int, signed short, int); + mln_internal_set_promotion_bi_(unsigned long, signed short, long); + + mln_internal_set_promotion_bi_(unsigned long, signed int, long); + + + mln_internal_set_promotion_twice_(unsigned char, unsigned); + mln_internal_set_promotion_twice_( signed char, int); + mln_internal_set_promotion_twice_(unsigned short, unsigned); + mln_internal_set_promotion_twice_( signed short, int); + mln_internal_set_promotion_twice_(unsigned int, unsigned); + mln_internal_set_promotion_twice_( signed int, int); + mln_internal_set_promotion_twice_(unsigned long, unsigned long); + mln_internal_set_promotion_twice_( signed long, long); + + mln_internal_set_promotion_twice_( float, float); + mln_internal_set_promotion_twice_( double, double); + + + mln_internal_set_promotion_auto_(unsigned char, unsigned short); + mln_internal_set_promotion_auto_(unsigned char, signed short); + mln_internal_set_promotion_auto_( signed char, signed short); + + mln_internal_set_promotion_auto_(unsigned char, unsigned int); + mln_internal_set_promotion_auto_(unsigned char, signed int); + mln_internal_set_promotion_auto_( signed char, signed int); + mln_internal_set_promotion_auto_(unsigned short, unsigned int); + mln_internal_set_promotion_auto_(unsigned short, signed int); + mln_internal_set_promotion_auto_( signed short, signed int); + mln_internal_set_promotion_auto_(unsigned int, signed int); + + mln_internal_set_promotion_auto_(unsigned char, unsigned long); + mln_internal_set_promotion_auto_(unsigned char, signed long); + mln_internal_set_promotion_auto_( signed char, signed long); + mln_internal_set_promotion_auto_(unsigned short, unsigned long); + mln_internal_set_promotion_auto_(unsigned short, signed long); + mln_internal_set_promotion_auto_( signed short, signed long); + mln_internal_set_promotion_auto_(unsigned int, unsigned long); + mln_internal_set_promotion_auto_(unsigned int, signed long); + mln_internal_set_promotion_auto_( signed int, signed long); + + mln_internal_set_promotion_auto_(unsigned char, float); + mln_internal_set_promotion_auto_( signed char, float); + mln_internal_set_promotion_auto_(unsigned short, float); + mln_internal_set_promotion_auto_( signed short, float); + mln_internal_set_promotion_auto_(unsigned int, float); + mln_internal_set_promotion_auto_( signed int, float); + mln_internal_set_promotion_auto_(unsigned long, float); + mln_internal_set_promotion_auto_( signed long, float); + + mln_internal_set_promotion_auto_(unsigned char, double); + mln_internal_set_promotion_auto_( signed char, double); + mln_internal_set_promotion_auto_(unsigned short, double); + mln_internal_set_promotion_auto_( signed short, double); + mln_internal_set_promotion_auto_(unsigned int, double); + mln_internal_set_promotion_auto_( signed int, double); + mln_internal_set_promotion_auto_(unsigned long, double); + mln_internal_set_promotion_auto_( signed long, double); + + mln_internal_set_promotion_auto_( float, double); + + + // Builtin unary traits. + + mln_internal_set_uplus_bi_(unsigned char ); + mln_internal_set_uplus_bi_( signed char ); + mln_internal_set_uplus_bi_(unsigned short); + mln_internal_set_uplus_bi_( signed short); + mln_internal_set_uplus_bi_(unsigned int ); + mln_internal_set_uplus_bi_( signed int ); + mln_internal_set_uplus_bi_(unsigned long ); + mln_internal_set_uplus_bi_( signed long ); + mln_internal_set_uplus_bi_( float ); + mln_internal_set_uplus_bi_( double ); + + mln_internal_set_uminus_bi_(unsigned char, unsigned char); + mln_internal_set_uminus_bi_( signed char, signed char); + mln_internal_set_uminus_bi_(unsigned short, unsigned short); + mln_internal_set_uminus_bi_( signed short, signed short); + mln_internal_set_uminus_bi_(unsigned int, unsigned int); + mln_internal_set_uminus_bi_( signed int, signed int); + mln_internal_set_uminus_bi_(unsigned long, unsigned long); + mln_internal_set_uminus_bi_( signed long, signed long); + mln_internal_set_uminus_bi_( float, float); + mln_internal_set_uminus_bi_( double, double); + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_VALUE_BUILTIN_PROMOTIONS_HH Index: mln/value/builtin/integers.hh --- mln/value/builtin/integers.hh (revision 0) +++ mln/value/builtin/integers.hh (revision 0) @@ -0,0 +1,109 @@ +// 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 MLN_VALUE_BUILTIN_INTEGERS_HH +# define MLN_VALUE_BUILTIN_INTEGERS_HH + +/*! \file mln/value/builtin/integers.hh + * + * \brief Some definitions about built-in integer types. + */ + +# include <mln/value/concept/built_in.hh> +# include <mln/value/concept/integer.hh> +# include <mln/trait/value_.hh> + +# include <mln/metal/int.hh> +# include <mln/metal/if.hh> +# include <mln/metal/bool.hh> + + +namespace mln +{ + + template <> struct category< unsigned char > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< signed char > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< unsigned short > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< signed short > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< unsigned int > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< signed int > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< unsigned long > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + template <> struct category< signed long > { typedef value::Built_In<void*> ret; typedef value::Integer<void> super; }; + + + namespace trait + { + + // FIXME: Move the definitions below elsewhere. + + namespace internal + { + + template < bool small_n /* = true */, unsigned n_bits > + struct helper_card_ + { + typedef metal::math::pow_int<2, n_bits> pow_; + typedef metal::int_<pow_::value> card; + }; + + template < unsigned n_bits > + struct helper_card_< false, n_bits > + { + typedef metal::int_<0> card; + }; + + } // end of namespace mln::trait::internal + + + template <unsigned n_bits> + struct value_integer_ + { + typedef typename internal::helper_card_<(n_bits <= 16), n_bits>::card card; + + typedef metal::int_<n_bits> nbits; + typedef trait::value::nature::integer nature; + typedef trait::value::kind::data kind; + typedef mln_value_quant_from_card(card) quant; + typedef float sum; + }; + + + template <> struct value_< unsigned char > : value_integer_< 8 * sizeof(unsigned char) > {}; + template <> struct value_< signed char > : value_integer_< 8 * sizeof( signed char) > {}; + template <> struct value_< unsigned short > : value_integer_< 8 * sizeof(unsigned short) > {}; + template <> struct value_< signed short > : value_integer_< 8 * sizeof( signed short) > {}; + template <> struct value_< unsigned int > : value_integer_< 8 * sizeof(unsigned int) > {}; + template <> struct value_< signed int > : value_integer_< 8 * sizeof( signed int) > {}; + template <> struct value_< unsigned long > : value_integer_< 8 * sizeof(unsigned long) > {}; + template <> struct value_< signed long > : value_integer_< 8 * sizeof( signed long) > {}; + + } // end of namespace mln::trait + +} // end of namespace mln + + +#endif // ! MLN_VALUE_BUILTIN_INTEGERS_HH Index: mln/value/rgb.hh --- mln/value/rgb.hh (revision 1381) +++ mln/value/rgb.hh (working copy) @@ -34,8 +34,11 @@ * n-bit encoded. */ -# include <mln/value/concept/structured.hh> -# include <mln/value/int_u8.hh> +# include <mln/value/ops.hh> + +# include <mln/value/concept/vectorial.hh> +# include <mln/value/int_u.hh> +# include <mln/metal/vec.hh> namespace mln @@ -53,45 +56,47 @@ } /// \} + namespace value { - - typedef int_u8 int_u8_x3_t[3]; - typedef unsigned char uchar_x3_t[3]; - typedef float float_x3_t[3]; - - /*! \brief Color class for red-green-blue where every component is * n-bit encoded. */ template <unsigned n> - struct rgb : public Structured< rgb<n> > + struct rgb + : + public Vectorial< rgb<n> > + , + public internal::value_like_< metal::vec< 3, int_u<n> >, // Equivalent. + metal::vec< 3, int_u<n> >, // Encoding. + metal::vec< 3, int >, // Interoperation. + rgb<n> > // Exact. { public: - /// Encoding associated type. - typedef int_u<n> enc; - - /// Equivalent associated type. - typedef int_u<n> equiv[3]; - /// \{ Acces to red/green/blue component. - int_u<n> red() const { return c_[0]; } - int_u<n>& red() { return c_[0]; } + int_u<n> red() const { return this->v_[0]; } + int_u<n>& red() { return this->v_[0]; } - int_u<n> green() const { return c_[1]; } - int_u<n>& green() { return c_[1]; } + int_u<n> green() const { return this->v_[1]; } + int_u<n>& green() { return this->v_[1]; } - int_u<n> blue() const { return c_[2]; } - int_u<n>& blue() { return c_[2]; } + int_u<n> blue() const { return this->v_[2]; } + int_u<n>& blue() { return this->v_[2]; } /// \} - /// \{ Ctors + /// Constructor without argument. rgb<n>(); - rgb<n>(equiv a); - rgb<n>(enc r, enc g, enc b); - //rgb<n>(enc l); + + /// Constructor from component values. + rgb<n>(int r, int g, int b); + + /// Constructor from a metal::vec. + rgb<n>(const metal::vec<3, int>& rhs); + rgb<n>(const metal::vec<3, int_u<n> >& rhs); + + /// \{ Constructors with literals. rgb<n>(const literal::white_t&); rgb<n>(const literal::black_t&); rgb<n>(const literal::blue_t&); @@ -99,62 +104,39 @@ rgb<n>(const literal::green_t&); /// \} - /// \{ Assignments. - rgb<n>& operator=(const rgb<n>& v); - rgb<n>& operator=(const enc& i); - /// \} + /// Assignment. + rgb<n>& operator=(const rgb<n>& rhs); /// Zero value. static const rgb<n> zero; - /// addition - rgb<n> operator+(const rgb<n>& v) const; - // FIXME: was: -// rgb<n> operator+(const enc& i) const; -// rgb<n> operator+(const size_t& i) const; - - /// substraction - rgb<n> operator-(const rgb<n>& v) const; - // FIXME: was: -// rgb<n> operator-(const enc& i) const; -// rgb<n> operator-(const size_t& i) const; - - /// multiplication - rgb<n> operator*(const enc& i) const; // FIXME: Use int instead of enc... - - /// division - rgb<n> operator/(const enc& i) const; // FIXME: Likewise! - - /// Self addition - rgb<n>& operator+=(const rgb<n>& v); - - /// Self subtraction. - rgb<n>& operator-=(const rgb<n>& v); - - /// Comparaison. - bool operator=(const rgb<n>& v) const; - bool operator!=(const rgb<n>& v) const; - /// hook to coord's buffer - const enc* buffer() const; + // FIXME: Cannot work for i negative; move operators outside the class; add traits! + + + /// Addition. + rgb<n> operator+(const rgb<n>& rhs) const; - private: - equiv c_; + /// Substraction. + rgb<n> operator-(const rgb<n>& rhs) const; + + /// Multiplication. + rgb<n> operator*(int i) const; + + /// Division. + rgb<n> operator/(int i) const; }; + template <unsigned n> struct props< rgb<n> > { - static const unsigned nbits = 24; + static const unsigned nbits = 3 * n; static const std::size_t card_ = 0; // FIXME: was: metal::math::pow_int<2, nbits>::value; typedef trait::value::kind::color kind; - typedef float_x3_t sum; - typedef uchar_x3_t interop; - - // FIXME: was: -// static const rgb<n> max() { rgb<n> c(props< int_u<n> >::max); return c; } -// static const rgb<n> min() { const rgb<n> c(props< int_u<n> >::min()); return c; } + typedef metal::vec<3, float> sum; + typedef metal::vec<3, int> interop; }; @@ -168,6 +150,9 @@ template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const rgb<n>& c); + template <unsigned n> + std::istream& operator>>(std::istream& istr, rgb<n>& c); + # ifndef MLN_INCLUDE_ONLY @@ -177,81 +162,78 @@ } template <unsigned n> - rgb<n>::rgb(equiv a) + rgb<n>::rgb(const metal::vec<3, int>& v) { - std::memcpy(this->c_, a, 3 * sizeof(enc)); + this->v_ = v; } template <unsigned n> - rgb<n>::rgb(enc r, enc g, enc b) + rgb<n>::rgb(const metal::vec<3, int_u<n> >& v) { - this->c_[0] = r; - this->c_[1] = g; - this->c_[2] = b; + this->v_ = v; } -// template <unsigned n> -// rgb<n>::rgb(enc l) -// { -// this->c_[0] = l; -// this->c_[1] = l; -// this->c_[2] = l; -// } + template <unsigned n> + rgb<n>::rgb(int r, int g, int b) + { + mln_precondition(r >= 0); + mln_precondition(g >= 0); + mln_precondition(b >= 0); + mln_precondition(unsigned(r) <= mln_max(int_u<n>)); + mln_precondition(unsigned(g) <= mln_max(int_u<n>)); + mln_precondition(unsigned(b) <= mln_max(int_u<n>)); + this->v_[0] = r; + this->v_[1] = g; + this->v_[2] = b; + } template <unsigned n> rgb<n>::rgb(const literal::white_t&) { - this->c_[0] = mln_max(enc); - this->c_[1] = mln_max(enc); - this->c_[2] = mln_max(enc); + this->v_[0] = mln_max(int_u<n>); + this->v_[1] = mln_max(int_u<n>); + this->v_[2] = mln_max(int_u<n>); } template <unsigned n> rgb<n>::rgb(const literal::black_t&) { - this->c_[0] = 0; - this->c_[1] = 0; - this->c_[2] = 0; + this->v_[0] = 0; + this->v_[1] = 0; + this->v_[2] = 0; } template <unsigned n> rgb<n>::rgb(const literal::red_t&) { - this->c_[0] = mln_max(enc); - this->c_[1] = 0; - this->c_[2] = 0; + this->v_[0] = mln_max(int_u<n>); + this->v_[1] = 0; + this->v_[2] = 0; } template <unsigned n> rgb<n>::rgb(const literal::green_t&) { - this->c_[0] = 0; - this->c_[1] = mln_max(enc); - this->c_[2] = 0; + this->v_[0] = 0; + this->v_[1] = mln_max(int_u<n>); + this->v_[2] = 0; } template <unsigned n> rgb<n>::rgb(const literal::blue_t&) { - this->c_[0] = 0; - this->c_[1] = 0; - this->c_[2] = mln_max(enc); + this->v_[0] = 0; + this->v_[1] = 0; + this->v_[2] = mln_max(int_u<n>); } template <unsigned n> rgb<n>& - rgb<n>::operator=(const rgb<n>& v) + rgb<n>::operator=(const rgb<n>& rhs) { - std::memcpy(this->c_, v.c_, 3 * sizeof(enc)); + if (& rhs = this) return *this; - } - - template <unsigned n> - rgb<n>& - rgb<n>::operator=(const enc& v) - { - for (int i = 0; i < 3; i++) - this->c_[i] = v; + this->v_ = rhs.v_; return *this; } @@ -260,130 +242,49 @@ template <unsigned n> rgb<n> - rgb<n>::operator-(const rgb<n>& v) const - { - rgb<n> res; - for (int i = 0; i < 3; i++) - res.c_[i] = this->c_[i] - v.c_[i]; - return res; - } - -// template <unsigned n> -// rgb<n> -// rgb<n>::operator-(const size_t& i_) const -// { -// enc i(i_); -// return (*this - i); -// } - -// template <unsigned n> -// rgb<n> -// rgb<n>::operator-(const enc& i) const -// { -// rgb<n> res; -// for (int j = 0; j < 3; j++) -// res.c_[j] = this->c_[j] - i; -// return res; -// } - - template <unsigned n> - rgb<n> - rgb<n>::operator+(const rgb<n>& v) const + rgb<n>::operator-(const rgb<n>& rhs) const { - rgb<n> res; - for (int i = 0; i < 3; i++) - res.c_[i] = this->c_[i] + v.c_[i]; - return res; - } - -// template <unsigned n> -// rgb<n> -// rgb<n>::operator+(const size_t& i_) const -// { -// enc i(i_); -// return (*this + i); -// } - -// template <unsigned n> -// rgb<n> -// rgb<n>::operator+(const enc& i) const -// { -// rgb<n> res; -// for (int j = 0; j < 3; j++) -// res.c_[j] = this->c_[j] + i; -// return res; -// } - - template <unsigned n> - rgb<n>& - rgb<n>::operator+=(const rgb<n>& v) - { - for (int i = 0; i < 3; i++) - this->c_[i] += v.c_[i]; - return *this; + rgb<n> tmp(this->v_ - rhs.v_); + return tmp; } template <unsigned n> - rgb<n>& - rgb<n>::operator-=(const rgb<n>& v) + rgb<n> + rgb<n>::operator+(const rgb<n>& rhs) const { - for (int i = 0; i < 3; i++) - this->c_[i] += v.c_[i]; - return *this; + rgb<n> tmp(this->v_ + rhs.v_); + return tmp; } template <unsigned n> rgb<n> - rgb<n>::operator*(const enc& i) const + rgb<n>::operator*(int i) const { - rgb<n> res; - for (int j = 0; j < 3; j++) - res.c_[j] = this->c_[j] * i; - return res; + rgb<n> tmp(this->v_ * i); + return tmp; } template <unsigned n> rgb<n> - rgb<n>::operator/(const enc& i) const + rgb<n>::operator/(int i) const { - rgb<n> res; - for (int j = 0; j < 3; j++) - res.c_[j] = this->c_[j] * i; - return res; + rgb<n> tmp(this->v_ / i); + return tmp; } - template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const rgb<n>& v) { - return ostr << "(R:" << debug::format(v.red()) - << ", G:" << debug::format(v.green()) - << ", B:" << debug::format(v.blue()) + return ostr << "(r" << debug::format(v.red()) + << ", g" << debug::format(v.green()) + << ", b" << debug::format(v.blue()) << ")"; } template <unsigned n> - bool - rgb<n>::operator=(const rgb<n>& v) const - { - return (this->green() = v.green() && - this->red() = v.red() && - this->blue() = v.blue()); - } - - template <unsigned n> - bool - rgb<n>::operator!=(const rgb<n>& v) const - { - return (!(*this = v)); - } - - - template <unsigned n> - const int_u<n> * - rgb<n>::buffer() const + std::istream& operator>>(std::istream& istr, rgb<n>& c) { - return c_; + return istr >> c.red() >> c.green() >> c.blue(); } # endif // ! MLN_INCLUDE_ONLY Index: mln/value/float01_f.hh --- mln/value/float01_f.hh (revision 1381) +++ mln/value/float01_f.hh (working copy) @@ -48,7 +48,7 @@ struct float01; - /// General float01_f class on n bits. + /// Class for floating values restricted to the interval [0..1]. struct float01_f : public Floating< float01_f >, @@ -58,20 +58,20 @@ float, // Interoperation. float01_f > // Exact. { - /// Ctor. + /// Constructor without argument. float01_f(); - /// Ctor. + /// Constructor from a float. float01_f(float val); - /// Access to std type. + /// Assignment from a float. + float01_f& operator=(const float val); + + /// Access to float value. float value() const; - /// Op encoding_t. + /// Conversion to a float. operator float() const; - - /// Assigment with float. - float01_f& operator=(const float val); }; Index: mln/convert/to_rgb.hh --- mln/convert/to_rgb.hh (revision 1381) +++ mln/convert/to_rgb.hh (working copy) @@ -31,6 +31,8 @@ /*! \file mln/convert/to_rgb.hh * * \brief Conversions to mln::value::rgb. + * + * \todo Re-write. */ @@ -41,6 +43,7 @@ { using namespace value; + /// Convert a int_u \p val into rgb value. template <unsigned int n> rgb<n> to_rgb(const int_u<n>& i); @@ -51,6 +54,7 @@ template <unsigned int n> const rgb<n>& to_rgb(const rgb<n>& i); + # ifndef MLN_INCLUDE_ONLY template <unsigned int n> Index: mln/io/pnm/save_header.hh --- mln/io/pnm/save_header.hh (revision 1381) +++ mln/io/pnm/save_header.hh (working copy) @@ -58,14 +58,14 @@ void save_max_val(V&, std::ofstream& file) { if (mln_max(V) > 1) - file << mln_max(V) << std::endl; + file << unsigned(mln_max(V)) << std::endl; } template <unsigned int n> void save_max_val(value::rgb<n>&, std::ofstream& file) { - typedef typename value::rgb<n>::enc E; - file << mln_max(E) << std::endl; + typedef typename value::int_u<n>::enc E; + file << unsigned(mln_max(E)) << std::endl; } template <typename I> Index: mln/io/pnm/save.hh --- mln/io/pnm/save.hh (revision 1381) +++ mln/io/pnm/save.hh (working copy) @@ -79,7 +79,7 @@ void write_value(std::ofstream& file, const value::rgb<n>& c) { - typedef typename value::rgb<n>::enc::enc E; + typedef typename value::int_u<n>::enc E; E v = c.red().to_enc(); file.write((char*)&v, sizeof(E)); Index: mln/io/pnm/load.hh --- mln/io/pnm/load.hh (revision 1381) +++ mln/io/pnm/load.hh (working copy) @@ -63,7 +63,7 @@ void read_value(std::ifstream& file, value::rgb<n>& v) { - typedef typename value::rgb<n>::enc::enc E; + typedef typename value::int_u<n>::enc E; E c; file.read((char*)(&c), sizeof(E)); @@ -124,13 +124,7 @@ { mln_fwd_piter(I) p(ima.domain()); for_all(p) - { - unsigned value; - file >> value; - ima(p) = value; - // FIXME: Test alt code below. - // file >> ima(p); - } + file >> ima(p); } /// load_raw_2d. Index: img/lena.ppm Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: img/lena.ppm ___________________________________________________________________ Name: svn:mime-type + application/octet-stream