00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "Watched.h"
00017
00018 #ifndef EXPRESSION_H
00019 #define EXPRESSION_H
00020
00021 #ifndef USE_PCH
00022 #include <boost/shared_ptr.hpp>
00023 #include "debug.h"
00024 #include <libcw/events.h>
00025 #endif
00026
00027 #include "ExpressionInterface.h"
00028 #include "Bool.h"
00029 #include "Counter.h"
00030
00031
00032 class ExpressionEventType {
00033 private:
00034 bool M_expression_value;
00035 #ifdef CWDEBUG
00036 boost::shared_ptr<ExpressionInterface> M_expression;
00037 #endif
00038 public:
00039 #ifdef CWDEBUG
00040 ExpressionEventType(bool value, boost::shared_ptr<ExpressionInterface> const& expression) :
00041 M_expression_value(value), M_expression(expression) { }
00042 #else
00043 ExpressionEventType(bool value) : M_expression_value(value) { }
00044 #endif
00045 operator bool(void) const { return M_expression_value; }
00046 #ifdef CWDEBUG
00047 friend std::ostream& operator<<(std::ostream& os, ExpressionEventType const& event_type);
00048 #endif
00049 };
00050
00051 #if 1 // No need to print constructing/destruction of ExpressionEventRequestBase (anymore).
00052
00053 typedef event_request_base_tct<ExpressionEventType> ExpressionEventRequestBase;
00054 #else
00055 class ExpressionEventRequestBase : public event_request_base_tct<ExpressionEventType> {
00056 public:
00057 ExpressionEventRequestBase(event_client_tracker_ct* event_client_tracker) :
00058 event_request_base_tct<ExpressionEventType>(event_client_tracker)
00059 { Dout(dc::objects, "Constructing ExpressionEventRequestBase()"); }
00060 ~ExpressionEventRequestBase() { Dout(dc::objects, "Destructing ExpressionEventRequestBase"); }
00061 ExpressionEventRequestBase(ExpressionEventRequestBase const& request) :
00062 event_request_base_tct<ExpressionEventType>(request)
00063 { Dout(dc::objects, "Copy-constructing ExpressionEventRequestBase"); }
00064 };
00065 #endif
00066
00067
00068 class ExpressionEventRequestQueue {
00069 typedef std::deque<ExpressionEventRequestBase*> event_requests_ct;
00070 private:
00071 Counter M_event_requests_locked;
00072 event_requests_ct M_event_requests;
00073 bool M_being_destroyed;
00074 protected:
00075 ExpressionEventRequestQueue(void) : M_being_destroyed(false) { }
00076 void add_request(ExpressionEventRequestBase* request)
00077 { ASSERT(!M_event_requests_locked); ASSERT(M_event_requests.empty()); M_event_requests.push_back(request); }
00078 virtual ~ExpressionEventRequestQueue()
00079 {
00080 M_being_destroyed = true;
00081 destroy_requests();
00082 }
00083 void destroy_requests(void)
00084 {
00085
00086
00087 if (M_event_requests_locked)
00088 return;
00089 if (!M_event_requests.empty())
00090 {
00091 M_event_requests.front()->release();
00092 M_event_requests.pop_front();
00093 }
00094
00095
00096
00097
00098 if (!M_being_destroyed)
00099 all_requests_destroyed();
00100 }
00101 public:
00102 void trigger(ExpressionEventRequestBase::event_type_ct const& request_data)
00103 {
00104 DoutEntering(dc::expression, "ExpressionEventRequestQueue::trigger(" <<
00105 libcwd::type_info_of<ExpressionEventRequestBase::event_type_ct>().demangled_name() <<
00106 " const& " << request_data << ")");
00107 {
00108 Increment tmp(M_event_requests_locked);
00109 event_requests_ct::iterator iter = M_event_requests.begin();
00110
00111
00112
00113 if (iter != M_event_requests.end())
00114 {
00115 (*iter)->handle(request_data);
00116 (*iter)->release();
00117 M_event_requests.erase(iter);
00118 }
00119 }
00120 ASSERT(M_event_requests.empty());
00121 all_requests_destroyed();
00122 }
00123 virtual void all_requests_destroyed() = 0;
00124 };
00125
00126
00127 class ExpressionEventServer : public event_server_tct<ExpressionEventRequestBase, ExpressionEventRequestQueue> {
00128 private:
00129 boost::shared_ptr<ExpressionInterface> M_expression;
00130 bool M_ok;
00131 bool M_evaluation;
00132
00133 public:
00134 ExpressionEventServer(boost::shared_ptr<ExpressionInterface> const& expression);
00135 #ifdef CWDEBUG
00136 ~ExpressionEventServer() { Dout(dc::objects, "Destructing ExpressionEventServer " << *this); }
00137 #endif
00138
00139 void bool_changed(void);
00140 void bool_destructed(void) { if (M_ok) { M_ok = false; destroy_requests(); } }
00141 virtual void all_requests_destroyed(void);
00142 #ifdef CWDEBUG
00143 friend std::ostream& operator<<(std::ostream& os, ExpressionEventServer const& expression_event_server);
00144 #endif
00145 };
00146
00147
00148 template<typename T>
00149 class ConstExpression : public ExpressionInterface {
00150 public:
00151 enum none { };
00152 typedef none inverted_type;
00153 private:
00154 T const M_const;
00155 public:
00156 template<typename T2>
00157 ConstExpression(T2 const& c) : M_const(c) { }
00158
00159 T const& evaluate_impl(void) const { return M_const; }
00160 void sub_event_server_impl(ExpressionEventServer*) { }
00161
00162 virtual bool evaluate(void) { DoutFatal(dc::core, "Calling ConstExpression::evaluate"); return false; }
00163 virtual void sub_event_server(ExpressionEventServer* event_server) { sub_event_server_impl(event_server); }
00164 virtual void add_event_server(boost::shared_ptr<ExpressionEventServer> const&) { }
00165 #ifdef CWDEBUG
00166 virtual void print_on(std::ostream& os) const;
00167 #endif
00168 };
00169
00170 #ifdef CWDEBUG
00171 template<typename T>
00172 void ConstExpression<T>::print_on(std::ostream& os) const
00173 {
00174 os << "ConstExpression<" << libcwd::type_info_of<T>().demangled_name() << ">(" << M_const << ")";
00175 }
00176 #endif
00177
00178
00179
00180
00181 enum beop_type {
00182 beop_AND,
00183 beop_OR,
00184 beop_NEQ,
00185 beop_EQ,
00186 beop_BITWISE_AND,
00187 beop_BITWISE_OR,
00188 beop_BITWISE_XOR
00189 };
00190
00191 template<bool inverted, typename T1, beop_type OP, typename T2>
00192 struct binary_operator;
00193
00194
00195
00196
00197
00198
00199 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
00200 class BinaryExpression : public ExpressionInterface {
00201 public:
00202
00203 typedef BinaryExpression<!inverted, EXPR1, OP, EXPR2> inverted_type;
00204
00205 protected:
00206 EXPR1 M_e1;
00207 EXPR2 M_e2;
00208
00209 public:
00210
00211 BinaryExpression(EXPR1 e1, EXPR2 e2) : M_e1(e1), M_e2(e2) { }
00212
00213
00214 BinaryExpression<!inverted, EXPR1, OP, EXPR2> operator!(void) const;
00215
00216
00217 ExpressionEventServer& create_event_server(void)
00218 {
00219 boost::shared_ptr<ExpressionInterface> expression(new BinaryExpression(*this));
00220 boost::shared_ptr<ExpressionEventServer> event_server(new ExpressionEventServer(expression));
00221 expression->add_event_server(event_server);
00222 return *event_server;
00223 }
00224
00225
00226 void sub_event_server_impl(ExpressionEventServer* event_server) { M_e1.sub_event_server_impl(event_server); M_e2.sub_event_server_impl(event_server); }
00227
00228
00229 virtual void add_event_server(boost::shared_ptr<ExpressionEventServer> const& event_server)
00230 { M_e1.add_event_server(event_server); M_e2.add_event_server(event_server); }
00231
00232 virtual bool evaluate(void);
00233
00234 virtual void sub_event_server(ExpressionEventServer* event_server) { sub_event_server_impl(event_server); }
00235
00236 #ifdef CWDEBUG
00237 virtual void print_on(std::ostream& os) const;
00238 #endif
00239 };
00240
00241
00242
00243
00244
00245
00246
00247 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
00248 struct BinaryExpressionDerived : public BinaryExpression<inverted, EXPR1, OP, EXPR2> {
00249 typename binary_operator<inverted, EXPR1, OP, EXPR2>::return_type evaluate_impl(void) const;
00250 };
00251
00252 template<typename T>
00253 inline bool only_pass_if_bool(T const&) { return false; }
00254
00255 inline bool only_pass_if_bool(bool value) { return value; }
00256
00257 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
00258 bool BinaryExpression<inverted, EXPR1, OP, EXPR2>::evaluate(void)
00259 {
00260 typename binary_operator<inverted, EXPR1, OP, EXPR2>::return_type result =
00261 static_cast<BinaryExpressionDerived<inverted, EXPR1, OP, EXPR2>*>(this)->evaluate_impl();
00262 return only_pass_if_bool(result);
00263 }
00264
00265 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
00266 BinaryExpression<!inverted, EXPR1, OP, EXPR2>
00267 BinaryExpression<inverted, EXPR1, OP, EXPR2>::operator!(void) const
00268 { return BinaryExpression<!inverted, EXPR1, OP, EXPR2>(M_e1, M_e2); }
00269
00270 #ifdef CWDEBUG
00271 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
00272 void BinaryExpression<inverted, EXPR1, OP, EXPR2>::print_on(std::ostream& os) const
00273 {
00274 if (inverted)
00275 os << '!';
00276 os << '(';
00277 M_e1.print_on(os);
00278 switch (OP)
00279 {
00280 case beop_AND:
00281 os << " && ";
00282 break;
00283 case beop_OR:
00284 os << " || ";
00285 break;
00286 case beop_NEQ:
00287 os << " != ";
00288 break;
00289 case beop_EQ:
00290 os << " == ";
00291 break;
00292 case beop_BITWISE_AND:
00293 os << " & ";
00294 break;
00295 case beop_BITWISE_OR:
00296 os << " | ";
00297 break;
00298 case beop_BITWISE_XOR:
00299 os << " ^ ";
00300 break;
00301 }
00302 M_e2.print_on(os);
00303 os << ')';
00304 }
00305 #endif
00306
00307
00308
00309
00310 template<bool inverted1, bool inverted2>
00311 inline BinaryExpression<inverted1 && inverted2,
00312 BoolExpression<inverted1 && !inverted2>,
00313 (inverted1 && inverted2) ? beop_OR : beop_AND,
00314 BoolExpression<inverted2 && !inverted1>
00315 >
00316 operator&&(BoolExpression<inverted1> const& e1,
00317 BoolExpression<inverted2> const& e2)
00318 {
00319 return BinaryExpression<inverted1 && inverted2,
00320 BoolExpression<inverted1 && !inverted2>,
00321 (inverted1 && inverted2) ? beop_OR : beop_AND,
00322 BoolExpression<inverted2 && !inverted1>
00323 >(e1, e2);
00324 }
00325
00326
00327 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, bool inverted2>
00328 inline BinaryExpression<inverted1 && inverted2,
00329 BinaryExpression<inverted1 && !inverted2, EXPR1, OP, EXPR2>,
00330 (inverted1 && inverted2) ? beop_OR : beop_AND,
00331 BoolExpression<inverted2 && !inverted1>
00332 >
00333 operator&&(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00334 BoolExpression<inverted2> const& e2)
00335 {
00336 return BinaryExpression<inverted1 && inverted2,
00337 BinaryExpression<inverted1 && !inverted2, EXPR1, OP, EXPR2>,
00338 (inverted1 && inverted2) ? beop_OR : beop_AND,
00339 BoolExpression<inverted2 && !inverted1>
00340 >(e1, e2);
00341 }
00342
00343
00344 template<bool inverted1, bool inverted2, class EXPR1, beop_type OP, class EXPR2>
00345 inline BinaryExpression<inverted1 && inverted2,
00346 BoolExpression<inverted1 && !inverted2>,
00347 (inverted1 && inverted2) ? beop_OR : beop_AND,
00348 BinaryExpression<inverted2 && !inverted1, EXPR1, OP, EXPR2>
00349 >
00350 operator&&(BoolExpression<inverted1> const& e1,
00351 BinaryExpression<inverted2, EXPR1, OP, EXPR2> const& e2)
00352 {
00353 return BinaryExpression<inverted1 && inverted2,
00354 BoolExpression<inverted1 && !inverted2>,
00355 (inverted1 && inverted2) ? beop_OR : beop_AND,
00356 BinaryExpression<inverted2 && !inverted1, EXPR1, OP, EXPR2>
00357 >(e1, e2);
00358 }
00359
00360
00361 template<bool inverted1, class EXPR1, beop_type OP1, class EXPR2,
00362 bool inverted2, class EXPR3, beop_type OP2, class EXPR4>
00363 inline BinaryExpression<inverted1 && inverted2,
00364 BinaryExpression<inverted1 && !inverted2, EXPR1, OP1, EXPR2>,
00365 (inverted1 && inverted2) ? beop_OR : beop_AND,
00366 BinaryExpression<inverted2 && !inverted1, EXPR3, OP2, EXPR4>
00367 >
00368 operator&&(BinaryExpression<inverted1, EXPR1, OP1, EXPR2> const& e1,
00369 BinaryExpression<inverted2, EXPR3, OP2, EXPR4> const& e2)
00370 {
00371 return BinaryExpression<inverted1 && inverted2,
00372 BinaryExpression<inverted1 && !inverted2, EXPR1, OP1, EXPR2>,
00373 (inverted1 && inverted2) ? beop_OR : beop_AND,
00374 BinaryExpression<inverted2 && !inverted1, EXPR3, OP2, EXPR4>
00375 >(e1, e2);
00376 }
00377
00378
00379 template<bool inverted1, bool inverted2>
00380 inline BinaryExpression<inverted1 && inverted2,
00381 BoolExpression<inverted1 && !inverted2>,
00382 (inverted1 && inverted2) ? beop_AND : beop_OR,
00383 BoolExpression<inverted2 && !inverted1>
00384 >
00385 operator||(BoolExpression<inverted1> const& e1,
00386 BoolExpression<inverted2> const& e2)
00387 {
00388 return BinaryExpression<inverted1 && inverted2,
00389 BoolExpression<inverted1 && !inverted2>,
00390 (inverted1 && inverted2) ? beop_AND : beop_OR,
00391 BoolExpression<inverted2 && !inverted1>
00392 >(e1, e2);
00393 }
00394
00395
00396 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, bool inverted2>
00397 inline BinaryExpression<inverted1 && inverted2,
00398 BinaryExpression<inverted1 && !inverted2, EXPR1, OP, EXPR2>,
00399 (inverted1 && inverted2) ? beop_AND : beop_OR,
00400 BoolExpression<inverted2 && !inverted1>
00401 >
00402 operator||(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00403 BoolExpression<inverted2> const& e2)
00404 {
00405 return BinaryExpression<inverted1 && inverted2,
00406 BinaryExpression<inverted1 && !inverted2, EXPR1, OP, EXPR2>,
00407 (inverted1 && inverted2) ? beop_AND : beop_OR,
00408 BoolExpression<inverted2 && !inverted1>
00409 >(e1, e2);
00410 }
00411
00412
00413 template<bool inverted1, bool inverted2, class EXPR1, beop_type OP, class EXPR2>
00414 inline BinaryExpression<inverted1 && inverted2,
00415 BoolExpression<inverted1 && !inverted2>,
00416 (inverted1 && inverted2) ? beop_AND : beop_OR,
00417 BinaryExpression<inverted2 && !inverted1, EXPR1, OP, EXPR2>
00418 >
00419 operator||(BoolExpression<inverted1> const& e1,
00420 BinaryExpression<inverted2, EXPR1, OP, EXPR2> const& e2)
00421 {
00422 return BinaryExpression<inverted1 && inverted2,
00423 BoolExpression<inverted1 && !inverted2>,
00424 (inverted1 && inverted2) ? beop_AND : beop_OR,
00425 BinaryExpression<inverted2 && !inverted1, EXPR1, OP, EXPR2>
00426 >(e1, e2);
00427 }
00428
00429
00430 template<bool inverted1, class EXPR1, beop_type OP1, class EXPR2,
00431 bool inverted2, class EXPR3, beop_type OP2, class EXPR4>
00432 inline BinaryExpression<inverted1 && inverted2,
00433 BinaryExpression<inverted1 && !inverted2, EXPR1, OP1, EXPR2>,
00434 (inverted1 && inverted2) ? beop_AND : beop_OR,
00435 BinaryExpression<inverted2 && !inverted1, EXPR3, OP2, EXPR4>
00436 >
00437 operator||(BinaryExpression<inverted1, EXPR1, OP1, EXPR2> const& e1,
00438 BinaryExpression<inverted2, EXPR3, OP2, EXPR4> const& e2)
00439 {
00440 return BinaryExpression<inverted1 && inverted2,
00441 BinaryExpression<inverted1 && !inverted2, EXPR1, OP1, EXPR2>,
00442 (inverted1 && inverted2) ? beop_AND : beop_OR,
00443 BinaryExpression<inverted2 && !inverted1, EXPR3, OP2, EXPR4>
00444 >(e1, e2);
00445 }
00446
00447
00448 template<bool inverted1, bool inverted2>
00449 inline BinaryExpression<false,
00450 BoolExpression<false>,
00451 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00452 BoolExpression<false>
00453 >
00454 operator!=(BoolExpression<inverted1> const& e1,
00455 BoolExpression<inverted2> const& e2)
00456 {
00457 return BinaryExpression<false,
00458 BoolExpression<false>,
00459 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00460 BoolExpression<false>
00461 >(e1, e2);
00462 }
00463
00464
00465 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, bool inverted2>
00466 inline BinaryExpression<false,
00467 BinaryExpression<false, EXPR1, OP, EXPR2>,
00468 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00469 BoolExpression<false>
00470 >
00471 operator!=(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00472 BoolExpression<inverted2> const& e2)
00473 {
00474 return BinaryExpression<false,
00475 BinaryExpression<false, EXPR1, OP, EXPR2>,
00476 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00477 BoolExpression<false>
00478 >(e1, e2);
00479 }
00480
00481
00482 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, typename T>
00483 inline BinaryExpression<false,
00484 BinaryExpression<false, EXPR1, OP, EXPR2>,
00485 inverted1 ? beop_EQ : beop_NEQ,
00486 ConstExpression<T>
00487 >
00488 operator!=(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00489 ConstExpression<T> const& e2)
00490 {
00491 return BinaryExpression<false,
00492 BinaryExpression<false, EXPR1, OP, EXPR2>,
00493 inverted1 ? beop_EQ : beop_NEQ,
00494 ConstExpression<T>
00495 >(e1, e2);
00496 }
00497
00498
00499 template<bool inverted1, bool inverted2, class EXPR1, beop_type OP, class EXPR2>
00500 inline BinaryExpression<false,
00501 BoolExpression<false>,
00502 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00503 BinaryExpression<false, EXPR1, OP, EXPR2>
00504 >
00505 operator!=(BoolExpression<inverted1> const& e1,
00506 BinaryExpression<inverted2, EXPR1, OP, EXPR2> const& e2)
00507 {
00508 return BinaryExpression<false,
00509 BoolExpression<false>,
00510 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00511 BinaryExpression<false, EXPR1, OP, EXPR2>
00512 >(e1, e2);
00513 }
00514
00515
00516 template<typename T, bool inverted1, class EXPR1, beop_type OP, class EXPR2>
00517 inline BinaryExpression<false,
00518 ConstExpression<T>,
00519 inverted1 ? beop_EQ : beop_NEQ,
00520 BinaryExpression<false, EXPR1, OP, EXPR2>
00521 >
00522 operator!=(ConstExpression<T> const& e1,
00523 BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e2)
00524 {
00525 return BinaryExpression<false,
00526 ConstExpression<T>,
00527 inverted1 ? beop_EQ : beop_NEQ,
00528 BinaryExpression<false, EXPR1, OP, EXPR2>
00529 >(e1, e2);
00530 }
00531
00532
00533 template<bool inverted1, class EXPR1, beop_type OP1, class EXPR2,
00534 bool inverted2, class EXPR3, beop_type OP2, class EXPR4>
00535 inline BinaryExpression<false,
00536 BinaryExpression<false, EXPR1, OP1, EXPR2>,
00537 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00538 BinaryExpression<false, EXPR3, OP2, EXPR4>
00539 >
00540 operator!=(BinaryExpression<inverted1, EXPR1, OP1, EXPR2> const& e1,
00541 BinaryExpression<inverted2, EXPR3, OP2, EXPR4> const& e2)
00542 {
00543 return BinaryExpression<false,
00544 BinaryExpression<false, EXPR1, OP1, EXPR2>,
00545 (inverted1 == inverted2) ? beop_NEQ : beop_EQ,
00546 BinaryExpression<false, EXPR3, OP2, EXPR4>
00547 >(e1, e2);
00548 }
00549
00550
00551 template<bool inverted1, bool inverted2>
00552 inline BinaryExpression<false,
00553 BoolExpression<false>,
00554 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00555 BoolExpression<false>
00556 >
00557 operator==(BoolExpression<inverted1> const& e1,
00558 BoolExpression<inverted2> const& e2)
00559 {
00560 return BinaryExpression<false,
00561 BoolExpression<false>,
00562 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00563 BoolExpression<false>
00564 >(e1, e2);
00565 }
00566
00567
00568 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, bool inverted2>
00569 inline BinaryExpression<false,
00570 BinaryExpression<false, EXPR1, OP, EXPR2>,
00571 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00572 BoolExpression<false>
00573 >
00574 operator==(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00575 BoolExpression<inverted2> const& e2)
00576 {
00577 return BinaryExpression<false,
00578 BinaryExpression<false, EXPR1, OP, EXPR2>,
00579 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00580 BoolExpression<false>
00581 >(e1, e2);
00582 }
00583
00584
00585 template<bool inverted1, class EXPR1, beop_type OP, class EXPR2, typename T>
00586 inline BinaryExpression<false,
00587 BinaryExpression<false, EXPR1, OP, EXPR2>,
00588 inverted1 ? beop_NEQ : beop_EQ,
00589 ConstExpression<T>
00590 >
00591 operator==(BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e1,
00592 ConstExpression<T> const& e2)
00593 {
00594 return BinaryExpression<false,
00595 BinaryExpression<false, EXPR1, OP, EXPR2>,
00596 inverted1 ? beop_NEQ : beop_EQ,
00597 ConstExpression<T>
00598 >(e1, e2);
00599 }
00600
00601
00602 template<bool inverted1, bool inverted2, class EXPR1, beop_type OP, class EXPR2>
00603 inline BinaryExpression<false,
00604 BoolExpression<false>,
00605 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00606 BinaryExpression<false, EXPR1, OP, EXPR2>
00607 >
00608 operator==(BoolExpression<inverted1> const& e1,
00609 BinaryExpression<inverted2, EXPR1, OP, EXPR2> const& e2)
00610 {
00611 return BinaryExpression<false,
00612 BoolExpression<false>,
00613 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00614 BinaryExpression<false, EXPR1, OP, EXPR2>
00615 >(e1, e2);
00616 }
00617
00618
00619 template<typename T, bool inverted1, class EXPR1, beop_type OP, class EXPR2>
00620 inline BinaryExpression<false,
00621 ConstExpression<T>,
00622 inverted1 ? beop_NEQ : beop_EQ,
00623 BinaryExpression<false, EXPR1, OP, EXPR2>
00624 >
00625 operator==(ConstExpression<T> const& e1,
00626 BinaryExpression<inverted1, EXPR1, OP, EXPR2> const& e2)
00627 {
00628 return BinaryExpression<false,
00629 ConstExpression<T>,
00630 inverted1 ? beop_NEQ : beop_EQ,
00631 BinaryExpression<false, EXPR1, OP, EXPR2>
00632 >(e1, e2);
00633 }
00634
00635
00636 template<bool inverted1, class EXPR1, beop_type OP1, class EXPR2,
00637 bool inverted2, class EXPR3, beop_type OP2, class EXPR4>
00638 inline BinaryExpression<false,
00639 BinaryExpression<false, EXPR1, OP1, EXPR2>,
00640 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00641 BinaryExpression<false, EXPR3, OP2, EXPR4>
00642 >
00643 operator==(BinaryExpression<inverted1, EXPR1, OP1, EXPR2> const& e1,
00644 BinaryExpression<inverted2, EXPR3, OP2, EXPR4> const& e2)
00645 {
00646 return BinaryExpression<false,
00647 BinaryExpression<false, EXPR1, OP1, EXPR2>,
00648 (inverted1 == inverted2) ? beop_EQ : beop_NEQ,
00649 BinaryExpression<false, EXPR3, OP2, EXPR4>
00650 >(e1, e2);
00651 }
00652
00653
00654 template<typename T>
00655 BinaryExpression<false,
00656 WatchedExpression<T>,
00657 beop_EQ,
00658 ConstExpression<T>
00659 >
00660 operator==(WatchedExpression<T> const& e1,
00661 ConstExpression<T> const& e2)
00662 {
00663 return BinaryExpression<false,
00664 WatchedExpression<T>,
00665 beop_EQ,
00666 ConstExpression<T>
00667 >(e1, e2);
00668 }
00669
00670
00671 template<typename T>
00672 BinaryExpression<false,
00673 ConstExpression<T>,
00674 beop_EQ,
00675 WatchedExpression<T>
00676 >
00677 operator==(ConstExpression<T> const& e1,
00678 WatchedExpression<T> const& e2)
00679 {
00680 return BinaryExpression<false,
00681 ConstExpression<T>,
00682 beop_EQ,
00683 WatchedExpression<T>
00684 >(e1, e2);
00685 }
00686
00687
00688 template<typename T1, typename T2>
00689 BinaryExpression<false,
00690 WatchedExpression<T1>,
00691 beop_EQ,
00692 WatchedExpression<T2>
00693 >
00694 operator==(WatchedExpression<T1> const& e1,
00695 WatchedExpression<T2> const& e2)
00696 {
00697 return BinaryExpression<false,
00698 WatchedExpression<T1>,
00699 beop_EQ,
00700 WatchedExpression<T2>
00701 >(e1, e2);
00702 }
00703
00704
00705 template<typename T>
00706 BinaryExpression<false,
00707 WatchedExpression<T>,
00708 beop_NEQ,
00709 ConstExpression<T>
00710 >
00711 operator!=(WatchedExpression<T> const& e1,
00712 ConstExpression<T> const& e2)
00713 {
00714 return BinaryExpression<false,
00715 WatchedExpression<T>,
00716 beop_NEQ,
00717 ConstExpression<T>
00718 >(e1, e2);
00719 }
00720
00721
00722 template<typename T>
00723 BinaryExpression<false,
00724 ConstExpression<T>,
00725 beop_NEQ,
00726 WatchedExpression<T>
00727 >
00728 operator!=(ConstExpression<T> const& e1,
00729 WatchedExpression<T> const& e2)
00730 {
00731 return BinaryExpression<false,
00732 ConstExpression<T>,
00733 beop_NEQ,
00734 WatchedExpression<T>
00735 >(e1, e2);
00736 }
00737
00738
00739 template<typename T1, typename T2>
00740 BinaryExpression<false,
00741 WatchedExpression<T1>,
00742 beop_NEQ,
00743 WatchedExpression<T2>
00744 >
00745 operator!=(WatchedExpression<T1> const& e1,
00746 WatchedExpression<T2> const& e2)
00747 {
00748 return BinaryExpression<false,
00749 WatchedExpression<T1>,
00750 beop_NEQ,
00751 WatchedExpression<T2>
00752 >(e1, e2);
00753 }
00754
00755
00756 template<typename T1, typename T2>
00757 BinaryExpression<false,
00758 WatchedExpression<T1>,
00759 beop_BITWISE_AND,
00760 ConstExpression<T2>
00761 >
00762 operator&(WatchedExpression<T1> const& e1,
00763 ConstExpression<T2> const& e2)
00764 {
00765 return BinaryExpression<false,
00766 WatchedExpression<T1>,
00767 beop_BITWISE_AND,
00768 ConstExpression<T2>
00769 >(e1, e2);
00770 }
00771
00772
00773 template<typename T1, typename T2>
00774 BinaryExpression<false,
00775 ConstExpression<T1>,
00776 beop_BITWISE_AND,
00777 WatchedExpression<T2>
00778 >
00779 operator&(ConstExpression<T1> const& e1,
00780 WatchedExpression<T2> const& e2)
00781 {
00782 return BinaryExpression<false,
00783 ConstExpression<T1>,
00784 beop_BITWISE_AND,
00785 WatchedExpression<T2>
00786 >(e1, e2);
00787 }
00788
00789
00790 template<typename T1, typename T2>
00791 BinaryExpression<false,
00792 WatchedExpression<T1>,
00793 beop_BITWISE_AND,
00794 WatchedExpression<T2>
00795 >
00796 operator&(WatchedExpression<T1> const& e1,
00797 WatchedExpression<T2> const& e2)
00798 {
00799 return BinaryExpression<false,
00800 WatchedExpression<T1>,
00801 beop_BITWISE_AND,
00802 WatchedExpression<T2>
00803 >(e1, e2);
00804 }
00805
00806
00807 template<typename T1, typename T2>
00808 BinaryExpression<false,
00809 WatchedExpression<T1>,
00810 beop_BITWISE_OR,
00811 ConstExpression<T2>
00812 >
00813 operator|(WatchedExpression<T1> const& e1,
00814 ConstExpression<T2> const& e2)
00815 {
00816 return BinaryExpression<false,
00817 WatchedExpression<T1>,
00818 beop_BITWISE_OR,
00819 ConstExpression<T2>
00820 >(e1, e2);
00821 }
00822
00823
00824 template<typename T1, typename T2>
00825 BinaryExpression<false,
00826 ConstExpression<T1>,
00827 beop_BITWISE_OR,
00828 WatchedExpression<T2>
00829 >
00830 operator|(ConstExpression<T1> const& e1,
00831 WatchedExpression<T2> const& e2)
00832 {
00833 return BinaryExpression<false,
00834 ConstExpression<T1>,
00835 beop_BITWISE_OR,
00836 WatchedExpression<T2>
00837 >(e1, e2);
00838 }
00839
00840
00841 template<typename T1, typename T2>
00842 BinaryExpression<false,
00843 WatchedExpression<T1>,
00844 beop_BITWISE_OR,
00845 WatchedExpression<T2>
00846 >
00847 operator|(WatchedExpression<T1> const& e1,
00848 WatchedExpression<T2> const& e2)
00849 {
00850 return BinaryExpression<false,
00851 WatchedExpression<T1>,
00852 beop_BITWISE_OR,
00853 WatchedExpression<T2>
00854 >(e1, e2);
00855 }
00856
00857
00858 template<typename T1, typename T2>
00859 BinaryExpression<false,
00860 WatchedExpression<T1>,
00861 beop_BITWISE_XOR,
00862 ConstExpression<T2>
00863 >
00864 operator^(WatchedExpression<T1> const& e1,
00865 ConstExpression<T2> const& e2)
00866 {
00867 return BinaryExpression<false,
00868 WatchedExpression<T1>,
00869 beop_BITWISE_XOR,
00870 ConstExpression<T2>
00871 >(e1, e2);
00872 }
00873
00874
00875 template<typename T1, typename T2>
00876 BinaryExpression<false,
00877 ConstExpression<T1>,
00878 beop_BITWISE_XOR,
00879 WatchedExpression<T2>
00880 >
00881 operator^(ConstExpression<T1> const& e1,
00882 WatchedExpression<T2> const& e2)
00883 {
00884 return BinaryExpression<false,
00885 ConstExpression<T1>,
00886 beop_BITWISE_XOR,
00887 WatchedExpression<T2>
00888 >(e1, e2);
00889 }
00890
00891
00892 template<typename T1, typename T2>
00893 BinaryExpression<false,
00894 WatchedExpression<T1>,
00895 beop_BITWISE_XOR,
00896 WatchedExpression<T2>
00897 >
00898 operator^(WatchedExpression<T1> const& e1,
00899 WatchedExpression<T2> const& e2)
00900 {
00901 return BinaryExpression<false,
00902 WatchedExpression<T1>,
00903 beop_BITWISE_XOR,
00904 WatchedExpression<T2>
00905 >(e1, e2);
00906 }
00907
00908 #define ON_TRUE(expr, action...) do { (expr).create_event_server()(action); } while(0)
00909
00910 #define DECLARE_BINARY_OPERATOR(op, code) \
00911 template<typename T1, typename T2> \
00912 struct binary_operator<false, T1, beop_##code, T2> \
00913 { \
00914 typedef T1 arg1_type; \
00915 typedef T2 arg2_type; \
00916 typedef typeof(((arg1_type const*)0)->evaluate_impl() op ((arg2_type const*)0)->evaluate_impl()) return_type; \
00917 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00918 { return a1.evaluate_impl() op a2.evaluate_impl(); } \
00919 }; \
00920 template<bool inverted, typename T3, beop_type OP, typename T4, typename T2> \
00921 struct binary_operator<false, BinaryExpression<inverted, T3, OP, T4>, beop_##code, T2> \
00922 { \
00923 typedef BinaryExpression<inverted, T3, OP, T4> arg1_type; \
00924 typedef BinaryExpressionDerived<inverted, T3, OP, T4> cast1_type; \
00925 typedef T2 arg2_type; \
00926 typedef typeof(((cast1_type const*)0)->evaluate_impl() op ((arg2_type const*)0)->evaluate_impl()) return_type; \
00927 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00928 { return static_cast<cast1_type const &>(a1).evaluate_impl() op a2.evaluate_impl(); } \
00929 }; \
00930 template<typename T1, bool inverted, typename T3, beop_type OP, typename T4> \
00931 struct binary_operator<false, T1, beop_##code, BinaryExpression<inverted, T3, OP, T4> > \
00932 { \
00933 typedef T1 arg1_type; \
00934 typedef BinaryExpression<inverted, T3, OP, T4> arg2_type; \
00935 typedef BinaryExpressionDerived<inverted, T3, OP, T4> cast2_type; \
00936 typedef typeof(((arg1_type const*)0)->evaluate_impl() op ((cast2_type const*)0)->evaluate_impl()) return_type; \
00937 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00938 { return a1.evaluate_impl() op static_cast<cast2_type const&>(a2).evaluate_impl(); } \
00939 }; \
00940 template<bool inverted1, typename T3, beop_type OP1, typename T4, \
00941 bool inverted2, typename T5, beop_type OP2, typename T6> \
00942 struct binary_operator<false, BinaryExpression<inverted1, T3, OP1, T4>, \
00943 beop_##code, BinaryExpression<inverted2, T5, OP2, T6> > \
00944 { \
00945 typedef BinaryExpression<inverted1, T3, OP1, T4> arg1_type; \
00946 typedef BinaryExpressionDerived<inverted1, T3, OP1, T4> cast1_type; \
00947 typedef BinaryExpression<inverted2, T5, OP2, T6> arg2_type; \
00948 typedef BinaryExpressionDerived<inverted2, T5, OP2, T6> cast2_type; \
00949 typedef typeof(((cast1_type*)0)->evaluate_impl() op ((cast2_type*)0)->evaluate_impl()) return_type; \
00950 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00951 { return static_cast<cast1_type const&>(a1).evaluate_impl() \
00952 op static_cast<cast2_type const&>(a2).evaluate_impl(); } \
00953 }; \
00954 template<typename T1, typename T2> \
00955 struct binary_operator<true, T1, beop_##code, T2> \
00956 { \
00957 typedef T1 arg1_type; \
00958 typedef T2 arg2_type; \
00959 typedef bool return_type; \
00960 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00961 { return !(a1.evaluate_impl() op a2.evaluate_impl()); } \
00962 }; \
00963 template<bool inverted, typename T3, beop_type OP, typename T4, typename T2> \
00964 struct binary_operator<true, BinaryExpression<inverted, T3, OP, T4>, beop_##code, T2> \
00965 { \
00966 typedef BinaryExpression<inverted, T3, OP, T4> arg1_type; \
00967 typedef BinaryExpressionDerived<inverted, T3, OP, T4> cast1_type; \
00968 typedef T2 arg2_type; \
00969 typedef bool return_type; \
00970 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00971 { return !(static_cast<cast1_type const&>(a1).evaluate_impl() op a2.evaluate_impl()); } \
00972 }; \
00973 template<typename T1, bool inverted, typename T3, beop_type OP, typename T4> \
00974 struct binary_operator<true, T1, beop_##code, BinaryExpression<inverted, T3, OP, T4> > \
00975 { \
00976 typedef T1 arg1_type; \
00977 typedef BinaryExpression<inverted, T3, OP, T4> arg2_type; \
00978 typedef BinaryExpressionDerived<inverted, T3, OP, T4> cast2_type; \
00979 typedef bool return_type; \
00980 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00981 { return !(a1.evaluate_impl() op static_cast<cast2_type const&>(a2).evaluate_impl()); } \
00982 }; \
00983 template<bool inverted1, typename T3, beop_type OP1, typename T4, \
00984 bool inverted2, typename T5, beop_type OP2, typename T6> \
00985 struct binary_operator<true, BinaryExpression<inverted1, T3, OP1, T4>, \
00986 beop_##code, BinaryExpression<inverted2, T5, OP2, T6> > \
00987 { \
00988 typedef BinaryExpression<inverted1, T3, OP1, T4> arg1_type; \
00989 typedef BinaryExpressionDerived<inverted1, T3, OP1, T4> cast1_type; \
00990 typedef BinaryExpression<inverted2, T5, OP2, T6> arg2_type; \
00991 typedef BinaryExpressionDerived<inverted2, T5, OP2, T6> cast2_type; \
00992 typedef bool return_type; \
00993 return_type operator()(arg1_type const& a1, arg2_type const& a2) \
00994 { return !(static_cast<cast1_type const&>(a1).evaluate_impl() \
00995 op static_cast<cast2_type const&>(a2).evaluate_impl()); } \
00996 }
00997
00998 DECLARE_BINARY_OPERATOR(&&, AND);
00999 DECLARE_BINARY_OPERATOR(||, OR);
01000 DECLARE_BINARY_OPERATOR(!=, NEQ);
01001 DECLARE_BINARY_OPERATOR(==, EQ);
01002 DECLARE_BINARY_OPERATOR(&, BITWISE_AND);
01003 DECLARE_BINARY_OPERATOR(|, BITWISE_OR);
01004 DECLARE_BINARY_OPERATOR(^, BITWISE_XOR);
01005
01006 template<bool inverted, class EXPR1, beop_type OP, class EXPR2>
01007 typename binary_operator<inverted, EXPR1, OP, EXPR2>::return_type
01008 BinaryExpressionDerived<inverted, EXPR1, OP, EXPR2>::evaluate_impl(void) const
01009 {
01010 return binary_operator<inverted, EXPR1, OP, EXPR2>()(this->M_e1, this->M_e2);
01011 }
01012
01013 #endif // EXPRESSION_H