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

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

More memory leak fixes. All known leaks accounted for.

File size: 2.1 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    }
35private:
36    template<typename iterator>
37    void flatten(iterator begin, iterator end, std::queue<CC*> & ccQ) {
38        for (auto i = begin; i != end; ++i) {
39            if (Alt * alt = dyn_cast<Alt>(*i)) {
40                flatten(alt->begin(), alt->end(), ccQ);
41                continue;
42            }
43            else if (CC * cc = dyn_cast<CC>(*i)) {
44                ccQ.push(cc);
45                continue;
46            }
47            push_back(*i);
48        }
49    }
50};
51
52/**
53 * @brief makeAlt
54 *
55 * Build an Alt, flattening alternative subgroups, and combining character classes and
56 * move character classes towards the end of the list to ensure that all combinations are found.
57 *
58 * @param list
59 * @return simplified RE representing the Alt
60 */
61
62inline Alt * makeAlt() {
63    return new Alt();
64}
65
66template<typename iterator>
67RE * makeAlt(iterator begin, iterator end) {
68    Alt * alt = makeAlt();
69    std::queue<CC*> ccQ;
70    alt->flatten(begin, end, ccQ);
71    if (!ccQ.empty()) {
72        while (ccQ.size() > 1) {
73            CC * a = ccQ.front(); ccQ.pop();
74            CC * b = ccQ.front(); ccQ.pop();
75            ccQ.push(makeCC(a, b));
76        }
77        alt->push_back(ccQ.front());
78    }
79    if (alt->size() == 1) {
80        return alt->back();
81    }
82    return alt;
83}
84
85inline RE * makeAlt(RE::InitializerList list) {
86    return makeAlt(list.begin(), list.end());
87}
88
89}
90
91#endif // ALT_H
92
Note: See TracBrowser for help on using the repository browser.