source: icGREP/icgrep-devel/icgrep/re/re_alt.h @ 4432

Last change on this file since 4432 was 4432, checked in by nmedfort, 5 years ago

Temporary check in.

File size: 2.2 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#ifndef ALT_H
8#define ALT_H
9
10#include "re_re.h"
11#include "re_cc.h"
12#include <queue>
13
14namespace re {
15
16class Alt : public Vector {
17public:
18    static inline bool classof(const RE * re) {
19        return re->getClassTypeId() == ClassTypeId::Alt;
20    }
21    static inline bool classof(const void *) {
22        return false;
23    }
24protected:
25    friend Alt * makeAlt();
26    template<typename iterator> friend RE * makeAlt(iterator, iterator);
27    Alt()
28    : Vector(ClassTypeId::Alt) {
29
30    }
31    Alt(iterator begin, iterator end)
32    : Vector(ClassTypeId::Alt, begin, end) {
33
34    }
35    void* operator new (std::size_t size) noexcept {
36        return mAllocator.allocate(size);
37    }
38private:
39    template<typename iterator>
40    void flatten(iterator begin, iterator end, std::queue<CC*> & ccQ) {
41        for (auto i = begin; i != end; ++i) {
42            if (Alt * alt = dyn_cast<Alt>(*i)) {
43                flatten(alt->begin(), alt->end(), ccQ);
44                continue;
45            }
46            else if (CC * cc = dyn_cast<CC>(*i)) {
47                ccQ.push(cc);
48                continue;
49            }
50            push_back(*i);
51        }
52    }
53};
54
55/**
56 * @brief makeAlt
57 *
58 * Build an Alt, flattening alternative subgroups, and combining character classes and
59 * move character classes towards the end of the list to ensure that all combinations are found.
60 *
61 * @param list
62 * @return simplified RE representing the Alt
63 */
64
65inline Alt * makeAlt() {
66    return new Alt();
67}
68
69template<typename iterator>
70RE * makeAlt(iterator begin, iterator end) {
71    Alt * alt = makeAlt();
72    std::queue<CC*> ccQ;
73    alt->flatten(begin, end, ccQ);
74    if (!ccQ.empty()) {
75        while (ccQ.size() > 1) {
76            CC * a = ccQ.front(); ccQ.pop();
77            CC * b = ccQ.front(); ccQ.pop();
78            ccQ.push(makeCC(a, b));
79        }
80        alt->push_back(ccQ.front());
81    }
82    if (alt->size() == 1) {
83        return alt->back();
84    }
85    return alt;
86}
87
88inline RE * makeAlt(RE::InitializerList list) {
89    return makeAlt(list.begin(), list.end());
90}
91
92}
93
94#endif // ALT_H
95
Note: See TracBrowser for help on using the repository browser.