• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef _PANDA_TYPE_SET_HPP__
17 #define _PANDA_TYPE_SET_HPP__
18 
19 #include "type_index.h"
20 #include "type_type.h"
21 
22 #include "runtime/include/mem/panda_string.h"
23 
24 namespace panda::verifier {
25 class TypeSystems;
26 
27 class TypeSet {
28 public:
29     TypeSet() = delete;
30 
31     template <typename... Types>
TypeSet(const Type & t,Types...types)32     explicit TypeSet(const Type &t, Types... types)
33         : kind_ {t.GetTypeSystemKind()}, threadnum_ {t.GetThreadNum()}, Numbers_ {}
34     {
35         if (sizeof...(types) == 0) {
36             Numbers_.Insert(t.Number());
37         } else {
38             std::array numbers_arr {t.Number(), types.Number()...};
39             Numbers_.Insert(numbers_arr.begin(), numbers_arr.end());
40         }
41     }
42 
43     explicit TypeSet(TypeSystemKind kind, ThreadNum threadnum, IntSet<TypeNum> &&numbers = {})
44         : kind_ {kind}, threadnum_ {threadnum}, Numbers_ {numbers} {};
45 
46     ~TypeSet() = default;
47 
Insert(const Type & t)48     void Insert(const Type &t)
49     {
50         ASSERT(t.GetTypeSystemKind() == kind_);
51         ASSERT(t.GetThreadNum() == threadnum_);
52         Numbers_.Insert(t.Number());
53     }
54 
55     TypeSet &operator|(const Type &t)
56     {
57         Insert(t);
58         return *this;
59     }
60 
Contains(const Type & t)61     bool Contains(const Type &t) const
62     {
63         return t.GetTypeSystemKind() == kind_ && t.GetThreadNum() == threadnum_ && Numbers_.Contains(t.Number());
64     }
65 
66     const Type &operator<<(const Type &st) const;
67 
68     const TypeSet &operator<<(const TypeSet &st) const;
69 
70     TypeSet operator&(const Type &rhs) const;
71 
72     TypeSet operator&(const TypeSet &rhs) const;
73 
Size()74     size_t Size() const
75     {
76         return Numbers_.Size();
77     }
78 
IsEmpty()79     bool IsEmpty() const
80     {
81         return Size() == 0;
82     }
83 
TheOnlyType()84     Type TheOnlyType() const
85     {
86         Index<TypeNum> the_only_number = Numbers_.TheOnlyElement();
87         if (the_only_number.IsValid()) {
88             return {kind_, threadnum_, *the_only_number};
89         }
90         return {};
91     }
92 
93     template <typename Handler>
ForAll(Handler && handler)94     bool ForAll(Handler &&handler) const
95     {
96         return Numbers_.ForAll([&](TypeNum num) { return handler(Type(kind_, threadnum_, num)); });
97     }
98 
99     template <typename Handler>
Exists(Handler && handler)100     bool Exists(Handler &&handler) const
101     {
102         return !ForAll([handler {std::move(handler)}](Type t) { return !handler(t); });
103     }
104 
105     template <typename TypeImageFunc>
Image(TypeImageFunc type_img_func)106     PandaString Image(TypeImageFunc type_img_func) const
107     {
108         PandaString result {"TypeSet{"};
109         bool first = true;
110         ForAll([&](const Type &type) {
111             if (first) {
112                 first = false;
113             } else {
114                 result += ", ";
115             }
116             result += type_img_func(type);
117             return true;
118         });
119         result += "}";
120         return result;
121     }
122 
123     bool operator==(const TypeSet &rhs) const
124     {
125         return kind_ == rhs.kind_ && threadnum_ == rhs.threadnum_ && Numbers_ == rhs.Numbers_;
126     }
127 
128     bool operator!=(const TypeSet &rhs) const
129     {
130         return !(*this == rhs);
131     }
132 
133 private:
134     TypeSystemKind kind_;
135     ThreadNum threadnum_;
136     IntSet<TypeNum> Numbers_;
137 };
138 }  // namespace panda::verifier
139 
140 #endif  // !_PANDA_TYPE_SET_HPP__
141