00001 #ifndef wali_nwa_StateStorage_GUARD 00002 #define wali_nwa_StateStorage_GUARD 1 00003 00004 /** 00005 * @author Amanda Burton 00006 */ 00007 00008 #include "opennwa/NwaFwd.hpp" 00009 00010 // ::wali 00011 #include "wali/Printable.hpp" 00012 #include "wali/Key.hpp" 00013 #include "wali/KeyContainer.hpp" 00014 #include "wali/ref_ptr.hpp" 00015 #include "opennwa/ClientInfo.hpp" 00016 00017 // std::c++ 00018 #include <iostream> 00019 #include <set> 00020 #include <map> 00021 00022 namespace opennwa 00023 { 00024 namespace details 00025 { 00026 00027 /** 00028 * 00029 * This class is used to keep track of the states of an NWA. 00030 * 00031 */ 00032 00033 class StateStorage : public wali::Printable 00034 { 00035 public: 00036 typedef ClientInfo Client; 00037 typedef StateSet::const_iterator const_iterator; 00038 typedef StateSet::iterator iterator; 00039 00040 typedef ref_ptr<Client> ClientInfoRefPtr; 00041 00042 00043 // The following macro fakes static data declarations with 00044 // initializers in a template class to work around C++ being 00045 // dumb. Static data in a template class is almost useless 00046 // because you have to explicitly define it for every 00047 // instantiation. Instead, make a static member function that 00048 // returns the value. (In this case, it's stored as a 00049 // function-static variable, but this is somewhat irrelevant. 00050 #define DEFINE_FAKE_STATIC_DATA(name, value) \ 00051 static std::string const & name() { \ 00052 static std::string ret = value; \ 00053 return ret; \ 00054 } 00055 00056 DEFINE_FAKE_STATIC_DATA(XMLFinalAttr, "final") 00057 DEFINE_FAKE_STATIC_DATA(XMLInitialAttr, "initial") 00058 DEFINE_FAKE_STATIC_DATA(XMLNameAttr, "name") 00059 DEFINE_FAKE_STATIC_DATA(XMLStateTag, "State") 00060 00061 #undef DEFINE_FAKE_STATIC_DATA 00062 00063 // 00064 // Methods 00065 // 00066 00067 public: 00068 00069 //Constructors and Destructor 00070 StateStorage(); 00071 StateStorage(StateStorage const & other); 00072 StateStorage & operator=( const StateStorage & other ); 00073 00074 //Client Info Accessors 00075 00076 /** 00077 * 00078 * @brief access the client information associated with the given state 00079 * 00080 * This method provides access to the client information associated with this state. 00081 * 00082 * @param - state: the state whose client information to retrieve 00083 * @return the client information associated with the given state 00084 * 00085 */ 00086 ClientInfoRefPtr getClientInfo( State state ) const; 00087 00088 /** 00089 * Q: If the state doesn't exit should we add the state(and assign it the given info)? 00090 * @brief set the client information associated with the given state 00091 * 00092 * This method sets the client information associated with the given state to the 00093 * client information provided. 00094 * Note: If there is already some client information associated with the given 00095 * state it is lost. 00096 * 00097 * @param - state: the state whose client information to set 00098 * @param - c: the desired client information for this state 00099 * 00100 */ 00101 void setClientInfo( State state, const ClientInfoRefPtr c ); 00102 00103 //State Accessors 00104 00105 00106 /** 00107 * 00108 * @brief removes all states 00109 * 00110 * This method removes all states from this collection. It also removes all 00111 * initial states and final states. 00112 * 00113 */ 00114 void clearStates( ); 00115 00116 /** 00117 * 00118 * @brief removes all initial states 00119 * 00120 * This method removes all states from the initial state set, but does not remove 00121 * any states from the state set. 00122 * 00123 */ 00124 void clearInitialStates( ); 00125 00126 /** 00127 * 00128 * @brief removes all final states 00129 * 00130 * This method removes all states from the final state set, but does not remove 00131 * any states from the state set. 00132 * 00133 */ 00134 void clearFinalStates( ); 00135 00136 /** 00137 * 00138 * @brief tests whether the given state is a member of this collection 00139 * 00140 * This method determines whether the given state is a member of this collection. 00141 * It returns true if the state is a member and false otherwise. 00142 * 00143 * @param - state: the state to test 00144 * @return true if the state is a member of this collection of states 00145 * 00146 */ 00147 bool isState( State state ) const; 00148 00149 /** 00150 * 00151 * @brief tests whether the given state is an initial state of this collection 00152 * 00153 * This method determines whether the given state is an initial state of this 00154 * collection. It returns true if the state is an initial state and false otherwise. 00155 * 00156 * @param - initialState: the state to test 00157 * @return true if the state is an initial state of this collection, false otherwise 00158 * 00159 */ 00160 bool isInitialState( State initialState ) const; 00161 00162 /** 00163 * 00164 * @brief tests whether the given state is a final state of this collection 00165 * 00166 * This method determines whether the given state is a final state of this 00167 * collection. It returns true if the state is a final state and false otherwise. 00168 * 00169 * @param - finalState: the state to test 00170 * @return true if the state is a final state of this collection, false otherwise 00171 * 00172 */ 00173 bool isFinalState( State finalState ) const; 00174 00175 /** 00176 * 00177 * @brief add the given state 00178 * 00179 * This method adds the given state. If the state already exists, false is 00180 * returned. Otherwise, true is returned. 00181 * 00182 * @param - state: the state to add 00183 * @return false if the state already exists, true otherwise 00184 * 00185 */ 00186 bool addState( State state ); 00187 00188 /** 00189 * 00190 * @brief add the given initial state 00191 * 00192 * This method adds the given state to this collection of states(if it does not 00193 * already exist). The given initial state is then added to the initial states. 00194 * If the state is already an initial state, false is returned. Otherwise, true 00195 * is returned. 00196 * 00197 * @param - initialState: the initial state to add 00198 * @return false if the state is already an initial state, true otherwise 00199 * 00200 */ 00201 bool addInitialState( State initialState ); 00202 00203 /** 00204 * 00205 * @brief add the given final state 00206 * 00207 * This method adds the given state to this collection of states(if it does not 00208 * already exist). The given final state is then added to the final states. If 00209 * the state is already a final state, false is returned. Otherwise, true is 00210 * returned. 00211 * 00212 * @param - finalState: the final state to add 00213 * @return false if the state is already a final state, true otherwise 00214 * 00215 */ 00216 bool addFinalState( State finalState ); 00217 00218 /** 00219 * 00220 * @brief add all states in the given collection to this collection of states 00221 * 00222 * This method adds all of the states in the given collection of states to this 00223 * collection of states. 00224 * 00225 * @param - stateSet: the collection of states to add to this collection of states 00226 * 00227 */ 00228 void addAll( const StateStorage & stateSet ); 00229 00230 /** 00231 * 00232 * @brief add all the states in the given StateStorage 00233 * 00234 * This method adds all of the given states to the state set. 00235 * 00236 * @param - stateSet: the StateStorage that contains the states to add 00237 * 00238 */ 00239 void addAllStates( const StateStorage & stateSet ); 00240 00241 /** 00242 * 00243 * @brief add all the initial states in the given StateStorage 00244 * 00245 * This method adds all of the given initial states to the initial state set (and 00246 * thus to the state set if they are not already elements of the state set). 00247 * 00248 * @param - stateSet: the StateStorage that contains the states to add 00249 * 00250 */ 00251 void addAllInitialStates( const StateStorage & stateSet ); 00252 00253 /** 00254 * 00255 * @brief add all the final states in the given StateStorage 00256 * 00257 * This method adds all of the given final states to the final state set (and thus 00258 * to the state set if they are not already elements of the state set). 00259 * 00260 * @param - stateSet: the StateStorage that contains the states to add 00261 * 00262 */ 00263 void addAllFinalStates( const StateStorage & stateSet ); 00264 00265 /** 00266 * 00267 * @brief remove the given state 00268 * 00269 * This method removes the given state. If the state does not exist, false is 00270 * returned. Otherwise, true is returned. 00271 * Note: If the given state is an initial state or a final state, it is also 00272 * removed from that set. 00273 * 00274 * @param - state: the state to remove 00275 * @return false if this state does not exist, true otherwise 00276 * 00277 */ 00278 bool removeState( State state ); 00279 00280 /** 00281 * 00282 * @brief remove the given initial state 00283 * 00284 * This method removes the given initial state. If the state is not an initial 00285 * state, false is returned. Otherwise, true is returned. 00286 * Note: The state is not removed from the state set. 00287 * 00288 * @param - initialState: the initial state to remove 00289 * @return false if this state is not an initial state, true otherwise 00290 * 00291 */ 00292 bool removeInitialState( State initialState ); 00293 00294 /** 00295 * 00296 * @brief remove the given final state 00297 * 00298 * This method removes the given final state. If the state is not a final state, 00299 * false is returned. Otherwise, true is returned. 00300 * Note: The state is not removed from the state set. 00301 * 00302 * @param - finalState: the final state to remove 00303 * @remove false if this state is not a final state, true otherwise 00304 * 00305 */ 00306 bool removeFinalState( State finalState ); 00307 00308 //Utilities 00309 00310 /** 00311 * 00312 * @brief print the collection of states 00313 * 00314 * This method prints out the keys associated with the state set to the output 00315 * stream provided. 00316 * 00317 * @param - o: the output stream to print to 00318 * @return the output stream that was printed to 00319 * 00320 */ 00321 std::ostream & print( std::ostream & o ) const; 00322 00323 /** 00324 * 00325 * @brief tests whether this collection of states is equivalent to the collection 00326 * of states 'other' 00327 * 00328 * This method tests the equivalence of this set of states and the set of states 00329 * 'other'. 00330 * 00331 * @param - other: the StateStorage to compare this StateStorage to 00332 * @return true if this StateStorage is equivalent to the StateStorage 'other' 00333 * 00334 */ 00335 bool operator==( const StateStorage & other ) const; 00336 00337 /** 00338 * 00339 * @brief provides access to the states in the collection 00340 * 00341 * This method provides access to the states in this collection through an iterator. 00342 * 00343 * @return the starting point of an iterator through the states 00344 * 00345 */ 00346 const_iterator beginStates( ) const; 00347 00348 /** 00349 * 00350 * @brief provides access to the initial states in the collection 00351 * 00352 * This method provides access to the initial states in this collection through an 00353 * iterator. 00354 * 00355 * @return the starting point of an iterator through the initial states 00356 * 00357 */ 00358 const_iterator beginInitialStates( ) const; 00359 00360 /** 00361 * 00362 * @brief provides access to the final states in the collection 00363 * 00364 * This method provides access to the final states in this collection through an 00365 * iterator. 00366 * 00367 * @return the starting point of an iterator through the final states 00368 * 00369 */ 00370 const_iterator beginFinalStates( ) const; 00371 00372 /** 00373 * 00374 * @brief provides access to the states in the collection 00375 * 00376 * This method provides access to the states in the collection through an iterator. 00377 * 00378 * @return one place past the exit point of an iterator through the states 00379 * 00380 */ 00381 const_iterator endStates( ) const; 00382 00383 /** 00384 * 00385 * @brief provides access to the initial states in the collection 00386 * 00387 * This method provides access to the initial states in the collection through an 00388 * iterator. 00389 * 00390 * @return one place past the exit point of an iterator through the initial states 00391 * 00392 */ 00393 const_iterator endInitialStates( ) const; 00394 00395 /** 00396 * 00397 * @brief provides access to the final states in the collection 00398 * 00399 * This method provides access to the final states in the collection through an 00400 * iterator. 00401 * 00402 * @return one place past the exit point of an iterator through the final states 00403 * 00404 */ 00405 const_iterator endFinalStates( ) const; 00406 00407 /** 00408 * 00409 * @brief provides access to all states in the collection 00410 * 00411 * This method provides access to all states in this collection in the form of a 00412 * set of states. 00413 * 00414 * @return a set containing all states in this collection 00415 * 00416 */ 00417 const StateSet & getStates( ) const; 00418 00419 /** 00420 * 00421 * @brief provides access to the names of all the initial states in the collection 00422 * 00423 * This method provides access to the names of all the initial states in the 00424 * collection in the form of a set of state names. 00425 * 00426 * @return a set containing the names of all initial states in the collection 00427 * 00428 */ 00429 const StateSet & getInitialStates( ) const; 00430 00431 /** 00432 * 00433 * @brief provides access to the names of all final states in the collection 00434 * 00435 * This method provides access to the names of all the final states in the 00436 * collection in the form of a set of state names. 00437 * 00438 * @return a set containing the names of all final states in the collection 00439 * 00440 */ 00441 const StateSet & getFinalStates( ) const; 00442 00443 /** 00444 * 00445 * @brief returns the number of states in this collection 00446 * 00447 * This method returns the number of states in this collection. 00448 * Note: This will always be at least 1 as the stuck state is 00449 * always a legitimate state. 00450 * 00451 * @return the number of states in this collection 00452 * 00453 */ 00454 size_t sizeStates( ) const; 00455 00456 size_t largestState() const { 00457 return *states.rbegin(); 00458 } 00459 00460 /** 00461 * 00462 * @brief returns the number of initial states in this collection 00463 * 00464 * This method returns the number of initial states in this collection. 00465 * 00466 * @return the number of initial states in this collection 00467 * 00468 */ 00469 size_t sizeInitialStates( ) const; 00470 00471 /** 00472 * 00473 * @brief returns the number of final states in this collection 00474 * 00475 * This method returns the number of final states in this collection. 00476 * 00477 * @return the number of final states in this collection 00478 * 00479 */ 00480 size_t sizeFinalStates( ) const; 00481 00482 /** 00483 * 00484 * @brief gives 'dup' all the state properties of 'orig' 00485 * 00486 * This method checks all the state properties (initial/final) of 'orig' and 00487 * assigns the same properties to 'dup'. 00488 * 00489 * @param - orig: the state whose properties to duplicate 00490 * @param - dup: the state whose properties are being set 00491 * 00492 */ 00493 void dupState( State orig, State dup ); 00494 00495 // 00496 // Variables 00497 // 00498 00499 protected: 00500 00501 StateSet states; 00502 StateSet initialStates; 00503 StateSet finalStates; 00504 00505 std::map<State,ClientInfoRefPtr> stateInfos; 00506 }; 00507 00508 00509 } 00510 } 00511 00512 // Yo, Emacs! 00513 // Local Variables: 00514 // c-file-style: "ellemtel" 00515 // c-basic-offset: 2 00516 // End: 00517 00518 #endif 00519