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

Last change on this file since 4823 was 4823, checked in by nmedfort, 4 years ago

Potential bug fix

File size: 5.0 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 <string>
7
8namespace pablo {
9    class PabloAST;
10}
11
12namespace UCD {
13    class UnicodeSet;
14}
15
16namespace re {
17
18class Name : public RE {
19public:
20    static inline bool classof(const RE * re) {
21        return re->getClassTypeId() == ClassTypeId::Name;
22    }
23    static inline bool classof(const void *) {
24        return false;
25    }
26    using length_t = std::string::size_type;
27    enum class Type {
28        Byte
29        , Unicode
30        , UnicodeProperty
31        , Unknown
32    };
33    std::string getNamespace() const;
34    bool hasNamespace() const;
35    std::string getName() const;
36    Type getType() const;
37    RE * getDefinition() const;
38    pablo::PabloAST * getCompiled() const {
39        return mCompiled;
40    }
41    void setCompiled(pablo::PabloAST * var) {
42        mCompiled = var;
43    }
44    bool operator<(const Name & other) const;
45    bool operator<(const CC & other) const;
46    bool operator>(const CC & other) const;
47    void setDefinition(RE * definition);
48    virtual ~Name() {}
49protected:
50    friend Name * makeName(const std::string & name, RE * cc);
51    friend Name * makeName(CC * const cc);
52    friend Name * makeName(const std::string &, const Type);
53    friend Name * makeName(const std::string &, const std::string &, const Type);
54    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, const Type type, RE * defn)
55    : RE(ClassTypeId::Name)
56    , mNamespaceLength(namespaceLength)
57    , mNamespace(replicateString(nameSpace, namespaceLength))
58    , mNameLength(nameLength)
59    , mName(replicateString(name, nameLength))
60    , mType(type)
61    , mDefinition(defn)
62    , mCompiled(nullptr)
63    {
64
65    }
66    inline const char * replicateString(const char * string, const length_t length) {
67        if (string) {
68            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
69            std::memcpy(allocated, string, length);
70            string = allocated;
71        }
72        return string;
73    }
74
75private:
76    const length_t      mNamespaceLength;
77    const char * const  mNamespace;
78    const length_t      mNameLength;
79    const char * const  mName;
80    const Type          mType;
81    RE *                mDefinition;
82    pablo::PabloAST *   mCompiled;
83};
84
85inline std::string Name::getNamespace() const {
86    return std::string(mNamespace, mNamespaceLength);
87}
88
89inline bool Name::hasNamespace() const {
90    return (mNamespaceLength != 0);
91}
92
93inline std::string Name::getName() const {
94    return std::string(mName, mNameLength);
95}
96   
97inline Name::Type Name::getType() const {
98    return mType;
99}
100
101inline RE * Name::getDefinition() const {
102    return mDefinition;
103}
104
105inline void Name::setDefinition(RE * definition) {
106    assert (definition != this);
107    mDefinition = definition;
108}
109
110inline bool Name::operator < (const Name & other) const {
111    if (LLVM_LIKELY(mDefinition && other.mDefinition && isa<CC>(mDefinition) && isa<CC>(other.mDefinition))) {
112        return *cast<CC>(mDefinition) < *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 && isa<CC>(mDefinition)) {
133        return *cast<CC>(mDefinition) < other;
134    }
135    return false;
136}
137
138inline bool Name::operator > (const CC & other) const {
139    if (mDefinition && isa<CC>(mDefinition)) {
140        return other < *cast<CC>(mDefinition);
141    }
142    return true;
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 & name, RE * cc) {
154    if (isa<Name>(cc)) {
155        return cast<Name>(cc);
156    }
157    else if (isa<CC>(cc)) {
158        Name::Type ccType = cast<CC>(cc)->max_codepoint() <= 0x7F ? Name::Type::Byte : Name::Type::Unicode;
159        return new Name(nullptr, 0, name.c_str(), name.length(), ccType, cc);
160    }
161    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
162}
163
164inline Name * makeName(CC * const cc) {
165    const bool ascii = cc->max_codepoint() <= 0x7F;
166    const std::string name = cc->canonicalName(ascii ? CC_type::ByteClass : CC_type::UnicodeClass);
167    return new Name(nullptr, 0, name.c_str(), name.length(), ascii ? Name::Type::Byte : Name::Type::Unicode, cc);
168}
169
170}
171
172#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.