1 /* 2 * Copyright (c) 2021 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_VERIFICATION_TYPE_TYPE_SET_H_ 17 #define PANDA_VERIFICATION_TYPE_TYPE_SET_H_ 18 19 #include "type_type.h" 20 21 #include "runtime/include/mem/panda_containers.h" 22 23 namespace panda::verifier { 24 class TypeSystems; 25 26 class TypeSet { 27 public: 28 TypeSet() = delete; 29 30 template <typename... Types> TypeSet(const Type & t,Types...types)31 explicit TypeSet(const Type &t, Types... types) : Kind_ {t.GetTypeSystemKind()} 32 { 33 Indices_.Insert(t.Index()); 34 if constexpr (sizeof...(types) > 0) { 35 (Insert(types), ...); 36 } 37 } 38 39 explicit TypeSet(TypeSystemKind kind, IntSet<TypeIdx> &&indices = {}) : Kind_ {kind}, Indices_ {indices} {}; 40 41 ~TypeSet() = default; 42 Insert(const Type & t)43 void Insert(const Type &t) 44 { 45 ASSERT(t.GetTypeSystemKind() == Kind_); 46 Indices_.Insert(t.Index()); 47 } 48 49 TypeSet &operator|(const Type &t) 50 { 51 Insert(t); 52 return *this; 53 } 54 Contains(const Type & t)55 bool Contains(const Type &t) const 56 { 57 return t.GetTypeSystemKind() == Kind_ && Indices_.Contains(t.Index()); 58 } 59 60 const Type &operator<<(const Type &st) const; 61 62 const TypeSet &operator<<(const TypeSet &st) const; 63 64 TypeSet operator&(const Type &rhs) const; 65 66 TypeSet operator&(const TypeSet &rhs) const; 67 Size()68 size_t Size() const 69 { 70 return Indices_.Size(); 71 } 72 IsEmpty()73 bool IsEmpty() const 74 { 75 return Size() == 0; 76 } 77 TheOnlyType()78 Type TheOnlyType() const 79 { 80 if (Size() == 1) { 81 return {Kind_, *(Indices_.begin())}; 82 } else { 83 return {}; 84 } 85 } 86 87 template <typename Handler> ForAll(Handler && handler)88 bool ForAll(Handler &&handler) const 89 { 90 for (TypeIdx index : Indices_) { 91 if (!handler(Type(Kind_, index))) { 92 return false; 93 } 94 } 95 return true; 96 } 97 98 template <typename Handler> Exists(Handler && handler)99 bool Exists(Handler &&handler) const 100 { 101 return !ForAll([handler {std::move(handler)}](Type t) { return !handler(t); }); 102 } 103 104 template <typename StrT, typename TypeImageFunc> Image(TypeImageFunc type_img_func)105 StrT Image(TypeImageFunc type_img_func) const 106 { 107 StrT result {"TypeSet{"}; 108 bool first = true; 109 ForAll([&](const Type &type) { 110 if (first) { 111 first = false; 112 } else { 113 result += ", "; 114 } 115 result += type_img_func(type); 116 return true; 117 }); 118 result += "}"; 119 return result; 120 } 121 122 bool operator==(const TypeSet &rhs) const 123 { 124 return Kind_ == rhs.Kind_ && Indices_ == rhs.Indices_; 125 } 126 127 bool operator!=(const TypeSet &rhs) const 128 { 129 return !(*this == rhs); 130 } 131 132 private: 133 TypeSystemKind Kind_; 134 IntSet<TypeIdx> Indices_; 135 }; 136 } // namespace panda::verifier 137 138 #endif // PANDA_VERIFICATION_TYPE_TYPE_SET_H_ 139