attribute_category.hpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
  8. #define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
  9. #include <boost/mpl/identity.hpp>
  10. #include <boost/mpl/logical.hpp>
  11. #include <boost/mpl/eval_if.hpp>
  12. #include <boost/fusion/include/is_sequence.hpp>
  13. #include <boost/fusion/support/category_of.hpp>
  14. #include <boost/spirit/home/x3/support/traits/is_variant.hpp>
  15. #include <boost/spirit/home/x3/support/traits/is_range.hpp>
  16. #include <boost/spirit/home/x3/support/traits/container_traits.hpp>
  17. #include <boost/spirit/home/x3/support/traits/optional_traits.hpp>
  18. namespace boost { namespace spirit { namespace x3
  19. {
  20. struct unused_type;
  21. }}}
  22. namespace boost { namespace spirit { namespace x3 { namespace traits
  23. {
  24. struct unused_attribute {};
  25. struct plain_attribute {};
  26. struct container_attribute {};
  27. struct tuple_attribute {};
  28. struct associative_attribute {};
  29. struct variant_attribute {};
  30. struct optional_attribute {};
  31. struct range_attribute {};
  32. template <typename T, typename Enable = void>
  33. struct attribute_category
  34. : mpl::identity<plain_attribute> {};
  35. template <>
  36. struct attribute_category<unused_type>
  37. : mpl::identity<unused_attribute> {};
  38. template <>
  39. struct attribute_category<unused_type const>
  40. : mpl::identity<unused_attribute> {};
  41. template <typename T>
  42. struct attribute_category< T
  43. , typename enable_if<
  44. typename mpl::eval_if<
  45. fusion::traits::is_sequence<T>
  46. , fusion::traits::is_associative<T>
  47. , mpl::false_
  48. >::type >::type >
  49. : mpl::identity<associative_attribute> {};
  50. template <typename T>
  51. struct attribute_category< T
  52. , typename enable_if<
  53. mpl::and_<
  54. fusion::traits::is_sequence<T>
  55. , mpl::not_<fusion::traits::is_associative<T> >
  56. > >::type >
  57. : mpl::identity<tuple_attribute> {};
  58. template <typename T>
  59. struct attribute_category<T,
  60. typename enable_if<traits::is_variant<T>>::type>
  61. : mpl::identity<variant_attribute> {};
  62. template <typename T>
  63. struct attribute_category<T,
  64. typename enable_if<traits::is_optional<T>>::type>
  65. : mpl::identity<optional_attribute> {};
  66. template <typename T>
  67. struct attribute_category<T,
  68. typename enable_if<traits::is_range<T>>::type>
  69. : mpl::identity<range_attribute> {};
  70. template <typename T>
  71. struct attribute_category< T
  72. , typename enable_if<
  73. mpl::and_<
  74. traits::is_container<T>
  75. , mpl::not_<fusion::traits::is_sequence<T> >
  76. , mpl::not_<traits::is_range<T> >
  77. > >::type >
  78. : mpl::identity<container_attribute> {};
  79. }}}}
  80. #endif