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