llvm.org GIT mirror llvm / 11ffccf
Provide GraphTraits and DOTGraphTraits interface for Trie. Retoss private/public stuff. Make copy ctor and operator= private. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45067 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 12 years ago
1 changed file(s) with 110 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
1414 #ifndef LLVM_ADT_TRIE_H
1515 #define LLVM_ADT_TRIE_H
1616
17 #include
17 #include "llvm/ADT/GraphTraits.h"
18 #include "llvm/Support/DOTGraphTraits.h"
19
1820 #include
1921
2022 namespace llvm {
2325 // - Labels are usually small, maybe it's better to use SmallString
2426 // - Should we use char* during construction?
2527 // - Should we templatize Empty with traits-like interface?
26 // - GraphTraits interface
2728
2829 template
2930 class Trie {
31 friend class GraphTraits >;
32 friend class DOTGraphTraits >;
33 public:
3034 class Node {
3135 friend class Trie;
36 friend class GraphTraits >;
3237
3338 typedef enum {
3439 Same = -3,
5257 std::string Label;
5358 Payload Data;
5459 NodeVector Children;
55 public:
56 inline explicit Node(const Payload& data, const std::string& label = ""):
57 Label(label), Data(data) { }
58
59 inline Node(const Node& n) {
60 Data = n.Data;
61 Children = n.Children;
62 Label = n.Label;
63 }
64 inline Node& operator=(const Node& n) {
65 if (&n != this) {
66 Data = n.Data;
67 Children = n.Children;
68 Label = n.Label;
69 }
70
71 return *this;
72 }
73
74 inline bool isLeaf() const { return Children.empty(); }
75
76 inline const Payload& getData() const { return Data; }
77 inline void setData(const Payload& data) { Data = data; }
78
79 inline void setLabel(const std::string& label) { Label = label; }
80 inline const std::string& getLabel() const { return Label; }
81
82 #if 0
83 inline void dump() {
84 std::cerr << "Node: " << this << "\n"
85 << "Label: " << Label << "\n"
86 << "Children:\n";
87
88 for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
89 std::cerr << (*I)->Label << "\n";
90 }
91 #endif
60
61 // Do not implement
62 Node(const Node&);
63 Node& operator=(const Node&);
9264
9365 inline void addEdge(Node* N) {
9466 if (Children.empty())
10173 }
10274 }
10375
104 inline Node* getEdge(char Id) {
105 Node* fNode = NULL;
106 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
107 Id, NodeCmp());
108 if (I != Children.end() && (*I)->Label[0] == Id)
109 fNode = *I;
110
111 return fNode;
112 }
113
11476 inline void setEdge(Node* N) {
11577 char Id = N->Label[0];
11678 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
140102 } else // s and Label have common (possible empty) part, return its length
141103 return (QueryResult)i;
142104 }
105
106 public:
107 inline explicit Node(const Payload& data, const std::string& label = ""):
108 Label(label), Data(data) { }
109
110 inline const Payload& data() const { return Data; }
111 inline void setData(const Payload& data) { Data = data; }
112
113 inline const std::string& label() const { return Label; }
114
115 #if 0
116 inline void dump() {
117 std::cerr << "Node: " << this << "\n"
118 << "Label: " << Label << "\n"
119 << "Children:\n";
120
121 for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
122 std::cerr << (*I)->Label << "\n";
123 }
124 #endif
125
126 inline Node* getEdge(char Id) {
127 Node* fNode = NULL;
128 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
129 Id, NodeCmp());
130 if (I != Children.end() && (*I)->Label[0] == Id)
131 fNode = *I;
132
133 return fNode;
134 }
143135 };
144136
137 private:
145138 std::vector Nodes;
146139 Payload Empty;
147
148 inline Node* getRoot() const { return Nodes[0]; }
149140
150141 inline Node* addNode(const Payload& data, const std::string label = "") {
151142 Node* N = new Node(data, label);
171162 return nNode;
172163 }
173164
165 // Do not implement
166 Trie(const Trie&);
167 Trie& operator=(const Trie&);
168
174169 public:
175170 inline explicit Trie(const Payload& empty):Empty(empty) {
176171 addNode(Empty);
179174 for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
180175 delete Nodes[i];
181176 }
177
178 inline Node* getRoot() const { return Nodes[0]; }
182179
183180 bool addString(const std::string& s, const Payload& data) {
184181 Node* cNode = getRoot();
201198 assert(0 && "Impossible!");
202199 return false;
203200 case Node::LabelIsPrefix:
204 s1 = s1.substr(nNode->getLabel().length());
201 s1 = s1.substr(nNode->label().length());
205202 cNode = nNode;
206203 break;
207204 default:
238235 assert(0 && "Impossible!");
239236 return Empty;
240237 case Node::LabelIsPrefix:
241 s1 = s1.substr(nNode->getLabel().length());
238 s1 = s1.substr(nNode->label().length());
242239 cNode = nNode;
243240 break;
244241 default:
248245 return Empty;
249246 }
250247
251 return tNode->getData();
248 return tNode->data();
252249 }
253250
254251 };
255252
256 }
253 template
254 struct GraphTraits > {
255 typedef typename Trie::Node NodeType;
256 typedef typename std::vector::iterator ChildIteratorType;
257
258 static inline NodeType *getEntryNode(const Trie& T) {
259 return T.getRoot();
260 }
261
262 static inline ChildIteratorType child_begin(NodeType *N) {
263 return N->Children.begin();
264 }
265 static inline ChildIteratorType child_end(NodeType *N) {
266 return N->Children.end();
267 }
268
269 typedef typename std::vector::const_iterator nodes_iterator;
270
271 static inline nodes_iterator nodes_begin(const Trie& G) {
272 return G.Nodes.begin();
273 }
274 static inline nodes_iterator nodes_end(const Trie& G) {
275 return G.Nodes.end();
276 }
277
278 };
279
280 template
281 struct DOTGraphTraits > : public DefaultDOTGraphTraits {
282 typedef typename Trie::Node NodeType;
283 typedef typename GraphTraits >::ChildIteratorType EdgeIter;
284
285 static std::string getGraphName(const Trie& T) {
286 return "Trie";
287 }
288
289 static std::string getNodeLabel(NodeType* Node, const Trie& T) {
290 if (T.getRoot() == Node)
291 return "";
292 else
293 return Node->label();
294 }
295
296 static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
297 NodeType* N = *I;
298 return N->label().substr(0, 1);
299 }
300
301 static std::string getNodeAttributes(const NodeType* Node,
302 const Trie& T) {
303 if (Node->data() != T.Empty)
304 return "color=blue";
305
306 return "";
307 }
308
309 };
310
311 } // end of llvm namespace
257312
258313 #endif // LLVM_ADT_TRIE_H