- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# element_ops.hxx

    00001 // element_ops.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
    00006 //
    00007 // This program is free software; you can redistribute it and/or
    00008 // modify it under the terms of the GNU General Public License
    00009 // as published by the Free Software Foundation; either version 2
    00010 // of the License, or (at your option) any later version.
    00011 //
    00012 // The complete GNU General Public Licence Notice can be found as the
    00013 // `COPYING' file in the root directory.
    00014 //
    00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
    00016 //
    00017 #ifndef VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX
    00018 # define VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX
    00019
    00020 # include <vaucanson/design_pattern/element_ops.hh>
    00021
    00022 # include <vaucanson/misc/selectors.hh>
    00023 # include <vaucanson/misc/static.hh>
    00024 # include <vaucanson/misc/unique.hh>
    00025
    00026 namespace vcsn {
    00027
    00028   /*-------------------------.
    00029   | Operator prototype forms |
    00030   `-------------------------*/
    00031
    00032 #define ELEMENT_OP_PROTO_SYM(Op, Ret)                           \
    00033 template<typename S1, typename T1, typename S2, typename T2>    \
    00034 static                                                          \
    00035 Ret                                                             \
    00036 operator Op(const Element<S1, T1>& e1,                          \
    00037             const Element<S2, T2>& e2)
    00038
    00039 #define ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, Ret)          \
    00040 template<typename S1, typename T1, typename T2>         \
    00041 static                                                  \
    00042 Ret                                                     \
    00043 operator Op(const Element<S1, T1>& e1, const T2& e2)
    00044
    00045 #define ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, Ret)         \
    00046 template<typename T1, typename S2, typename T2>         \
    00047 static                                                  \
    00048 Ret                                                     \
    00049 operator Op(const T1& e1, const Element<S2, T2>& e2)
    00050
    00051   /*--------------------------.
    00052   | Standard delegation forms |
    00053   `--------------------------*/
    00054
    00055 #define DELEGATE_SYM(OpName) \
    00056  return op_ ## OpName(e1.structure(), e2.structure(), e1.value(), e2.value())
    00057
    00058 #define DELEGATE_LEFT_FOREIGN(OpName) \
    00059   return op_ ## OpName(e1.structure(),                                  \
    00060                        e1.value(),                                      \
    00061                        op_convert(e1.structure(), SELECT(T1), e2))
    00062
    00063 #define DELEGATE_RIGHT_FOREIGN(OpName) \
    00064   return op_ ## OpName(e2.structure(),                                  \
    00065                        op_convert(e2.structure(), SELECT(T2), e1),      \
    00066                        e2.value())
    00067
    00068
    00069   /*-----------------------------.
    00070   | Standard Boolean delegations |
    00071   `-----------------------------*/
    00072
    00073 #define BOOLEAN_DELEGATION(Op, OpName)          \
    00074   ELEMENT_OP_PROTO_SYM(Op, bool)                \
    00075   {                                             \
    00076     DELEGATE_SYM(OpName);                       \
    00077   }                                             \
    00078                                                 \
    00079   ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, bool)       \
    00080   {                                             \
    00081     DELEGATE_LEFT_FOREIGN(OpName);              \
    00082   }                                             \
    00083                                                 \
    00084   ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, bool)      \
    00085   {                                             \
    00086     DELEGATE_RIGHT_FOREIGN(OpName);             \
    00087   }
    00088
    00089   BOOLEAN_DELEGATION(==, eq)
    00090   BOOLEAN_DELEGATION(<, lt)
    00091 #undef BOOLEAN_DELEGATION
    00092
    00093 #define BOOLEAN_CANONICAL_DELEGATION(Op, Not, E1, Del, E2)      \
    00094   ELEMENT_OP_PROTO_SYM(Op, bool)                                \
    00095   {                                                             \
    00096     return Not (e ## E1 Del e ## E2);                           \
    00097   }                                                             \
    00098                                                                 \
    00099   ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, bool)                       \
    00100   {                                                             \
    00101     return Not (e ## E1 Del e ## E2);                           \
    00102   }                                                             \
    00103                                                                 \
    00104   ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, bool)                      \
    00105   {                                                             \
    00106     return Not (e ## E1 Del e ## E2);                           \
    00107   }
    00108
    00109   BOOLEAN_CANONICAL_DELEGATION(!=, !, 1, ==, 2)
    00110   BOOLEAN_CANONICAL_DELEGATION(> ,  , 2, <, 1)
    00111   BOOLEAN_CANONICAL_DELEGATION(>=, !, 1, <, 2)
    00112   BOOLEAN_CANONICAL_DELEGATION(<=, !, 2, <, 1)
    00113 #undef BOOLEAN_CANONICAL_DELEGATION
    00114
    00115 #undef ELEMENT_PROTO_SYM
    00116 #undef ELEMENT_PROTO_LEFT_FOREIGN
    00117 #undef ELEMENT_PROTO_RIGHT_FOREIGN
    00118 #undef DELEGATE_SYM
    00119 #undef DELEGATE_LEFT_FOREIGN
    00120 #undef DELEGATE_RIGHT_FOREIGN
    00121
    00122     /*----------------------------------.
    00123     | Standard arithmetical delegations |
    00124     `----------------------------------*/
    00125
    00126 #define ELEMENT_OPERATOR(Op, HookName)                                  \
    00127 template<typename S1, typename T1, typename S2, typename T2>            \
    00128 static                                                                  \
    00129 typename op_##HookName##_traits<S1, S2, T1, T2>::ret_t                  \
    00130 operator Op(const Element<S1, T1>& e1, const Element<S2, T2>& e2)       \
    00131 {                                                                       \
    00132   /* Compute return Element type */                                     \
    00133   typedef typename op_##HookName##_traits<S1, S2, T1, T2>::ret_t ret_t; \
    00134                                                                         \
    00135   /* Compute return structural element from return Element type */      \
    00136   const bool want_s1 = misc::static_eq<S1, typename ret_t::set_t>::value; \
    00137   typedef typename misc::static_if<want_s1, S1, S2>::t ret_set_t;       \
    00138   const ret_set_t& s = misc::static_if<want_s1, const S1, const S2>::   \
    00139     choose(e1.structure(), e2.structure());                             \
    00140                                                                         \
    00141   /* Delegate */                                                        \
    00142   return Element<ret_set_t, typename ret_t::value_t>                    \
    00143     (s, op_##HookName(e1.structure(),                                   \
    00144                       e2.structure(),                                   \
    00145                       e1.value(),                                       \
    00146                       e2.value()));                                     \
    00147 }                                                                       \
    00148                                                                         \
    00149 template<typename S, typename T, typename U>                            \
    00150 static                                                                  \
    00151 Element<S, T>                                                           \
    00152 operator Op(const Element<S, T>& e, const U& v)                         \
    00153 {                                                                       \
    00154   return Element<S, T> (e.structure(),                                  \
    00155                         op_##HookName(e.structure(),                    \
    00156                                       e.value(),                        \
    00157                                       op_convert(e.structure(),         \
    00158                                                  SELECT(T), v)));       \
    00159 }                                                                       \
    00160                                                                         \
    00161 template<typename U, typename S, typename T>                            \
    00162 static                                                                  \
    00163 Element<S, T>                                                           \
    00164 operator Op(const U& v, const Element<S, T>& e)                         \
    00165 {                                                                       \
    00166   return Element<S, T> (e.structure(),                                  \
    00167                         op_ ## HookName(e.structure(),                  \
    00168                                         op_convert(e.structure(),       \
    00169                                                    SELECT(T), v),       \
    00170                                         e.value()));                    \
    00171 }
    00172
    00173 ELEMENT_OPERATOR(+, add)
    00174 ELEMENT_OPERATOR(-, sub)
    00175 ELEMENT_OPERATOR(*, mul)
    00176 ELEMENT_OPERATOR(/, div)
    00177 ELEMENT_OPERATOR(%, mod)
    00178
    00179 #undef ELEMENT_OPERATOR
    00180
    00181 /*-----------------------------------------------.
    00182 | Implementation of input and output delegations |
    00183 `-----------------------------------------------*/
    00184
    00185 template<typename St, typename S, typename T>
    00186 static
    00187 St&
    00188 operator << (St& s, const Element<S, T>& e)
    00189 {
    00190   return op_rout(e.structure(), s, e.value());
    00191 }
    00192
    00193 template<typename St, typename S, typename T>
    00194 static
    00195 St&
    00196 operator >> (St& s, Element<S, T>& e)
    00197 {
    00198   S structure = e.structure();
    00199   op_rin(structure, s, e.value());
    00200   e.attach(structure);
    00201   return s;
    00202 }
    00203
    00204 /*------------------------------------------.
    00205 | Implementation of the negation delegation |
    00206 `------------------------------------------*/
    00207
    00208 template<typename S, typename T>
    00209 static
    00210 Element<S, T>
    00211 operator-(const Element<S, T>& e)
    00212 {
    00213   return Element<S, T>(e.structure(), op_neg(e.structure(), e.value()));
    00214 }
    00215
    00216 } // vcsn
    00217
    00218
    00219 /*--------------------------------------.
    00220 | Implementation of the swap delegation |
    00221 `--------------------------------------*/
    00222
    00223 namespace std
    00224 {
    00225   template<typename S, typename T1, typename T2>
    00226   void
    00227   swap(vcsn::Element<S, T1>& e1,
    00228        vcsn::Element<S, T2>& e2)
    00229   {
    00230     assertion(&e1.structure() == &e2.structure());
    00231     op_swap(e1.structure(), e1.value(), e2.value());
    00232   }
    00233
    00234   template<typename S, typename T>
    00235   void
    00236   swap(vcsn::Element<S, T>& e1, T& v2)
    00237   {
    00238     op_swap(e1.structure(), e1.value(), v2);
    00239   }
    00240
    00241   template<typename T, typename S>
    00242   void
    00243   swap(T& v1, vcsn::Element<S, T>& e2)
    00244   {
    00245     op_swap(e2.structure(), v1, e2.value());
    00246   }
    00247 } // std
    00248
    00249 #endif // ! VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX