1 /* 2 * Copyright 2014 Google Inc. All rights reserved. 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 FRUIT_TYPE_INFO_H 18 #define FRUIT_TYPE_INFO_H 19 20 #include <fruit/impl/meta/vector.h> 21 #include <fruit/impl/util/demangle_type_name.h> 22 #include <typeinfo> 23 24 #include <vector> 25 26 namespace fruit { 27 namespace impl { 28 29 // Similar to std::type_index, but with a constexpr constructor and also storing the type size and alignment. 30 // Also guaranteed to be aligned, to allow storing a TypeInfo and 1 bit together in the size of a void*. 31 struct alignas(1) alignas(void*) TypeInfo { 32 33 struct ConcreteTypeInfo { 34 // These fields are allowed to have dummy values for abstract types. 35 std::size_t type_size; 36 std::size_t type_alignment; 37 bool is_trivially_destructible; 38 39 #if FRUIT_EXTRA_DEBUG 40 bool is_abstract; 41 #endif 42 }; 43 44 // This should only be used if RTTI is disabled. Use the other constructor if possible. 45 explicit constexpr TypeInfo(ConcreteTypeInfo concrete_type_info); 46 47 constexpr TypeInfo(const std::type_info& info, ConcreteTypeInfo concrete_type_info); 48 49 std::string name() const; 50 51 size_t size() const; 52 53 size_t alignment() const; 54 55 bool isTriviallyDestructible() const; 56 57 private: 58 // The std::type_info struct associated with the type, or nullptr if RTTI is disabled. 59 // This is only used for the type name. 60 const std::type_info* info; 61 ConcreteTypeInfo concrete_type_info; 62 }; 63 64 struct TypeId { 65 const TypeInfo* type_info; 66 67 explicit operator std::string() const; 68 69 bool operator==(TypeId x) const; 70 bool operator!=(TypeId x) const; 71 bool operator<(TypeId x) const; 72 }; 73 74 // Returns the TypeId for the type T. 75 // Multiple invocations for the same type return the same value. 76 // This has special support for types of the form Annotated<SomeAnnotation, SomeType>, it reports 77 // data for SomeType (except the name, that is "Annotated<SomeAnnotation, SomeType>"). 78 template <typename T> 79 TypeId getTypeId(); 80 81 // A convenience function that returns an std::vector of TypeId values for the given meta-vector of types. 82 template <typename V> 83 std::vector<TypeId> getTypeIdsForList(); 84 85 } // namespace impl 86 } // namespace fruit 87 88 #if FRUIT_EXTRA_DEBUG 89 90 #include <ostream> 91 92 namespace fruit { 93 namespace impl { 94 95 inline std::ostream& operator<<(std::ostream& os, TypeId type); 96 97 } // namespace impl 98 } // namespace fruit 99 100 #endif // FRUIT_EXTRA_DEBUG 101 102 namespace std { 103 104 template <> 105 struct hash<fruit::impl::TypeId> { 106 std::size_t operator()(fruit::impl::TypeId type) const; 107 }; 108 109 } // namespace std 110 111 #include <fruit/impl/util/type_info.defn.h> 112 113 #endif // FRUIT_TYPE_INFO_H 114