1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
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(FUSION_CATEGORY_OF_07202005_0308)
8 #define FUSION_CATEGORY_OF_07202005_0308
9 
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/fusion/support/detail/category_of.hpp>
12 #include <boost/fusion/support/tag_of.hpp>
13 #include <boost/type_traits/is_base_of.hpp>
14 
15 namespace boost { namespace fusion
16 {
17     // Special tags:
18     struct boost_tuple_tag; // boost::tuples::tuple tag
19     struct boost_array_tag; // boost::array tag
20     struct mpl_sequence_tag; // mpl sequence tag
21     struct std_pair_tag; // std::pair tag
22 
23     struct incrementable_traversal_tag {};
24 
25     struct single_pass_traversal_tag
26         : incrementable_traversal_tag {};
27 
28     struct forward_traversal_tag
29         : single_pass_traversal_tag {};
30 
31     struct bidirectional_traversal_tag
32         : forward_traversal_tag {};
33 
34     struct random_access_traversal_tag
35         : bidirectional_traversal_tag {};
36 
37     struct associative_tag {};
38 
39     struct unbounded_tag {};
40 
41     namespace extension
42     {
43         template<typename Tag>
44         struct category_of_impl
45         {
46             template<typename T>
47             struct apply : detail::fusion_category_of<T> {};
48         };
49 
50         template <>
51         struct category_of_impl<boost_tuple_tag>;
52 
53         template <>
54         struct category_of_impl<boost_array_tag>;
55 
56         template <>
57         struct category_of_impl<mpl_sequence_tag>;
58 
59         template <>
60         struct category_of_impl<std_pair_tag>;
61     }
62 
63     namespace traits
64     {
65         template <typename T>
66         struct category_of
67             : extension::category_of_impl<typename fusion::detail::tag_of<T>::type>::
68                 template apply<T>
69         {};
70 
71         template <typename T>
72         struct is_associative
73             : is_base_of<
74                 associative_tag
75               , typename category_of<T>::type>
76         {};
77 
78         template <typename T>
79         struct is_incrementable
80             : is_base_of<
81                 incrementable_traversal_tag
82               , typename category_of<T>::type>
83         {};
84 
85         template <typename T>
86         struct is_single_pass
87             : is_base_of<
88                 single_pass_traversal_tag
89               , typename category_of<T>::type>
90         {};
91 
92         template <typename T>
93         struct is_forward
94             : is_base_of<
95                 forward_traversal_tag
96               , typename category_of<T>::type>
97         {};
98 
99         template <typename T>
100         struct is_bidirectional
101             : is_base_of<
102                 bidirectional_traversal_tag
103               , typename category_of<T>::type>
104         {};
105 
106         template <typename T>
107         struct is_random_access
108             : is_base_of<
109                 random_access_traversal_tag
110               , typename category_of<T>::type>
111         {};
112 
113         template <typename T>
114         struct is_unbounded
115             : is_base_of<
116                 unbounded_tag
117               , typename category_of<T>::type>
118         {};
119     }
120 }}
121 
122 #endif
123