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_UTIL_REF_WRAPPER_H_ 17 #define PANDA_VERIFICATION_UTIL_REF_WRAPPER_H_ 18 19 #include <functional> 20 #include <type_traits> 21 22 #include "invalid_ref.h" 23 24 #include "macros.h" 25 26 namespace panda::verifier { 27 28 template <typename T> 29 class Ref : public std::reference_wrapper<T> { 30 using Base = std::reference_wrapper<T>; 31 32 public: 33 using type = T; Ref()34 Ref() : Base(Invalid<T>()) {} 35 Ref(const Ref &) = default; 36 Ref &operator=(const Ref &) = default; Ref(const std::reference_wrapper<T> & ref)37 Ref(const std::reference_wrapper<T> &ref) : Base(ref) {} 38 Ref &operator=(const std::reference_wrapper<T> &ref) 39 { 40 Base::operator=(ref); 41 return *this; 42 } 43 ~Ref() = default; get()44 T &get() const noexcept 45 { 46 T &result = Base::get(); 47 ASSERT(Valid(result)); 48 return result; 49 } 50 operator T &() const noexcept 51 { 52 return get(); 53 } 54 template <typename... Args> operator()55 std::invoke_result_t<T &, Args...> operator()(Args &&... args) const 56 { 57 #ifndef NDEBUG 58 T &result = Base::get(); 59 ASSERT(Valid(result)); 60 #endif // NDEBUG 61 62 return Base::operator()(std::forward<Args>(args)...); 63 } 64 }; 65 66 } // namespace panda::verifier 67 68 #endif // PANDA_VERIFICATION_UTIL_REF_WRAPPER_H_ 69