uniquenames.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_UNIQUENAMES_H)
00023 #define INCLUDED_UNIQUENAMES_H
00024
00025 #include "debugging/debugging.h"
00026 #include <map>
00027 #include "string/string.h"
00028 #include "generic/static.h"
00029
00030 class Postfix
00031 {
00032 unsigned int m_value;
00033 public:
00034 Postfix (const std::string& postfix) :
00035 m_value(string::toInt(postfix))
00036 {
00037 }
00038 unsigned int number () const
00039 {
00040 return m_value;
00041 }
00042 void write (char* buffer)
00043 {
00044 sprintf(buffer, "%u", m_value);
00045 }
00046 Postfix& operator++ ()
00047 {
00048 ++m_value;
00049 return *this;
00050 }
00051 bool operator< (const Postfix& other) const
00052 {
00053 return m_value < other.m_value;
00054 }
00055 bool operator== (const Postfix& other) const
00056 {
00057 return m_value == other.m_value;
00058 }
00059 bool operator!= (const Postfix& other) const
00060 {
00061 return !operator==(other);
00062 }
00063 };
00064
00065 typedef std::pair<std::string, Postfix> name_t;
00066
00067 inline void name_write (char* buffer, name_t name)
00068 {
00069 strcpy(buffer, name.first.c_str());
00070 name.second.write(buffer + name.first.length());
00071 }
00072
00073 inline name_t name_read (const char* name)
00074 {
00075 const char* end = name + strlen(name);
00076 for (const char* p = end; end != name; --p) {
00077 if (strrchr("1234567890", *p) == NULL)
00078 break;
00079 end = p;
00080 }
00081
00082 return name_t(string::toString(string_clone_range(StringRange(name, end))), Postfix(end));
00083 }
00084
00085 class PostFixes
00086 {
00087 typedef std::map<Postfix, unsigned int> postfixes_t;
00088 postfixes_t m_postfixes;
00089
00090 Postfix find_first_empty () const
00091 {
00092 Postfix postfix("1");
00093 for (postfixes_t::const_iterator i = m_postfixes.find(postfix); i != m_postfixes.end(); ++i, ++postfix) {
00094 if ((*i).first != postfix) {
00095 break;
00096 }
00097 }
00098 return postfix;
00099 }
00100
00101 public:
00102 Postfix make_unique (Postfix postfix) const
00103 {
00104 postfixes_t::const_iterator i = m_postfixes.find(postfix);
00105 if (i == m_postfixes.end()) {
00106 return postfix;
00107 } else {
00108 return find_first_empty();
00109 }
00110 }
00111
00112 void insert (Postfix postfix)
00113 {
00114 postfixes_t::iterator i = m_postfixes.find(postfix);
00115 if (i == m_postfixes.end()) {
00116 m_postfixes.insert(postfixes_t::value_type(postfix, 1));
00117 } else {
00118 ++(*i).second;
00119 }
00120 }
00121
00122 void erase (Postfix postfix)
00123 {
00124 postfixes_t::iterator i = m_postfixes.find(postfix);
00125 if (i == m_postfixes.end()) {
00126
00127 } else {
00128 if (--(*i).second == 0)
00129 m_postfixes.erase(i);
00130 }
00131 }
00132
00133 bool empty () const
00134 {
00135 return m_postfixes.empty();
00136 }
00137 };
00138
00139 class UniqueNames
00140 {
00141 typedef std::map<std::string, PostFixes> names_t;
00142 names_t m_names;
00143 public:
00144 name_t make_unique (const name_t& name) const
00145 {
00146 names_t::const_iterator i = m_names.find(name.first);
00147 if (i == m_names.end()) {
00148 return name;
00149 } else {
00150 return name_t(name.first, (*i).second.make_unique(name.second));
00151 }
00152 }
00153
00154 void insert (const name_t& name)
00155 {
00156 m_names[name.first].insert(name.second);
00157 }
00158
00159 void erase (const name_t& name)
00160 {
00161 names_t::iterator i = m_names.find(name.first);
00162 if (i == m_names.end()) {
00163 ASSERT_MESSAGE(true, "erase: name not found");
00164 } else {
00165 (*i).second.erase(name.second);
00166 if ((*i).second.empty())
00167 m_names.erase(i);
00168 }
00169 }
00170
00171 bool empty () const
00172 {
00173 return m_names.empty();
00174 }
00175 };
00176
00177 #endif