Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

state_tag.h

Go to the documentation of this file.
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 doxygen1.2.7