member_type.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // (C) Copyright Edward Diener 2011,2012,2013
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt).
  5. #if !defined(BOOST_TTI_MEMBER_TYPE_HPP)
  6. #define BOOST_TTI_MEMBER_TYPE_HPP
  7. #include <boost/config.hpp>
  8. #include <boost/mpl/eval_if.hpp>
  9. #include <boost/mpl/identity.hpp>
  10. #include <boost/mpl/not.hpp>
  11. #include <boost/type_traits/is_same.hpp>
  12. #include <boost/preprocessor/cat.hpp>
  13. #include <boost/tti/gen/member_type_gen.hpp>
  14. #include <boost/tti/gen/namespace_gen.hpp>
  15. #include <boost/tti/detail/dmem_type.hpp>
  16. #include <boost/tti/detail/dnotype.hpp>
  17. /*
  18. The succeeding comments in this file are in doxygen format.
  19. */
  20. /** \file
  21. */
  22. /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type.
  23. /**
  24. trait = the name of the metafunction within the tti namespace.
  25. name = the name of the inner type.
  26. generates a metafunction called "trait" where 'trait' is the macro parameter.
  27. template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype>
  28. struct trait
  29. {
  30. typedef unspecified type;
  31. typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type;
  32. };
  33. The metafunction types and return:
  34. BOOST_TTI_TP_T = the enclosing type.
  35. BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type.
  36. defaults to the internal boost::tti::detail::notype.
  37. returns = 'type' is the inner type of 'name' if the inner type exists
  38. within the enclosing type, else 'type' is a marker type.
  39. if the end-user does not specify a marker type then
  40. an internal boost::tti::detail::notype marker type is used.
  41. The metafunction also encapsulates the type of the marker type as
  42. a nested 'boost_tti_marker_type'.
  43. The purpose of this macro is to encapsulate the 'name' type as the typedef 'type'
  44. of a metafunction, but only if it exists within the enclosing type. This allows for
  45. an evaluation of inner type existence, without generating a compiler error,
  46. which can be used by other metafunctions in this library.
  47. */
  48. #define BOOST_TTI_TRAIT_MEMBER_TYPE(trait,name) \
  49. BOOST_TTI_DETAIL_TRAIT_HAS_TYPE_MEMBER_TYPE(trait,name) \
  50. BOOST_TTI_DETAIL_TRAIT_MEMBER_TYPE(trait,name) \
  51. template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype> \
  52. struct trait : \
  53. boost::mpl::eval_if \
  54. < \
  55. BOOST_PP_CAT(trait,_detail)<BOOST_TTI_TP_T>, \
  56. BOOST_PP_CAT(trait,_detail_member_type)<BOOST_TTI_TP_T>, \
  57. boost::mpl::identity<BOOST_TTI_TP_MARKER_TYPE> \
  58. > \
  59. { \
  60. typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; \
  61. }; \
  62. /**/
  63. /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type.
  64. /**
  65. name = the name of the inner type.
  66. generates a metafunction called "member_type_name" where 'name' is the macro parameter.
  67. template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype>
  68. struct member_type_name
  69. {
  70. typedef unspecified type;
  71. typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type;
  72. };
  73. The metafunction types and return:
  74. BOOST_TTI_TP_T = the enclosing type.
  75. BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type.
  76. defaults to the internal boost::tti::detail::notype.
  77. returns = 'type' is the inner type of 'name' if the inner type exists
  78. within the enclosing type, else 'type' is a marker type.
  79. if the end-user does not specify a marker type then
  80. an internal boost::tti::detail::notype marker type is used.
  81. The metafunction also encapsulates the type of the marker type as
  82. a nested 'boost_tti_marker_type'.
  83. The purpose of this macro is to encapsulate the 'name' type as the typedef 'type'
  84. of a metafunction, but only if it exists within the enclosing type. This allows for
  85. an evaluation of inner type existence, without generating a compiler error,
  86. which can be used by other metafunctions in this library.
  87. */
  88. #define BOOST_TTI_MEMBER_TYPE(name) \
  89. BOOST_TTI_TRAIT_MEMBER_TYPE \
  90. ( \
  91. BOOST_TTI_MEMBER_TYPE_GEN(name), \
  92. name \
  93. ) \
  94. /**/
  95. namespace boost
  96. {
  97. namespace tti
  98. {
  99. /// A metafunction which checks whether the member 'type' returned from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) is a valid type.
  100. /**
  101. template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype>
  102. struct valid_member_type
  103. {
  104. static const value = unspecified;
  105. typedef mpl::bool_<true-or-false> type;
  106. };
  107. The metafunction types and return:
  108. BOOST_TTI_TP_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ).
  109. BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type.
  110. defaults to the internal boost::tti::detail::notype.
  111. returns = 'value' is true if the type is valid, otherwise 'value' is false.
  112. A valid type means that the returned inner 'type' is not the marker type.
  113. */
  114. template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype>
  115. struct valid_member_type :
  116. boost::mpl::not_
  117. <
  118. boost::is_same<BOOST_TTI_TP_T,BOOST_TTI_TP_MARKER_TYPE>
  119. >
  120. {
  121. };
  122. /// A metafunction which checks whether the invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) hold a valid type.
  123. /**
  124. template<class TTI_METAFUNCTION>
  125. struct valid_member_metafunction
  126. {
  127. static const value = unspecified;
  128. typedef mpl::bool_<true-or-false> type;
  129. };
  130. The metafunction types and return:
  131. TTI_METAFUNCTION = The invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ).
  132. returns = 'value' is true if the nested type of the invoked metafunction is valid, otherwise 'value' is false.
  133. A valid type means that the invoked metafunction's inner 'type' is not the marker type.
  134. */
  135. template<class TTI_METAFUNCTION>
  136. struct valid_member_metafunction :
  137. boost::mpl::not_
  138. <
  139. boost::is_same<typename TTI_METAFUNCTION::type,typename TTI_METAFUNCTION::boost_tti_marker_type>
  140. >
  141. {
  142. };
  143. }
  144. }
  145. #endif // BOOST_TTI_MEMBER_TYPE_HPP