uniquenames.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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                 // error
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

Generated by  doxygen 1.6.2