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_VERIFIER_UTIL_INDEX_HPP_ 17 #define PANDA_VERIFIER_UTIL_INDEX_HPP_ 18 19 #include "libpandabase/macros.h" 20 #include "verification/util/hash.h" 21 22 #include <limits> 23 24 namespace panda::verifier { 25 // similar to std::optional, but much more effective for numeric types 26 // when not all range of values is required and some value may be used 27 // as dedicated invalid value 28 template <typename Int, const Int INVALID = std::numeric_limits<Int>::max()> 29 class Index { 30 public: Index()31 Index() : Value_ {INVALID} {} Index(Int val)32 Index(Int val) : Value_ {val} 33 { 34 ASSERT(IsValid()); 35 } 36 Index &operator=(Int val) 37 { 38 Value_ = val; 39 ASSERT(IsValid()); 40 return *this; 41 } 42 Index(const Index &) = default; Index(Index && idx)43 Index(Index &&idx) : Value_ {idx.Value_} 44 { 45 idx.Invalidate(); 46 } 47 Index &operator=(const Index &) = default; 48 Index &operator=(Index &&idx) 49 { 50 Value_ = idx.Value_; 51 idx.Invalidate(); 52 return *this; 53 } 54 ~Index() = default; 55 56 bool operator==(const Index &other) const 57 { 58 return Value_ == other.Value_; 59 }; 60 bool operator!=(const Index &other) const 61 { 62 return !(*this == other); 63 }; 64 Invalidate()65 void Invalidate() 66 { 67 Value_ = INVALID; 68 } 69 IsValid()70 bool IsValid() const 71 { 72 return Value_ != INVALID; 73 } 74 75 // for contextual conversion in if/while/etc. 76 explicit operator bool() const 77 { 78 return IsValid(); 79 } 80 Int()81 operator Int() const 82 { 83 ASSERT(IsValid()); 84 return Value_; 85 } 86 87 Int operator*() const 88 { 89 ASSERT(IsValid()); 90 return Value_; 91 } 92 93 template <typename T> T()94 explicit operator T() const 95 { 96 ASSERT(IsValid()); 97 // todo: check that T is capable of holding valid range of value 98 return static_cast<T>(Value_); 99 } 100 101 private: 102 Int Value_; 103 template <typename T> 104 friend struct std::hash; 105 }; 106 } // namespace panda::verifier 107 108 namespace std { 109 template <typename Int, const Int I> 110 struct hash<panda::verifier::Index<Int, I>> { 111 size_t operator()(const panda::verifier::Index<Int, I> &i) const noexcept 112 { 113 return panda::verifier::StdHash(i.Value_); 114 } 115 }; 116 } // namespace std 117 118 #endif // !PANDA_VERIFIER_UTIL_INDEX_HPP_ 119