type_inspection.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2008 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 00010 #ifndef ADOBE_TYPE_INSPECTION_HPP 00011 #define ADOBE_TYPE_INSPECTION_HPP 00012 00013 00014 00015 namespace adobe 00016 { 00017 00018 00019 namespace detail 00020 { 00021 struct yes_struct {char a;}; 00022 struct no_struct { yes_struct a[2];}; 00023 } 00024 00037 #define ADOBE_HAS_TYPE_IMPL(TypeInQuestion) \ 00038 template< \ 00039 typename C##TypeInQuestion> \ 00040 struct has_type##TypeInQuestion \ 00041 { \ 00042 template <typename T##TypeInQuestion> \ 00043 static adobe::detail::yes_struct SFINAE(typename T##TypeInQuestion::TypeInQuestion*); \ 00044 template <typename> \ 00045 static adobe::detail::no_struct SFINAE(...); \ 00046 static const bool value = sizeof(SFINAE<C##TypeInQuestion>(0)) == sizeof(adobe::detail::yes_struct); \ 00047 } 00048 00065 #define ADOBE_HAS_TYPE(C, TypeInQuestion) \ 00066 has_type##TypeInQuestion<C>::value 00067 00068 00074 // one of the most important types to look for is 'type', so let's just implement that one here 00075 template <typename T> 00076 struct has_type_type 00077 { 00078 ADOBE_HAS_TYPE_IMPL(type); 00079 00080 static const bool value = ADOBE_HAS_TYPE(T, type); 00081 }; 00082 00083 template <typename T, typename Default> 00084 struct type_or_default 00085 { 00086 template <bool condition, typename IFtype, typename ELSEtype> 00087 struct if_has_type 00088 { 00089 typedef typename IFtype::type type; 00090 }; 00091 template <typename IFtype, typename ELSEtype> 00092 struct if_has_type<false, IFtype, ELSEtype> 00093 { 00094 typedef ELSEtype type; 00095 }; 00096 typedef typename if_has_type<has_type_type<T>::value, T, Default>::type type; 00097 }; 00098 00099 00116 #if _MSC_VER <= 1400 00117 #define ADOBE_HAS_MEMBER_IMPL(Member) \ 00118 template <class Class> \ 00119 struct has_member##Member \ 00120 { \ 00121 __if_exists(Class::Member) \ 00122 { \ 00123 static const bool value = true; \ 00124 } \ 00125 __if_not_exists(Class::Member) \ 00126 { \ 00127 static const bool value = false; \ 00128 } \ 00129 } 00130 #else 00131 00132 namespace detail 00133 { 00134 template<size_t> 00135 struct member_test_helper 00136 { 00137 }; 00138 } 00139 00140 #define ADOBE_HAS_MEMBER_IMPL(MemberInQuestion) \ 00141 template <class Class> \ 00142 struct has_member##MemberInQuestion \ 00143 { \ 00144 template <class T##MemberInQuestion> \ 00145 static adobe::detail::yes_struct SFINAE( adobe::detail::member_test_helper<sizeof(&T##MemberInQuestion::MemberInQuestion)> * ); \ 00146 template<class> \ 00147 static adobe::detail::no_struct SFINAE(...); \ 00148 static const bool value = sizeof(SFINAE<Class>(0)) == sizeof(adobe::detail::yes_struct); \ 00149 } 00150 #endif 00151 00168 #define ADOBE_HAS_MEMBER(C, MemberInQuestion) \ 00169 has_member##MemberInQuestion<C>::value 00170 00171 00184 #define ADOBE_HAS_TEMPLATE1_IMPL(TemplateInQuestion) \ 00185 template< \ 00186 typename C##TemplateInQuestion> \ 00187 struct has_template1##TemplateInQuestion \ 00188 { \ 00189 template <typename T##TemplateInQuestion> \ 00190 static adobe::detail::yes_struct SFINAE(typename T##TemplateInQuestion::template TemplateInQuestion<int>*); \ 00191 template <typename> \ 00192 static adobe::detail::no_struct SFINAE(...); \ 00193 static const bool value = sizeof(SFINAE<C##TemplateInQuestion>(0)) == sizeof(adobe::detail::yes_struct); \ 00194 } 00195 00217 #define ADOBE_HAS_TEMPLATE1(C, TemplateInQuestion) \ 00218 has_template1##TemplateInQuestion<C>::value 00219 00220 00222 // 2 Arg case 00223 // 00224 #define ADOBE_HAS_TEMPLATE2_IMPL(TemplateInQuestion) \ 00225 template< \ 00226 typename C##TemplateInQuestion> \ 00227 struct has_template2##TemplateInQuestion \ 00228 { \ 00229 template <typename T##TemplateInQuestion> \ 00230 static adobe::detail::yes_struct SFINAE(typename T##TemplateInQuestion::template TemplateInQuestion<int, int>*); \ 00231 template <typename> \ 00232 static adobe::detail::no_struct SFINAE(...); \ 00233 static const bool value = sizeof(SFINAE<C##TemplateInQuestion>(0)) == sizeof(adobe::detail::yes_struct); \ 00234 } 00235 00236 #define ADOBE_HAS_TEMPLATE2(C, TemplateInQuestion) \ 00237 has_template2##TemplateInQuestion<C>::value 00238 00239 #define ADOBE_HAS_TEMPLATE3_IMPL(TemplateInQuestion) \ 00240 template< \ 00241 typename C##TemplateInQuestion> \ 00242 struct has_template3##TemplateInQuestion \ 00243 { \ 00244 template <typename T##TemplateInQuestion> \ 00245 static adobe::detail::yes_struct SFINAE(typename T##TemplateInQuestion::template TemplateInQuestion<int, int, int>*); \ 00246 template <typename> \ 00247 static adobe::detail::no_struct SFINAE(...); \ 00248 static const bool value = sizeof(SFINAE<C##TemplateInQuestion>(0)) == sizeof(adobe::detail::yes_struct); \ 00249 } 00250 00251 #define ADOBE_HAS_TEMPLATE3(C, TemplateInQuestion) \ 00252 has_template3##TemplateInQuestion<C>::value 00253 00254 00255 } // namespace 00256 00257 #endif // include guard 00258 |