17 #ifndef VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX
18 # define VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX
32 #define ELEMENT_OP_PROTO_SYM(Op, Ret) \
33 template<typename S1, typename T1, typename S2, typename T2> \
36 operator Op(const Element<S1, T1>& e1, \
37 const Element<S2, T2>& e2)
39 #define ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, Ret) \
40 template<typename S1, typename T1, typename T2> \
43 operator Op(const Element<S1, T1>& e1, const T2& e2)
45 #define ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, Ret) \
46 template<typename T1, typename S2, typename T2> \
49 operator Op(const T1& e1, const Element<S2, T2>& e2)
55 #define DELEGATE_SYM(OpName) \
56 return op_ ## OpName(e1.structure(), e2.structure(), e1.value(), e2.value())
58 #define DELEGATE_LEFT_FOREIGN(OpName) \
59 return op_ ## OpName(e1.structure(), \
61 op_convert(e1.structure(), SELECT(T1), e2))
63 #define DELEGATE_RIGHT_FOREIGN(OpName) \
64 return op_ ## OpName(e2.structure(), \
65 op_convert(e2.structure(), SELECT(T2), e1), \
73 #define BOOLEAN_DELEGATION(Op, OpName) \
74 ELEMENT_OP_PROTO_SYM(Op, bool) \
76 DELEGATE_SYM(OpName); \
79 ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, bool) \
81 DELEGATE_LEFT_FOREIGN(OpName); \
84 ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, bool) \
86 DELEGATE_RIGHT_FOREIGN(OpName); \
89 BOOLEAN_DELEGATION(==, eq)
90 BOOLEAN_DELEGATION(<, lt)
91 #undef BOOLEAN_DELEGATION
93 #define BOOLEAN_CANONICAL_DELEGATION(Op, Not, E1, Del, E2) \
94 ELEMENT_OP_PROTO_SYM(Op, bool) \
96 return Not (e ## E1 Del e ## E2); \
99 ELEMENT_OP_PROTO_LEFT_FOREIGN(Op, bool) \
101 return Not (e ## E1 Del e ## E2); \
104 ELEMENT_OP_PROTO_RIGHT_FOREIGN(Op, bool) \
106 return Not (e ## E1 Del e ## E2); \
109 BOOLEAN_CANONICAL_DELEGATION(!=, !, 1, ==, 2)
110 BOOLEAN_CANONICAL_DELEGATION(> , , 2, <, 1)
111 BOOLEAN_CANONICAL_DELEGATION(>=, !, 1, <, 2)
112 BOOLEAN_CANONICAL_DELEGATION(<=, !, 2, <, 1)
113 #undef BOOLEAN_CANONICAL_DELEGATION
115 #undef ELEMENT_PROTO_SYM
116 #undef ELEMENT_PROTO_LEFT_FOREIGN
117 #undef ELEMENT_PROTO_RIGHT_FOREIGN
119 #undef DELEGATE_LEFT_FOREIGN
120 #undef DELEGATE_RIGHT_FOREIGN
126 #define ELEMENT_OPERATOR(Op, HookName) \
127 template<typename S1, typename T1, typename S2, typename T2> \
129 typename op_##HookName##_traits<S1, S2, T1, T2>::ret_t \
130 operator Op(const Element<S1, T1>& e1, const Element<S2, T2>& e2) \
133 typedef typename op_##HookName##_traits<S1, S2, T1, T2>::ret_t ret_t; \
136 const bool want_s1 = misc::static_eq<S1, typename ret_t::set_t>::value; \
137 typedef typename misc::static_if<want_s1, S1, S2>::t ret_set_t; \
138 const ret_set_t& s = misc::static_if<want_s1, const S1, const S2>:: \
139 choose(e1.structure(), e2.structure()); \
142 return Element<ret_set_t, typename ret_t::value_t> \
143 (s, op_##HookName(e1.structure(), \
149 template<typename S, typename T, typename U> \
152 operator Op(const Element<S, T>& e, const U& v) \
154 return Element<S, T> (e.structure(), \
155 op_##HookName(e.structure(), \
157 op_convert(e.structure(), \
161 template<typename U, typename S, typename T> \
164 operator Op(const U& v, const Element<S, T>& e) \
166 return Element<S, T> (e.structure(), \
167 op_ ## HookName(e.structure(), \
168 op_convert(e.structure(), \
173 ELEMENT_OPERATOR(+, add)
174 ELEMENT_OPERATOR(-, sub)
175 ELEMENT_OPERATOR(*, mul)
176 ELEMENT_OPERATOR(/, div)
177 ELEMENT_OPERATOR(%, mod)
179 #undef ELEMENT_OPERATOR
185 template<
typename St,
typename S,
typename T>
188 operator << (St& s, const Element<S, T>& e)
190 return op_rout(e.structure(), s, e.value());
193 template<
typename St,
typename S,
typename T>
198 S structure = e.structure();
199 op_rin(structure, s, e.value());
208 template<
typename S,
typename T>
213 return Element<S, T>(e.structure(), op_neg(e.structure(), e.value()));
225 template<
typename S,
typename T1,
typename T2>
234 template<
typename S,
typename T>
243 template<
typename S,
typename T>
250 template<
typename T,
typename S>
258 #endif // ! VCSN_DESIGN_PATTERN_ELEMENT_OPS_HXX