1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 http://spirit.sourceforge.net/
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
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>
21 namespace boost { namespace spirit { namespace x3
26 namespace boost { namespace spirit { namespace x3 { namespace traits
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 {};
37 template <typename T, typename Enable = void>
38 struct attribute_category
39 : mpl::identity<plain_attribute> {};
42 struct attribute_category<unused_type>
43 : mpl::identity<unused_attribute> {};
46 struct attribute_category<unused_type const>
47 : mpl::identity<unused_attribute> {};
50 struct attribute_category< T
52 typename mpl::eval_if<
53 fusion::traits::is_sequence<T>
54 , fusion::traits::is_associative<T>
57 : mpl::identity<associative_attribute> {};
60 struct attribute_category< T
63 fusion::traits::is_sequence<T>
64 , mpl::not_<fusion::traits::is_associative<T> >
66 : mpl::identity<tuple_attribute> {};
69 struct attribute_category<T,
70 typename enable_if<traits::is_variant<T>>::type>
71 : mpl::identity<variant_attribute> {};
74 struct attribute_category<T,
75 typename enable_if<traits::is_optional<T>>::type>
76 : mpl::identity<optional_attribute> {};
79 struct attribute_category<T,
80 typename enable_if<traits::is_range<T>>::type>
81 : mpl::identity<range_attribute> {};
84 struct attribute_category< T
87 traits::is_container<T>
88 , mpl::not_<fusion::traits::is_sequence<T> >
89 , mpl::not_<traits::is_range<T> >
91 : mpl::identity<container_attribute> {};