00001 // -*- C++ -*- 00002 /*************************************************************************** 00003 * 00004 * The IPPL Framework 00005 * 00006 * 00007 * Visit http://people.web.psi.ch/adelmann/ for more details 00008 * 00009 ***************************************************************************/ 00010 00011 #ifndef TAG_MAKER_H 00012 #define TAG_MAKER_H 00013 00014 /* 00015 * TagMaker.h - creates tags from a given base tag and a cycle size. New 00016 * tags are generated each time one is requested, by adding an 00017 * integer which varies from 0 ... (cycle size - 1) to the provided 00018 * base tag. Routines exist to establish a base tag and cycle size, 00019 * and to get a new tag for a given base tag. 00020 */ 00021 00022 00023 // include files 00024 #ifdef IPPL_STDSTL 00025 #include <map> 00026 using std::map; 00027 #else 00028 #include <map.h> 00029 #endif // IPPL_STDSTL 00030 00031 00032 // default cycle size, if not specified by the user 00033 #define DEF_CYCLE_SIZE 1000 00034 00035 00036 class TagMaker { 00037 00038 public: 00039 // constructor/destructor 00040 TagMaker(void) { } 00041 ~TagMaker(void) { } 00042 00043 // generate a new tag given a base tag. If the base tag has not been 00044 // previously established by create_base_tag, it will be done so by 00045 // this routine with the default cycle size. A new tag can be established 00046 // at the same time by also giving a cycle size as the second argument. 00047 int next_tag(int t, int s = DEF_CYCLE_SIZE) { 00048 TagInfo& found = create_base_tag(t, s); 00049 found.current = (found.current + 1) % found.cycleSize; 00050 return (found.base + found.current); 00051 } 00052 00053 // just return the `current' tag that is to be generated from the 00054 // given base tag, without incrementing the cycle counter. 00055 int current_tag(int t, int s = DEF_CYCLE_SIZE) { 00056 TagInfo& found = create_base_tag(t, s); 00057 return (found.base + found.current); 00058 } 00059 00060 // reset the cycle counter for the given tag to be 0. If the tag is 00061 // not in the list, it is added. Returns the reset tag. 00062 int reset_tag(int t, int s = DEF_CYCLE_SIZE) { 00063 TagInfo& found = create_base_tag(t, s); 00064 found.current = 0; 00065 return found.base; 00066 } 00067 00068 private: 00069 // Simple struct holding info about the cycle size and current tag 00070 // for a base tag 00071 class TagInfo { 00072 public: 00073 int base; // base tag value, the key for the map 00074 int cycleSize; // range through which to cycle tag 00075 int current; // current value of tag 00076 TagInfo(int b, int s) : base(b), cycleSize(s), current(0) { } 00077 TagInfo() : base(-1), cycleSize(-1), current(0) { } 00078 }; 00079 00080 // class used for comparisons 00081 class TagCompare { 00082 public: 00083 bool operator()(const int& x, const int& y) const { return x < y; } 00084 }; 00085 00086 // the list of base tags which have been established 00087 map<int, TagInfo, TagCompare> TagList; 00088 00089 // Establish a new base tag and cycle size. Returns a reference to 00090 // the new TagInfo structure. 00091 // Arguments are: base tag, cycle size. 00092 TagInfo& create_base_tag(int t, int s = DEF_CYCLE_SIZE) { 00093 TagInfo& found = TagList[t]; 00094 if ( found.base < 0 ) { 00095 found.base = t; 00096 found.cycleSize = s; 00097 } 00098 return TagList[t]; 00099 } 00100 00101 }; 00102 00103 #endif // TAG_MAKER_H 00104 00105 /*************************************************************************** 00106 * $RCSfile: TagMaker.h,v $ $Author: adelmann $ 00107 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:28 $ 00108 * IPPL_VERSION_ID: $Id: TagMaker.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 00109 ***************************************************************************/