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

Last change on this file since 5350 was 5267, checked in by nmedfort, 3 years ago

Code clean-up. Removed Pablo Call, SetIthBit? and Prototype.

File size: 5.6 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        Byte
25        , Unicode
26        , UnicodeProperty
27        , Capture
28        , Reference
29        , ZeroWidth
30        , Unknown
31    };
32    std::string getNamespace() const;
33    bool hasNamespace() const;
34    std::string getName() 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    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, Type type, RE * defn)
51    : RE(ClassTypeId::Name)
52    , mNamespaceLength(namespaceLength)
53    , mNamespace(replicateString(nameSpace, namespaceLength))
54    , mNameLength(nameLength)
55    , mName(replicateString(name, nameLength))
56    , mType(type)
57    , mDefinition(defn) {
58
59    }
60    inline const char * replicateString(const char * string, const length_t length) {
61        if (string) {
62            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
63            std::memcpy(allocated, string, length);
64            string = allocated;
65        }
66        return string;
67    }
68
69private:
70    const length_t      mNamespaceLength;
71    const char * const  mNamespace;
72    const length_t      mNameLength;
73    const char * const  mName;
74    Type                mType;
75    RE *                mDefinition;
76};
77
78inline std::string Name::getNamespace() const {
79    return std::string(mNamespace, mNamespaceLength);
80}
81
82inline bool Name::hasNamespace() const {
83    return (mNamespaceLength != 0);
84}
85
86inline std::string Name::getName() const {
87    return std::string(mName, mNameLength);
88}
89   
90inline Name::Type Name::getType() const {
91    return mType;
92}
93
94inline RE * Name::getDefinition() const {
95    return mDefinition;
96}
97
98inline void Name::setDefinition(RE * definition) {
99    assert (definition != this);
100    mDefinition = definition;
101}
102
103inline bool Name::operator < (const Name & other) const {
104    if (LLVM_LIKELY(mDefinition && other.mDefinition && llvm::isa<CC>(mDefinition) && llvm::isa<CC>(other.mDefinition))) {
105        return *llvm::cast<CC>(mDefinition) < *llvm::cast<CC>(other.mDefinition);
106    } else if (mNamespaceLength < other.mNamespaceLength) {
107        return true;
108    } else if (mNamespaceLength > other.mNamespaceLength) {
109        return false;
110    } else if (mNameLength < other.mNameLength) {
111        return true;
112    } else if (mNameLength > other.mNameLength) {
113        return false;
114    }
115    const auto diff = std::memcmp(mNamespace, other.mNamespace, mNamespaceLength);
116    if (diff < 0) {
117        return true;
118    } else if (diff > 0) {
119        return false;
120    }
121    return (std::memcmp(mName, other.mName, mNameLength) < 0);
122}
123
124inline bool Name::operator < (const CC & other) const {
125    if (mDefinition && llvm::isa<CC>(mDefinition)) {
126        return *llvm::cast<CC>(mDefinition) < other;
127    }
128    return false;
129}
130
131inline bool Name::operator > (const CC & other) const {
132    if (mDefinition && llvm::isa<CC>(mDefinition)) {
133        return other < *llvm::cast<CC>(mDefinition);
134    }
135    return true;
136}
137
138inline Name * makeName(const std::string & name, const Name::Type type) {
139    return new Name(nullptr, 0, name.c_str(), name.length(), type, nullptr);
140}
141
142inline Name * makeName(const std::string & property, const std::string & value, const Name::Type type) {
143    return new Name(property.c_str(), property.length(), value.c_str(), value.length(),  type, nullptr);
144}
145
146inline Name * makeName(const std::string & name, RE * cc) {
147    if (llvm::isa<Name>(cc)) {
148        return llvm::cast<Name>(cc);
149    }
150    else if (llvm::isa<CC>(cc)) {
151        Name::Type ccType = llvm::cast<CC>(cc)->max_codepoint() <= 0x7F ? Name::Type::Byte : Name::Type::Unicode;
152        return new Name(nullptr, 0, name.c_str(), name.length(), ccType, cc);
153    }
154    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
155}
156
157inline Name * makeName(CC * const cc) {
158    const bool ascii = cc->max_codepoint() <= 0x7F;
159    const std::string name = cc->canonicalName(ascii ? CC_type::ByteClass : CC_type::UnicodeClass);
160    return new Name(nullptr, 0, name.c_str(), name.length(), ascii ? Name::Type::Byte : Name::Type::Unicode, cc);
161}
162
163inline Name * makeCapture(const std::string & name, RE * captured) {
164    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Capture, captured);
165}
166   
167inline Name * makeReference(const std::string & name, RE * captureName) {
168    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Reference, captureName);
169}
170
171inline Name * makeZeroWidth(const std::string & name, RE * zerowidth = NULL) {
172    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::ZeroWidth, zerowidth);
173}
174}
175
176#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.