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