dunion.hpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // (C) Copyright Edward Diener 2019
  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_DETAIL_UNION_HPP)
  6. #define BOOST_TTI_DETAIL_UNION_HPP
  7. #include <boost/mpl/and.hpp>
  8. #include <boost/mpl/apply.hpp>
  9. #include <boost/mpl/bool.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/mpl/has_xxx.hpp>
  12. #include <boost/preprocessor/cat.hpp>
  13. #include <boost/tti/detail/ddeftype.hpp>
  14. #include <boost/tti/detail/dlambda.hpp>
  15. #include <boost/tti/detail/denclosing_type.hpp>
  16. #include <boost/tti/gen/namespace_gen.hpp>
  17. #include <boost/type_traits/is_union.hpp>
  18. #define BOOST_TTI_DETAIL_TRAIT_INVOKE_HAS_UNION(trait,name) \
  19. template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_MFC> \
  20. struct BOOST_PP_CAT(trait,_detail_union_invoke) \
  21. { \
  22. BOOST_MPL_ASSERT((BOOST_TTI_NAMESPACE::detail::is_lambda_expression<BOOST_TTI_DETAIL_TP_MFC>)); \
  23. typedef typename boost::mpl::apply<BOOST_TTI_DETAIL_TP_MFC,typename BOOST_TTI_DETAIL_TP_T::name>::type type; \
  24. }; \
  25. /**/
  26. #define BOOST_TTI_DETAIL_TRAIT_HAS_UNION_OP_CHOOSE(trait,name) \
  27. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(trait,_detail_union_mpl), name, false) \
  28. BOOST_TTI_DETAIL_TRAIT_INVOKE_HAS_UNION(trait,name) \
  29. template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_U,class BOOST_TTI_DETAIL_TP_B> \
  30. struct BOOST_PP_CAT(trait,_detail_union_op_choose) : \
  31. boost::mpl::and_ \
  32. < \
  33. boost::is_union<typename BOOST_TTI_DETAIL_TP_T::name>, \
  34. BOOST_PP_CAT(trait,_detail_union_invoke)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_U> \
  35. > \
  36. { \
  37. }; \
  38. \
  39. template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_U> \
  40. struct BOOST_PP_CAT(trait,_detail_union_op_choose)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_U,boost::mpl::false_::type> : \
  41. boost::mpl::false_ \
  42. { \
  43. }; \
  44. \
  45. template<class BOOST_TTI_DETAIL_TP_T> \
  46. struct BOOST_PP_CAT(trait,_detail_union_op_choose)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_NAMESPACE::detail::deftype,boost::mpl::true_::type> : \
  47. boost::is_union<typename BOOST_TTI_DETAIL_TP_T::name> \
  48. { \
  49. }; \
  50. /**/
  51. #define BOOST_TTI_DETAIL_TRAIT_HAS_UNION_OP(trait,name) \
  52. BOOST_TTI_DETAIL_TRAIT_HAS_UNION_OP_CHOOSE(trait,name) \
  53. template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_U> \
  54. struct BOOST_PP_CAT(trait,_detail_union_op) : \
  55. BOOST_PP_CAT(trait,_detail_union_op_choose) \
  56. < \
  57. BOOST_TTI_DETAIL_TP_T, \
  58. BOOST_TTI_DETAIL_TP_U, \
  59. typename BOOST_PP_CAT(trait,_detail_union_mpl)<BOOST_TTI_DETAIL_TP_T>::type \
  60. > \
  61. { \
  62. }; \
  63. /**/
  64. #define BOOST_TTI_DETAIL_TRAIT_HAS_UNION(trait,name) \
  65. BOOST_TTI_DETAIL_TRAIT_HAS_UNION_OP(trait,name) \
  66. template<class BOOST_TTI_DETAIL_TP_T,class BOOST_TTI_DETAIL_TP_U> \
  67. struct BOOST_PP_CAT(trait,_detail_union) : \
  68. boost::mpl::eval_if \
  69. < \
  70. BOOST_TTI_NAMESPACE::detail::enclosing_type<BOOST_TTI_DETAIL_TP_T>, \
  71. BOOST_PP_CAT(trait,_detail_union_op)<BOOST_TTI_DETAIL_TP_T,BOOST_TTI_DETAIL_TP_U>, \
  72. boost::mpl::false_ \
  73. > \
  74. { \
  75. }; \
  76. /**/
  77. #endif // BOOST_TTI_DETAIL_UNION_HPP