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

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

First attempt at adding grapheme cluster mode to icgrep.

File size: 4.8 KB
RevLine 
[3917]1#ifndef RE_NAME_H
2#define RE_NAME_H
3
[4246]4#include <re/re_re.h>
[4335]5#include <re/re_cc.h>
[3917]6#include <string>
7
[4808]8namespace UCD {
9    class UnicodeSet;
10}
[4246]11
[4194]12namespace re {
13
14class Name : public RE {
[3917]15public:
[4194]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    }
[4516]22    using length_t = std::string::size_type;
[4194]23    enum class Type {
[4337]24        Byte
[4246]25        , Unicode
[4377]26        , UnicodeProperty
[4335]27        , Unknown
[4194]28    };
[4516]29    std::string getNamespace() const;
[4809]30    bool hasNamespace() const;
[4516]31    std::string getName() const;
[4182]32    Type getType() const;
[4808]33    RE * getDefinition() const;
[4819]34    bool operator<(const Name & other) const;
35    bool operator<(const CC & other) const;
[4823]36    bool operator>(const CC & other) const;
[4818]37    void setDefinition(RE * definition);
[4194]38    virtual ~Name() {}
39protected:
[4823]40    friend Name * makeName(const std::string & name, RE * cc);
41    friend Name * makeName(CC * const cc);
[4516]42    friend Name * makeName(const std::string &, const Type);
43    friend Name * makeName(const std::string &, const std::string &, const Type);
44    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, const Type type, RE * defn)
[4249]45    : RE(ClassTypeId::Name)
[4516]46    , mNamespaceLength(namespaceLength)
47    , mNamespace(replicateString(nameSpace, namespaceLength))
48    , mNameLength(nameLength)
49    , mName(replicateString(name, nameLength))
[4249]50    , mType(type)
[4818]51    , mDefinition(defn)
[4249]52    {
53
54    }
[4516]55    inline const char * replicateString(const char * string, const length_t length) {
56        if (string) {
57            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
58            std::memcpy(allocated, string, length);
59            string = allocated;
60        }
61        return string;
62    }
[4249]63
[3917]64private:
[4660]65    const length_t      mNamespaceLength;
66    const char * const  mNamespace;
67    const length_t      mNameLength;
68    const char * const  mName;
[4438]69    const Type          mType;
[4818]70    RE *                mDefinition;
[3917]71};
72
[4516]73inline std::string Name::getNamespace() const {
74    return std::string(mNamespace, mNamespaceLength);
[4377]75}
76
[4809]77inline bool Name::hasNamespace() const {
78    return (mNamespaceLength != 0);
79}
80
[4516]81inline std::string Name::getName() const {
82    return std::string(mName, mNameLength);
83}
[4380]84   
[4246]85inline Name::Type Name::getType() const {
86    return mType;
[4194]87}
88
[4336]89inline RE * Name::getDefinition() const {
[4818]90    return mDefinition;
[4194]91}
92
[4818]93inline void Name::setDefinition(RE * definition) {
94    assert (definition != this);
95    mDefinition = definition;
[4194]96}
97
[4819]98inline bool Name::operator < (const Name & other) const {
[4823]99    if (LLVM_LIKELY(mDefinition && other.mDefinition && isa<CC>(mDefinition) && isa<CC>(other.mDefinition))) {
[4819]100        return *cast<CC>(mDefinition) < *cast<CC>(other.mDefinition);
101    } else if (mNamespaceLength < other.mNamespaceLength) {
102        return true;
103    } else if (mNamespaceLength > other.mNamespaceLength) {
104        return false;
105    } else if (mNameLength < other.mNameLength) {
106        return true;
107    } else if (mNameLength > other.mNameLength) {
108        return false;
109    }
110    const auto diff = std::memcmp(mNamespace, other.mNamespace, mNamespaceLength);
111    if (diff < 0) {
112        return true;
113    } else if (diff > 0) {
114        return false;
115    }
116    return (std::memcmp(mName, other.mName, mNameLength) < 0);
117}
118
119inline bool Name::operator < (const CC & other) const {
120    if (mDefinition && isa<CC>(mDefinition)) {
121        return *cast<CC>(mDefinition) < other;
122    }
123    return false;
124}
125
[4823]126inline bool Name::operator > (const CC & other) const {
127    if (mDefinition && isa<CC>(mDefinition)) {
128        return other < *cast<CC>(mDefinition);
129    }
130    return true;
131}
132
[4660]133inline Name * makeName(const std::string & name, const Name::Type type) {
[4516]134    return new Name(nullptr, 0, name.c_str(), name.length(), type, nullptr);
[4194]135}
136
[4660]137inline Name * makeName(const std::string & property, const std::string & value, const Name::Type type) {
[4516]138    return new Name(property.c_str(), property.length(), value.c_str(), value.length(),  type, nullptr);
[4377]139}
140
[4516]141inline Name * makeName(const std::string & name, RE * cc) {
[4249]142    if (isa<Name>(cc)) {
143        return cast<Name>(cc);
144    }
[4335]145    else if (isa<CC>(cc)) {
[4337]146        Name::Type ccType = cast<CC>(cc)->max_codepoint() <= 0x7F ? Name::Type::Byte : Name::Type::Unicode;
[4516]147        return new Name(nullptr, 0, name.c_str(), name.length(), ccType, cc);
[4335]148    }
[4516]149    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
[4194]150}
151
[4823]152inline Name * makeName(CC * const cc) {
153    const bool ascii = cc->max_codepoint() <= 0x7F;
154    const std::string name = cc->canonicalName(ascii ? CC_type::ByteClass : CC_type::UnicodeClass);
155    return new Name(nullptr, 0, name.c_str(), name.length(), ascii ? Name::Type::Byte : Name::Type::Unicode, cc);
[4194]156}
157
[4823]158}
159
[3917]160#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.