Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/wabt/cast.h
1 /* 2 * Copyright 2017 WebAssembly Community Group participants 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WABT_CAST_H_ 18 #define WABT_CAST_H_ 19 20 #include <memory> 21 #include <type_traits> 22 23 #include "wabt/common.h" 24 25 // Modeled after LLVM's dynamic casts: 26 // http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates 27 // 28 // Use isa<T>(foo) to check whether foo is a T*: 29 // 30 // if (isa<Minivan>(car)) { 31 // ... 32 // } 33 // 34 // Use cast<T>(foo) when you know that foo is a T* -- it will assert that the 35 // type matches: 36 // 37 // switch (car.type) { 38 // case CarType::Minivan: { 39 // auto minivan = cast<Minivan>(car); 40 // ... 41 // } 42 // } 43 // 44 // Use dyn_cast<T>(foo) as a combination if isa and cast, it will return 45 // nullptr if the type doesn't match: 46 // 47 // if (auto minivan = dyn_cast<Minivan>(car)) { 48 // ... 49 // } 50 // 51 // 52 // To use these classes in a type hierarchy, you must implement classof: 53 // 54 // enum CarType { Minivan, ... }; 55 // struct Car { CarType type; ... }; 56 // struct Minivan : Car { 57 // static bool classof(const Car* car) { return car->type == Minivan; } 58 // ... 59 // }; 60 // 61 62 namespace wabt { 63 64 template <typename Derived, typename Base> 65 bool isa(const Base* base) { 66 WABT_STATIC_ASSERT((std::is_base_of<Base, Derived>::value)); 67 return Derived::classof(base); 68 } 69 70 template <typename Derived, typename Base> 71 const Derived* cast(const Base* base) { 72 assert(isa<Derived>(base)); 73 return static_cast<const Derived*>(base); 74 }; 75 76 template <typename Derived, typename Base> 77 Derived* cast(Base* base) { 78 assert(isa<Derived>(base)); 79 return static_cast<Derived*>(base); 80 }; 81 82 template <typename Derived, typename Base> 83 const Derived* dyn_cast(const Base* base) { 84 return isa<Derived>(base) ? static_cast<const Derived*>(base) : nullptr; 85 }; 86 87 template <typename Derived, typename Base> 88 Derived* dyn_cast(Base* base) { 89 return isa<Derived>(base) ? static_cast<Derived*>(base) : nullptr; 90 }; 91 92 // Cast functionality for unique_ptr. isa and dyn_cast are not included because 93 // they won't always pass ownership back to the caller. 94 95 template <typename Derived, typename Base> 96 std::unique_ptr<const Derived> cast(std::unique_ptr<const Base>&& base) { 97 assert(isa<Derived>(base.get())); 98 return std::unique_ptr<Derived>(static_cast<const Derived*>(base.release())); 99 }; 100 101 template <typename Derived, typename Base> 102 std::unique_ptr<Derived> cast(std::unique_ptr<Base>&& base) { 103 assert(isa<Derived>(base.get())); 104 return std::unique_ptr<Derived>(static_cast<Derived*>(base.release())); 105 }; 106 107 } // namespace wabt 108 109 #endif // WABT_CAST_H_