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