ircproxy The Ultimate Cyborg |
00001 // ircproxy -- An IRC bouncer. 00002 // 00003 //! @file Bool.h 00004 //! @brief This file contains the declaration of class Bool. 00005 // 00006 // Copyright (C) 2006, 2007 by 00007 // 00008 // Carlo Wood, Run on IRC <carlo@alinoe.com> 00009 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 00010 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 00011 // 00012 // This file may be distributed under the terms of the Q Public License 00013 // version 1.0 as appearing in the file LICENSE.QPL included in the 00014 // packaging of this file. 00015 00016 #ifndef BOOL_H 00017 #define BOOL_H 00018 00019 #ifndef USE_PCH 00020 #include <set> 00021 #include <boost/shared_ptr.hpp> 00022 #include "debug.h" 00023 #endif 00024 00025 #include "ExpressionInterface.h" 00026 00027 class Bool; 00028 class ExpressionEventServer; 00029 00030 //! An Expression consisting of a single boolean (Bool). 00031 template<bool inverted> 00032 class BoolExpression : public ExpressionInterface { 00033 public: 00034 typedef BoolExpression<!inverted> inverted_type; //!< The type of the inverted expression. 00035 typedef bool evaluation_type; //!< The return type of evaluate_impl. 00036 00037 private: 00038 Bool& M_b; //!< The underlying Bool. 00039 00040 public: 00041 //! Copy constructor. 00042 BoolExpression(Bool& b) : M_b(b) { } 00043 00044 //! Inversion operator. Returns an inverted expression. 00045 BoolExpression<!inverted> operator!(void) const { return BoolExpression<!inverted>(M_b); } 00046 00047 //! Create and return an event server that is watching this expression. 00048 ExpressionEventServer& create_event_server(void); 00049 00050 bool evaluate_impl(void) const; 00051 void sub_event_server_impl(ExpressionEventServer*); 00052 00053 virtual void add_event_server(boost::shared_ptr<ExpressionEventServer> const& event_server); 00054 //! Implementation of pure virtual function ExpressionInterface::evaluate. 00055 virtual bool evaluate(void) { return evaluate_impl(); } 00056 //! Implementation of pure virtual function ExpressionInterface::sub_event_server. 00057 virtual void sub_event_server(ExpressionEventServer* event_server) { sub_event_server_impl(event_server); } 00058 #ifdef CWDEBUG 00059 virtual void print_on(std::ostream& os) const; 00060 #endif 00061 }; 00062 00063 //! A watchable boolean. 00064 class Bool { 00065 private: 00066 bool M_value; //!< Underlaying bool value. 00067 bool M_being_destructed; //!< True when this object is being destructed. 00068 std::set<boost::shared_ptr<ExpressionEventServer> > M_event_servers; //!< List of Expression event servers that are watching this Bool. 00069 #ifdef CWDEBUG 00070 char const* M_name; //!< For debugging purposes; a human readable name for this object. 00071 #endif 00072 00073 public: 00074 #ifdef CWDEBUG 00075 //! Construct a Bool with debug name \a name. 00076 Bool(char const* name) : M_value(false), M_being_destructed(false), M_name(name) { } 00077 #else 00078 //! Default constructor. 00079 Bool(void) : M_value(false), M_being_destructed(false) { } 00080 #endif 00081 //! Copy constructor. 00082 Bool(Bool const& b) : M_value(b.M_value), M_being_destructed(false) 00083 #ifdef CWDEBUG 00084 , M_name(b.M_name) 00085 #endif 00086 { 00087 #ifdef CWDEBUG 00088 if (!b.M_event_servers.empty()) 00089 Dout(dc::warning, "Copy-constructing a Bool that is being used by one or more ExpressionEventServer's"); 00090 #endif 00091 } 00092 //! Destructor. 00093 ~Bool(); 00094 00095 #ifdef CWDEBUG 00096 //! For debugging purposes. Write the (debug) name of this object to \a os. 00097 void print_name(std::ostream& os) const { os << M_name; } 00098 #endif 00099 00100 //! Add event server to notification list. 00101 void add_event_server(boost::shared_ptr<ExpressionEventServer> const& event_server) 00102 { 00103 // If this Bool appears multiple times in one expression, we come here more than once. 00104 // However, since M_event_servers is a set<>, only the first time the event_server is really added. 00105 M_event_servers.insert(event_server); 00106 } 00107 00108 //! Remove event server from notification list. 00109 void sub_event_server(ExpressionEventServer* event_server) 00110 { 00111 if (M_being_destructed) 00112 return; 00113 std::set<boost::shared_ptr<ExpressionEventServer> >::iterator iter = M_event_servers.begin(); 00114 while (iter != M_event_servers.end()) 00115 { 00116 if ((*iter).get() == event_server) 00117 break; 00118 ++iter; 00119 } 00120 // If this Bool appears multiple times in one expression, we come here more than once. 00121 if (iter != M_event_servers.end()) 00122 M_event_servers.erase(iter); 00123 } 00124 00125 //! Assign bool value. 00126 Bool& operator=(bool b) 00127 { 00128 if (M_value != b) 00129 changed_to(b); 00130 return *this; 00131 } 00132 00133 //! Assign Bool value. 00134 Bool& operator=(Bool const& b) 00135 { 00136 if (M_value != b.M_value) 00137 changed_to(b.M_value); 00138 return *this; 00139 } 00140 00141 //! Dereference operator. Returns this object as expression. 00142 BoolExpression<false> operator*(void) { return BoolExpression<false>(*this); } 00143 00144 //! Returns underlying bool value. 00145 bool value(void) const { return M_value; } 00146 00147 //! Write Bool \a b to \a os. 00148 friend std::ostream& operator<<(std::ostream& os, Bool const& b); 00149 00150 private: 00151 //! Called when the underlying boolean changes value to \a b. 00152 void changed_to(bool b); 00153 }; 00154 00155 #ifdef CWDEBUG 00156 //! For debugging purposes. Write the contents of this object to \a os. 00157 template<bool inverted> 00158 void BoolExpression<inverted>::print_on(std::ostream& os) const 00159 { 00160 if (inverted) 00161 os << '!'; 00162 M_b.print_name(os); 00163 } 00164 #endif 00165 00166 //! Add event server \a event_server to notification list. 00167 template<bool inverted> 00168 void BoolExpression<inverted>::add_event_server(boost::shared_ptr<ExpressionEventServer> const& event_server) 00169 { 00170 M_b.add_event_server(event_server); 00171 } 00172 00173 //! @brief Evaluate this expression. 00174 // 00175 // Returns the underlying bool value of the single Bool that this expression consists off. 00176 template<bool inverted> 00177 bool BoolExpression<inverted>::evaluate_impl(void) const 00178 { 00179 return M_b.value() != inverted; 00180 } 00181 00182 //! Implementation of sub_event_server(). Remove event server \a event_server from the notification list. 00183 template<bool inverted> 00184 void BoolExpression<inverted>::sub_event_server_impl(ExpressionEventServer* event_server) 00185 { 00186 M_b.sub_event_server(event_server); 00187 } 00188 00189 #endif // BOOL_H 00190
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|