~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/name_map.h

  • Committer: Brian Aker
  • Date: 2009-12-05 01:48:28 UTC
  • mfrom: (1237.2.12 push)
  • Revision ID: brian@gaz-20091205014828-xd4e29ujttx2xe2j
MergeĀ forĀ staging.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#ifndef DRIZZLED_NAME_MAP_H
21
 
#define DRIZZLED_NAME_MAP_H
22
 
 
23
 
#include <map>
24
 
#include <set>
25
 
#include <string>
26
 
#include <vector>
27
 
#include <algorithm>
28
 
#include <functional>
29
 
 
30
 
namespace drizzled {
31
 
 
32
 
namespace internal {
33
 
 
34
 
template<class T>
35
 
struct NameMapCompare
36
 
{
37
 
  bool operator() (const T& a, const T& b) const
38
 
  {
39
 
    return a.getName() < b.getName();
40
 
  }
41
 
};
42
 
 
43
 
template<class T>
44
 
struct NameMapCompare<T *>
45
 
{
46
 
  bool operator() (const T* a, const T* b) const
47
 
  {
48
 
    return a->getName() < b->getName();
49
 
  }
50
 
};
51
 
 
52
 
} /* namespace internal */
53
 
 
54
 
template<class T>
55
 
class NameMap
56
 
{
57
 
  std::map<std::string, T> item_map;
58
 
  std::set<T,internal::NameMapCompare<T> > item_set;
59
 
 
60
 
  bool addItemEntry(std::string name, T item)
61
 
  {
62
 
    if (item_map.count(name) == 0)
63
 
    {
64
 
      item_map[name]= item;
65
 
      return false;
66
 
    }
67
 
    return true;
68
 
  }
69
 
 
70
 
  bool addItem(std::string name, T item)
71
 
  {
72
 
 
73
 
    /* First, add with no transform */
74
 
    if (addItemEntry(name, item))
75
 
      return true;
76
 
 
77
 
    /* Transform to lower, then add */ 
78
 
    std::transform(name.begin(), name.end(),
79
 
                   name.begin(), ::tolower);
80
 
 
81
 
    /* Ignore failures here - the original name could be all lower */
82
 
    addItemEntry(name, item);
83
 
 
84
 
    /* Transform to upper, then add */ 
85
 
    std::transform(name.begin(), name.end(),
86
 
                   name.begin(), ::toupper);
87
 
 
88
 
    /* Ignore failures here - the original name could be all upper */
89
 
    addItemEntry(name, item);
90
 
 
91
 
    return false;
92
 
  }
93
 
 
94
 
  void removeItem(std::string name)
95
 
  {
96
 
 
97
 
    /* First, remove with no transform */
98
 
    item_map.erase(name);
99
 
 
100
 
    /* Transform to lower, then remove */ 
101
 
    std::transform(name.begin(), name.end(),
102
 
                   name.begin(), ::tolower);
103
 
    item_map.erase(name);
104
 
  }
105
 
 
106
 
public:
107
 
 
108
 
  typedef typename std::set<T>::const_iterator const_iterator;
109
 
  typedef typename std::set<T>::iterator iterator;
110
 
  typedef size_t size_type;
111
 
 
112
 
  T find(const char *name, size_t length) const
113
 
  {
114
 
    std::string find_str(name, length);
115
 
    return find(find_str);
116
 
  }
117
 
 
118
 
  T find(const std::string &name) const
119
 
  {
120
 
 
121
 
    typename std::map<std::string, T>::const_iterator find_iter;
122
 
    find_iter=  item_map.find(name);
123
 
    if (find_iter != item_map.end())
124
 
      return (*find_iter).second;
125
 
    
126
 
    /* We must look for lower case, so we make a copy of the input name */
127
 
    std::string lower_name(name);
128
 
    std::transform(lower_name.begin(), lower_name.end(),
129
 
                   lower_name.begin(), ::tolower);
130
 
    find_iter=  item_map.find(lower_name);
131
 
    if (find_iter != item_map.end())
132
 
      return (*find_iter).second;
133
 
 
134
 
    return NULL;
135
 
  }
136
 
 
137
 
  /**
138
 
   * True == failure
139
 
   */
140
 
  bool add(T item)
141
 
  {
142
 
    bool failed= false;
143
 
 
144
 
    if (item_set.insert(item).second == false)
145
 
      return true;
146
 
 
147
 
    if (addItem(item->getName(), item))
148
 
      failed= true;
149
 
 
150
 
    const std::vector<std::string>& aliases= item->getAliases();
151
 
    if (!(failed) && (aliases.size() > 0))
152
 
    {
153
 
      typename std::vector<std::string>::const_iterator iter= aliases.begin();
154
 
      while (iter != aliases.end())
155
 
      {
156
 
        if(addItem(*iter, item))
157
 
          failed= true;
158
 
        ++iter;
159
 
      }
160
 
    }
161
 
   
162
 
    if (failed == true)
163
 
      remove(item);
164
 
    return failed; 
165
 
  }
166
 
 
167
 
  /**
168
 
   * Remove an item from the registry. We don't care about failure
169
 
   */
170
 
  void remove(T item)
171
 
  {
172
 
    removeItem(item->getName());
173
 
 
174
 
    const std::vector<std::string>& aliases= item->getAliases();
175
 
    if (aliases.size() > 0)
176
 
    {
177
 
      std::vector<std::string>::const_iterator iter= aliases.begin();
178
 
      while (iter != aliases.end())
179
 
      {
180
 
        removeItem(*iter);
181
 
        ++iter;
182
 
      }
183
 
    }
184
 
  }
185
 
 
186
 
  iterator begin()
187
 
  {
188
 
    return item_set.begin();
189
 
  }
190
 
 
191
 
  iterator end()
192
 
  {
193
 
    return item_set.end();
194
 
  }
195
 
 
196
 
  const_iterator begin() const
197
 
  {
198
 
    return item_set.begin();
199
 
  }
200
 
 
201
 
  const_iterator end() const
202
 
  {
203
 
    return item_set.end();
204
 
  }
205
 
 
206
 
  size_type count(std::string name) const
207
 
  {
208
 
    /* Transform to lower, then add */
209
 
    std::transform(name.begin(), name.end(),
210
 
                   name.begin(), ::tolower);
211
 
    return item_map.count(name);
212
 
  }
213
 
 
214
 
  size_type size() const
215
 
  {
216
 
    return item_set.size();
217
 
  }
218
 
};
219
 
 
220
 
} /* namespace drizzled */
221
 
 
222
 
#endif /* DRIZZLED_NAME_MAP_H */
223