00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __TYPE_MEMBER_HH
00018 # define __TYPE_MEMBER_HH
00019
00020 namespace catsfoot {
00022 struct undefined_member_type {};
00023 }
00024
00032 # define DEF_TYPE_MEMBER_PREDICATE(X...) \
00033 namespace details { \
00034 template <typename T> \
00035 std::false_type has_member_##X##_helper \
00036 (catsfoot::details::try_second, const T&) { \
00037 static_assert(catsfoot::details::always_false<T>::value, \
00038 "Cannot use this function"); \
00039 return 0; \
00040 } \
00041 template <typename T, \
00042 typename = typename T::X> \
00043 std::true_type has_member_##X##_helper \
00044 (catsfoot::details::try_first, const T&) { \
00045 static_assert(catsfoot::details::always_false<T>::value, \
00046 "Cannot use this function"); \
00047 return 0; \
00048 } \
00049 template <typename T> \
00050 struct has_member_##X##_real_map { \
00051 typedef typename T::X member_type; \
00052 }; \
00053 template <typename> \
00054 struct has_member_##X##_bad_map { \
00055 typedef catsfoot::undefined_member_type member_type; \
00056 }; \
00057 } \
00058 template <typename T> \
00059 struct has_member_##X: \
00060 public catsfoot::identity \
00061 <decltype(details:: \
00062 has_member_##X##_helper \
00063 (catsfoot::details::try_first(), std::declval<T>()))> \
00064 ::type { \
00065 typedef typename catsfoot::identity \
00066 <decltype(details:: \
00067 has_member_##X##_helper \
00068 (catsfoot::details::try_first(), std::declval<T>()))> \
00069 ::type \
00070 super; \
00071 typedef typename \
00072 std::conditional<super::value, \
00073 details::has_member_##X##_real_map<T>, \
00074 details::has_member_##X##_bad_map<T> > \
00075 ::type::member_type member_type; \
00076 }; \
00077 template <> \
00078 struct has_member_##X<void>: \
00079 public std::false_type { \
00080 typedef ::catsfoot::undefined_member_type member_type; \
00081 };
00082
00083 #endif