source: icGREP/icgrep-devel/icgrep/re/re_name.h

Last change on this file was 5887, checked in by cameron, 4 months ago

Separate compilation of Unicode property kernels

File size: 5.9 KB
Line 
1#ifndef RE_NAME_H
2#define RE_NAME_H
3
4#include <re/re_re.h>
5#include <re/re_cc.h>
6#include <llvm/Support/Casting.h>
7
8namespace UCD {
9    class UnicodeSet;
10}
11
12namespace re {
13
14class Name : public RE {
15public:
16    static inline bool classof(const RE * re) {
17        return re->getClassTypeId() == ClassTypeId::Name;
18    }
19    static inline bool classof(const void *) {
20        return false;
21    }
22    using length_t = std::string::size_type;
23    enum class Type {
24        Unicode
25        , UnicodeProperty
26        , Capture
27        , Reference
28        , ZeroWidth
29        , Unknown
30    };
31    std::string getNamespace() const;
32    bool hasNamespace() const;
33    std::string getName() const;
34    std::string getFullName() const;
35    Type getType() const;
36    RE * getDefinition() const;
37    bool operator<(const Name & other) const;
38    bool operator<(const CC & other) const;
39    bool operator>(const CC & other) const;
40    void setDefinition(RE * definition);
41    virtual ~Name() {}
42protected:
43    friend Name * makeName(const std::string & name, RE * cc);
44    friend Name * makeCapture(const std::string & name, RE * captured);
45    friend Name * makeReference(const std::string & name, RE * captureName);
46    friend Name * makeZeroWidth(const std::string & name, RE * zerowidth);
47    friend Name * makeName(CC * const cc);
48    friend Name * makeName(const std::string &, Type);
49    friend Name * makeName(const std::string &, const std::string &, Type);
50    friend Name * makeName(const std::string & nm, const Name::Type type, RE * defn); 
51    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, Type type, RE * defn)
52    : RE(ClassTypeId::Name)
53    , mNamespaceLength(namespaceLength)
54    , mNamespace(replicateString(nameSpace, namespaceLength))
55    , mNameLength(nameLength)
56    , mName(replicateString(name, nameLength))
57    , mType(type)
58    , mDefinition(defn) {
59
60    }
61    inline const char * replicateString(const char * string, const length_t length) {
62        if (string && (length > 0)) {
63            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
64            std::memcpy(allocated, string, length);
65            return allocated;
66        }
67        return nullptr;
68    }
69
70private:
71    const length_t      mNamespaceLength;
72    const char * const  mNamespace;
73    const length_t      mNameLength;
74    const char * const  mName;
75    Type                mType;
76    RE *                mDefinition;
77};
78
79inline std::string Name::getNamespace() const {
80    return std::string(mNamespace, mNamespaceLength);
81}
82
83inline bool Name::hasNamespace() const {
84    return (mNamespaceLength != 0);
85}
86
87inline std::string Name::getName() const {
88    return std::string(mName, mNameLength);
89}
90
91inline std::string Name::getFullName() const {
92    if (hasNamespace()) return getNamespace() + "=" + getName();
93    else return getName();
94}
95
96inline Name::Type Name::getType() const {
97    return mType;
98}
99
100inline RE * Name::getDefinition() const {
101    return mDefinition;
102}
103
104inline void Name::setDefinition(RE * definition) {
105    assert (definition != nullptr);
106    assert (definition != this);
107    mDefinition = definition;
108}
109
110inline bool Name::operator < (const Name & other) const {
111    if (LLVM_LIKELY(mDefinition && other.mDefinition && llvm::isa<CC>(mDefinition) && llvm::isa<CC>(other.mDefinition))) {
112        return *llvm::cast<CC>(mDefinition) < *llvm::cast<CC>(other.mDefinition);
113    } else if (mNamespaceLength < other.mNamespaceLength) {
114        return true;
115    } else if (mNamespaceLength > other.mNamespaceLength) {
116        return false;
117    } else if (mNameLength < other.mNameLength) {
118        return true;
119    } else if (mNameLength > other.mNameLength) {
120        return false;
121    }
122    const auto diff = std::memcmp(mNamespace, other.mNamespace, mNamespaceLength);
123    if (diff < 0) {
124        return true;
125    } else if (diff > 0) {
126        return false;
127    }
128    return (std::memcmp(mName, other.mName, mNameLength) < 0);
129}
130
131inline bool Name::operator < (const CC & other) const {
132    if (mDefinition && llvm::isa<CC>(mDefinition)) {
133        return *llvm::cast<CC>(mDefinition) < other;
134    }
135    return RE::ClassTypeId::Name < RE::ClassTypeId::CC;
136}
137
138inline bool Name::operator > (const CC & other) const {
139    if (mDefinition && llvm::isa<CC>(mDefinition)) {
140        return other < *llvm::cast<CC>(mDefinition);
141    }
142    return RE::ClassTypeId::CC < RE::ClassTypeId::Name;
143}
144
145inline Name * makeName(const std::string & name, const Name::Type type) {
146    return new Name(nullptr, 0, name.c_str(), name.length(), type, nullptr);
147}
148
149inline Name * makeName(const std::string & property, const std::string & value, const Name::Type type) {
150    return new Name(property.c_str(), property.length(), value.c_str(), value.length(), type, nullptr);
151}
152   
153inline Name * makeName(const std::string & nm, const Name::Type type, RE * defn) {
154    return new Name(nullptr, 0, nm.c_str(), nm.length(), type, defn);
155}
156
157inline Name * makeName(const std::string & name, RE * cc) {
158    if (llvm::isa<Name>(cc)) {
159        return llvm::cast<Name>(cc);
160    }
161    else if (llvm::isa<CC>(cc)) {
162        return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
163    }
164    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
165}
166
167inline Name * makeName(CC * const cc) {
168    const std::string name = cc->canonicalName();
169    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
170}
171
172inline Name * makeCapture(const std::string & name, RE * captured) {
173    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Capture, captured);
174}
175   
176inline Name * makeReference(const std::string & name, RE * captureName) {
177    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Reference, captureName);
178}
179
180inline Name * makeZeroWidth(const std::string & name, RE * zerowidth = NULL) {
181    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::ZeroWidth, zerowidth);
182}
183}
184
185#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.