1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_UTILITIES_TEMPLATE_IDIOMS_HPP 26 #define SHARE_VM_UTILITIES_TEMPLATE_IDIOMS_HPP 27 28 template <typename Base, typename Derived> 29 struct IsBaseOfHost 30 { 31 operator Base*() const; 32 operator Derived*(); 33 }; 34 35 // Statically check if two types are related in a class hierarchy 36 template <typename Base, typename Derived> 37 struct is_base_of 38 { 39 typedef char yes[1]; 40 typedef char no[2]; 41 42 template <typename T> 43 static yes &check(Derived*, T); 44 static no &check(Base*, int); 45 46 static const bool value = sizeof(check(IsBaseOfHost<Base,Derived>(), int())) == sizeof(yes); 47 }; 48 49 // Statically check if two types are equal 50 template <typename T, typename U> 51 struct is_same 52 { 53 static const bool value = false; 54 }; 55 56 template <typename T> 57 struct is_same<T,T> 58 { 59 static const bool value = true; 60 }; 61 62 template <typename Base, typename Derived> 63 struct is_kind_of { 64 static const bool value = is_same<Base, Derived>::value || is_base_of<Base, Derived>::value; 65 }; 66 67 // Enable a template substitution only if a certain condition holds 68 template <bool, class T> 69 struct enable_if 70 {}; 71 72 template <class T> 73 struct enable_if<true, T> 74 { 75 typedef T type; 76 }; 77 78 // Like enable_if but infuse a dependency to a type not in the parameters to the template. 79 // This would normally make SFINAE fail, but with the infused dependency, all is fine. 80 template <bool value, class D, class T> 81 struct enable_if_depend: public enable_if<(sizeof(D) == -1 || value), T> 82 {}; 83 84 // Check for a certain typedef in a class 85 #define GENERATE_SFINAE_TYPEDEF_CHECK(name) \ 86 template <typename T> \ 87 struct has_typedef_##name { \ 88 typedef char yes[1]; \ 89 typedef char no[2]; \ 90 \ 91 template <typename C> \ 92 static yes& test(typename C::name*); \ 93 \ 94 template <typename> \ 95 static no& test(...); \ 96 \ 97 static const bool value = sizeof(test<T>(0)) == sizeof(yes); \ 98 } 99 100 // TODO: Currently generates compiler error when used on forward declarations 101 // Check for a certain member declaration 102 #define GENERATE_SFINAE_MEMBER_CHECK(name) \ 103 template<typename T> struct has_member_##name { \ 104 struct Fallback { int name ; }; \ 105 struct Derived: T, Fallback { }; \ 106 \ 107 template<typename C, C> struct Check; \ 108 \ 109 template<typename C> static char (&f(Check<int Fallback::*, &C::name>*))[1];\ 110 template<typename C> static char (&f(...))[2]; \ 111 \ 112 static bool const value = sizeof(f<Derived>(0)) == 2; \ 113 } 114 115 // Checks for certain overload of a member function 116 #define GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(function) \ 117 template<typename T, typename Signature> \ 118 struct has_member_function_##function { \ 119 typedef char yes[1]; \ 120 typedef char no [2]; \ 121 template <typename U, U> struct Check; \ 122 template <typename C> static yes &check(Check<Signature, &C::function> *); \ 123 template <typename > static no &check(...); \ 124 static bool const value = sizeof(check<T>(0)) == sizeof(yes); \ 125 } 126 127 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_oop_nv); 128 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_metadata_nv); 129 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_klass_nv); 130 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_class_loader_data_nv); 131 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_oop); 132 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_metadata); 133 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_klass); 134 GENERATE_SFINAE_MEMBER_FUNCTION_CHECK(do_class_loader_data); 135 136 #endif // SHARE_VM_UTILITIES_TEMPLATE_IDIOMS_HPP 137