00001 // SuperMix version 1.0 C++ source file 00002 // 00003 // Copyright (c) 1999 California Institute of Technology. 00004 // All rights reserved. 00005 // 00006 // Redistribution and use in source and binary forms for noncommercial 00007 // purposes are permitted provided that the above copyright notice and 00008 // this paragraph are duplicated in all such forms and that any 00009 // documentation and other materials related to such distribution and 00010 // use acknowledge that the software was developed by California 00011 // Institute of Technology. Redistribution and/or use in source or 00012 // binary forms is not permitted for any commercial purpose. Use of 00013 // this software does not include a permitted use of the Institute's 00014 // name or trademark for any purpose. 00015 // 00016 // DISCLAIMER: 00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT 00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR 00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET 00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE 00021 // LICENSED PRODUCT, HOWEVER USED. IN NO EVENT SHALL CALTECH/JPL BE 00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO 00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC 00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF 00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN 00026 // FACT SHALL KNOW OF THE POSSIBILITY. THE USER BEARS ALL RISK 00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED 00028 // MATERIALS. 00029 00030 // ******************************************************************** 00031 // 00032 // state_tag.h 00033 // 00034 // State tags are a system to allow devices to remember the operating 00035 // state at which they were last calculated. 00036 // 00037 // The idea is that if a caller asks for a calculation which depends upon 00038 // some external parameters which define a device's operating state, he would 00039 // first set up the parameters and then call state_tag::get_tag() to get a 00040 // new, unique state tag with which to refer to that state. The caller then 00041 // asks a device for its operating data, passing this state_tag to the 00042 // device. In the case of an nport (circuit) element, the caller would use 00043 // nport::get_data(state_tag). 00044 // 00045 // The device will then compare the state_tag passed by the caller to 00046 // its internally saved state_tag; if the two match, then the device 00047 // assumes that the external parameters which define its operating state 00048 // have not changed, so it can quickly return data based on the previous 00049 // operating state calculation without performing a lengthy recalculation. 00050 // If the state_tags do not match (or one of them is undefined), then the 00051 // device assumes that the parameters have changed, requiring a full 00052 // calculation. 00053 // 00054 // Realize that state tags are not intelligent. It is up to the user to 00055 // ensure that relevant parts of the system are in the same state each 00056 // time he uses a given state tag. 00057 // 00058 // When a state_tag object is first created, or is reset using the reset() 00059 // member function, then it is tagged as having an "undefined" state. Such 00060 // a state_tag will never match another state_tag (using ==), even if both 00061 // state_tags are undefined. Consequently, the undefined state_tag has a 00062 // special meaning, i.e. that a recalculation needs to be performed. 00063 // get_tag() will never return an undefined state_tag. 00064 // 00065 // 00066 // examples for using state_tag: 00067 // 00068 // state_tag s1, s2; 00069 // 00070 // undefined(s1); // true, since s1 is newly created 00071 // s1 == s2; // false, since undefined state_tags never match 00072 // 00073 // s1 = state_tag::get_tag(); // now s1 has a unique, defined value 00074 // s2 = s1; 00075 // s1 == s2; // true, since both are defined and equal 00076 // s2 = state_tag::get_tag(); // s2 has a new, unique value 00077 // s1 == s2; // false 00078 // 00079 // s1.reset(); // now we've erased defined value for s1 00080 // undefined(s1); // true 00081 // 00082 // 00083 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 00084 // state_tag::current_state is a static variable which must be defined and 00085 // initialized to some small value (like 1). Since most programs which 00086 // would use the supermix library will have to link to nport.o, the 00087 // initialization is performed there (see nport.cc). Beware that programs 00088 // that don't link to nport.o and still want to use state_tag must take care 00089 // of the initialization. 00090 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 00091 // 00092 // John Ward 4/21/99 00093 // 00094 // Change history: 00095 // 7/29/99: Some mainly cosmetic changes, added undefined() 00096 // 00097 // ******************************************************************** 00098 #ifndef STATE_TAG_H 00099 #define STATE_TAG_H 00100 00101 class state_tag 00102 { 00103 public: 00104 00105 // The default constructor sets the state_tag to the undefined state 00106 state_tag(); 00107 00108 // Call this function to get a unique state_tag. 00109 static state_tag get_tag(); 00110 00111 // Reset sets the state_tag to undefined, so it will not match 00112 // another state_tag. This will usually force a full recalculation 00113 // by a device which cares about state_tags. 00114 state_tag & reset(); 00115 00116 // Functions to compare the states of two state_tags 00117 friend bool undefined(const state_tag & s1); 00118 friend bool operator ==(const state_tag & s1, const state_tag & s2); 00119 friend bool operator !=(const state_tag & s1, const state_tag & s2); 00120 00121 private: 00122 enum {UNDEFINED = 0L}; // defines "undefined" 00123 00124 // The variable "tag" is the actual ID tag that this instance is holding. 00125 // No class needs to see the ID tag directly, they can only set it by 00126 // assignment or test it with == or !=. 00127 unsigned long tag; 00128 00129 // This counter keeps incrementing every time get_tag() is called. 00130 static unsigned long current_state; 00131 00132 }; 00133 00134 inline state_tag::state_tag() : tag(UNDEFINED) { } 00135 00136 inline state_tag state_tag::get_tag() 00137 { 00138 state_tag s; 00139 s.tag = ++current_state; 00140 return s; 00141 } 00142 00143 inline state_tag & state_tag::reset() 00144 { tag = UNDEFINED; return *this; } 00145 00146 inline bool undefined(const state_tag & s) { return state_tag::UNDEFINED == s.tag; } 00147 00148 inline bool operator ==(const state_tag & s1, const state_tag & s2) 00149 { 00150 return (state_tag::UNDEFINED != s1.tag && state_tag::UNDEFINED != s2.tag 00151 && s1.tag == s2.tag); 00152 } 00153 00154 inline bool operator !=(const state_tag & s1, const state_tag & s2) 00155 { return !(s1 == s2); } 00156 00157 #endif /* STATE_TAG_H */
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7