mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-26 07:34:06 +00:00
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
This commit is contained in:
parent
b5ec947b5e
commit
11ffccf2a5
@ -15,7 +15,9 @@
|
|||||||
#ifndef LLVM_ADT_TRIE_H
|
#ifndef LLVM_ADT_TRIE_H
|
||||||
#define LLVM_ADT_TRIE_H
|
#define LLVM_ADT_TRIE_H
|
||||||
|
|
||||||
#include <map>
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
|
#include "llvm/Support/DOTGraphTraits.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -24,12 +26,15 @@ namespace llvm {
|
|||||||
// - Labels are usually small, maybe it's better to use SmallString
|
// - Labels are usually small, maybe it's better to use SmallString
|
||||||
// - Should we use char* during construction?
|
// - Should we use char* during construction?
|
||||||
// - Should we templatize Empty with traits-like interface?
|
// - Should we templatize Empty with traits-like interface?
|
||||||
// - GraphTraits interface
|
|
||||||
|
|
||||||
template<class Payload>
|
template<class Payload>
|
||||||
class Trie {
|
class Trie {
|
||||||
|
friend class GraphTraits<Trie<Payload> >;
|
||||||
|
friend class DOTGraphTraits<Trie<Payload> >;
|
||||||
|
public:
|
||||||
class Node {
|
class Node {
|
||||||
friend class Trie;
|
friend class Trie;
|
||||||
|
friend class GraphTraits<Trie<Payload> >;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Same = -3,
|
Same = -3,
|
||||||
@ -53,43 +58,10 @@ class Trie {
|
|||||||
std::string Label;
|
std::string Label;
|
||||||
Payload Data;
|
Payload Data;
|
||||||
NodeVector Children;
|
NodeVector Children;
|
||||||
public:
|
|
||||||
inline explicit Node(const Payload& data, const std::string& label = ""):
|
|
||||||
Label(label), Data(data) { }
|
|
||||||
|
|
||||||
inline Node(const Node& n) {
|
// Do not implement
|
||||||
Data = n.Data;
|
Node(const Node&);
|
||||||
Children = n.Children;
|
Node& operator=(const Node&);
|
||||||
Label = n.Label;
|
|
||||||
}
|
|
||||||
inline Node& operator=(const Node& n) {
|
|
||||||
if (&n != this) {
|
|
||||||
Data = n.Data;
|
|
||||||
Children = n.Children;
|
|
||||||
Label = n.Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isLeaf() const { return Children.empty(); }
|
|
||||||
|
|
||||||
inline const Payload& getData() const { return Data; }
|
|
||||||
inline void setData(const Payload& data) { Data = data; }
|
|
||||||
|
|
||||||
inline void setLabel(const std::string& label) { Label = label; }
|
|
||||||
inline const std::string& getLabel() const { return Label; }
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
inline void dump() {
|
|
||||||
std::cerr << "Node: " << this << "\n"
|
|
||||||
<< "Label: " << Label << "\n"
|
|
||||||
<< "Children:\n";
|
|
||||||
|
|
||||||
for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
|
|
||||||
std::cerr << (*I)->Label << "\n";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void addEdge(Node* N) {
|
inline void addEdge(Node* N) {
|
||||||
if (Children.empty())
|
if (Children.empty())
|
||||||
@ -102,16 +74,6 @@ class Trie {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Node* getEdge(char Id) {
|
|
||||||
Node* fNode = NULL;
|
|
||||||
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
|
||||||
Id, NodeCmp());
|
|
||||||
if (I != Children.end() && (*I)->Label[0] == Id)
|
|
||||||
fNode = *I;
|
|
||||||
|
|
||||||
return fNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setEdge(Node* N) {
|
inline void setEdge(Node* N) {
|
||||||
char Id = N->Label[0];
|
char Id = N->Label[0];
|
||||||
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
||||||
@ -141,13 +103,42 @@ class Trie {
|
|||||||
} else // s and Label have common (possible empty) part, return its length
|
} else // s and Label have common (possible empty) part, return its length
|
||||||
return (QueryResult)i;
|
return (QueryResult)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline explicit Node(const Payload& data, const std::string& label = ""):
|
||||||
|
Label(label), Data(data) { }
|
||||||
|
|
||||||
|
inline const Payload& data() const { return Data; }
|
||||||
|
inline void setData(const Payload& data) { Data = data; }
|
||||||
|
|
||||||
|
inline const std::string& label() const { return Label; }
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
inline void dump() {
|
||||||
|
std::cerr << "Node: " << this << "\n"
|
||||||
|
<< "Label: " << Label << "\n"
|
||||||
|
<< "Children:\n";
|
||||||
|
|
||||||
|
for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
|
||||||
|
std::cerr << (*I)->Label << "\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline Node* getEdge(char Id) {
|
||||||
|
Node* fNode = NULL;
|
||||||
|
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
||||||
|
Id, NodeCmp());
|
||||||
|
if (I != Children.end() && (*I)->Label[0] == Id)
|
||||||
|
fNode = *I;
|
||||||
|
|
||||||
|
return fNode;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
std::vector<Node*> Nodes;
|
std::vector<Node*> Nodes;
|
||||||
Payload Empty;
|
Payload Empty;
|
||||||
|
|
||||||
inline Node* getRoot() const { return Nodes[0]; }
|
|
||||||
|
|
||||||
inline Node* addNode(const Payload& data, const std::string label = "") {
|
inline Node* addNode(const Payload& data, const std::string label = "") {
|
||||||
Node* N = new Node(data, label);
|
Node* N = new Node(data, label);
|
||||||
Nodes.push_back(N);
|
Nodes.push_back(N);
|
||||||
@ -172,6 +163,10 @@ class Trie {
|
|||||||
return nNode;
|
return nNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not implement
|
||||||
|
Trie(const Trie&);
|
||||||
|
Trie& operator=(const Trie&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline explicit Trie(const Payload& empty):Empty(empty) {
|
inline explicit Trie(const Payload& empty):Empty(empty) {
|
||||||
addNode(Empty);
|
addNode(Empty);
|
||||||
@ -181,6 +176,8 @@ public:
|
|||||||
delete Nodes[i];
|
delete Nodes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Node* getRoot() const { return Nodes[0]; }
|
||||||
|
|
||||||
bool addString(const std::string& s, const Payload& data) {
|
bool addString(const std::string& s, const Payload& data) {
|
||||||
Node* cNode = getRoot();
|
Node* cNode = getRoot();
|
||||||
Node* tNode = NULL;
|
Node* tNode = NULL;
|
||||||
@ -202,7 +199,7 @@ public:
|
|||||||
assert(0 && "Impossible!");
|
assert(0 && "Impossible!");
|
||||||
return false;
|
return false;
|
||||||
case Node::LabelIsPrefix:
|
case Node::LabelIsPrefix:
|
||||||
s1 = s1.substr(nNode->getLabel().length());
|
s1 = s1.substr(nNode->label().length());
|
||||||
cNode = nNode;
|
cNode = nNode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -239,7 +236,7 @@ public:
|
|||||||
assert(0 && "Impossible!");
|
assert(0 && "Impossible!");
|
||||||
return Empty;
|
return Empty;
|
||||||
case Node::LabelIsPrefix:
|
case Node::LabelIsPrefix:
|
||||||
s1 = s1.substr(nNode->getLabel().length());
|
s1 = s1.substr(nNode->label().length());
|
||||||
cNode = nNode;
|
cNode = nNode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -249,11 +246,69 @@ public:
|
|||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tNode->getData();
|
return tNode->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
template<class Payload>
|
||||||
|
struct GraphTraits<Trie<Payload> > {
|
||||||
|
typedef typename Trie<Payload>::Node NodeType;
|
||||||
|
typedef typename std::vector<NodeType*>::iterator ChildIteratorType;
|
||||||
|
|
||||||
|
static inline NodeType *getEntryNode(const Trie<Payload>& T) {
|
||||||
|
return T.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||||
|
return N->Children.begin();
|
||||||
|
}
|
||||||
|
static inline ChildIteratorType child_end(NodeType *N) {
|
||||||
|
return N->Children.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename std::vector<NodeType*>::const_iterator nodes_iterator;
|
||||||
|
|
||||||
|
static inline nodes_iterator nodes_begin(const Trie<Payload>& G) {
|
||||||
|
return G.Nodes.begin();
|
||||||
|
}
|
||||||
|
static inline nodes_iterator nodes_end(const Trie<Payload>& G) {
|
||||||
|
return G.Nodes.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Payload>
|
||||||
|
struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
|
||||||
|
typedef typename Trie<Payload>::Node NodeType;
|
||||||
|
typedef typename GraphTraits<Trie<Payload> >::ChildIteratorType EdgeIter;
|
||||||
|
|
||||||
|
static std::string getGraphName(const Trie<Payload>& T) {
|
||||||
|
return "Trie";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
|
||||||
|
if (T.getRoot() == Node)
|
||||||
|
return "<Root>";
|
||||||
|
else
|
||||||
|
return Node->label();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
|
||||||
|
NodeType* N = *I;
|
||||||
|
return N->label().substr(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getNodeAttributes(const NodeType* Node,
|
||||||
|
const Trie<Payload>& T) {
|
||||||
|
if (Node->data() != T.Empty)
|
||||||
|
return "color=blue";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of llvm namespace
|
||||||
|
|
||||||
#endif // LLVM_ADT_TRIE_H
|
#endif // LLVM_ADT_TRIE_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user