1 
2 // (C) Copyright Tobias Schwinger
3 //
4 // Use modification and distribution are subject to the boost Software License,
5 // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
6 
7 //------------------------------------------------------------------------------
8 
9 #ifndef BOOST_FT_DETAIL_TAGS_HPP_INCLUDED
10 #define BOOST_FT_DETAIL_TAGS_HPP_INCLUDED
11 
12 #include <cstddef>
13 
14 #include <boost/type_traits/integral_constant.hpp>
15 #include <boost/type_traits/is_same.hpp>
16 #include <boost/mpl/bitxor.hpp>
17 
18 
19 namespace boost { namespace function_types {
20 
21 namespace detail
22 {
23   typedef long bits_t;
24 
25   template<bits_t Value> struct constant
26     : boost::integral_constant<bits_t,Value>
27   { };
28 
29   template<bits_t Bits, bits_t Mask> struct property_tag
30   {
31     typedef constant<Bits> bits;
32     typedef constant<Mask> mask;
33   };
34 
35   template<typename T> struct bits : T::bits { };
36   template<typename T> struct mask : T::mask { };
37 
38   // forward declaration, defined in pp_tags
39   template<bits_t Bits, bits_t CCID> struct encode_bits_impl;
40 
41   // forward declaration, defined in pp_tags
42   template<bits_t LHS_bits, bits_t LHS_mask,
43            bits_t RHS_bits, bits_t RHS_mask>
44   struct tag_ice;
45 
46   // forward declaration, defined in retag_default_cc
47   template<class Tag, class RegTag = Tag> struct retag_default_cc;
48 
49   template<bits_t Bits, bits_t CCID> struct encode_bits
50     : constant<
51         ::boost::function_types::detail::encode_bits_impl<Bits,CCID>::value
52       >
53   { };
54 
55   template<class LHS, class RHS> struct compound_tag
56   {
57     typedef constant<
58       ::boost::function_types::detail::tag_ice
59         < ::boost::function_types::detail::bits<LHS>::value
60         , ::boost::function_types::detail::mask<LHS>::value
61         , ::boost::function_types::detail::bits<RHS>::value
62         , ::boost::function_types::detail::mask<RHS>::value
63         >::combined_bits
64     > bits;
65 
66     typedef constant<
67       ::boost::function_types::detail::tag_ice
68         < ::boost::function_types::detail::bits<LHS>::value
69         , ::boost::function_types::detail::mask<LHS>::value
70         , ::boost::function_types::detail::bits<RHS>::value
71         , ::boost::function_types::detail::mask<RHS>::value
72         >::combined_mask
73     > mask;
74   };
75 
76   template <class Base, class PropOld, class PropNew>
77   struct changed_tag
78     : Base
79   {
80     typedef mpl::bitxor_
81         <typename Base::bits, typename PropOld::bits, typename PropNew::bits>
82     bits;
83   };
84 
85   template<class Tag, class QueryTag> struct represents_impl
86     : boost::integral_constant<bool,
87         ::boost::function_types::detail::tag_ice
88           < ::boost::function_types::detail::bits<Tag>::value
89           , ::boost::function_types::detail::mask<Tag>::value
90           , ::boost::function_types::detail::bits<QueryTag>::value
91           , ::boost::function_types::detail::mask<QueryTag>::value
92           >::match
93       >
94   { };
95 
96 } // namespace detail
97 
98 typedef detail::property_tag<0,0> null_tag;
99 
100 template<class Tag1, class Tag2, class Tag3 = null_tag, class Tag4 = null_tag>
101 struct tag
102   : detail::compound_tag< detail::compound_tag<Tag1,Tag2>,
103         detail::compound_tag<Tag3,Tag4> >
104 { };
105 
106 template<class Tag1, class Tag2, class Tag3> struct tag<Tag1,Tag2,Tag3,null_tag>
107   : detail::compound_tag<detail::compound_tag<Tag1,Tag2>,Tag3>
108 { };
109 template<class Tag1, class Tag2> struct tag<Tag1,Tag2,null_tag,null_tag>
110   : detail::compound_tag<Tag1,Tag2>
111 { };
112 template<class Tag1> struct tag<Tag1,null_tag,null_tag,null_tag>
113   : Tag1
114 { };
115 
116 
117 template<class Tag, class QueryTag> struct represents
118   : detail::represents_impl<Tag, detail::retag_default_cc<QueryTag,Tag> >
119 { };
120 
121 
122 template<class Tag, class QueryTag> struct extract
123 {
124   typedef detail::constant<
125     ::boost::function_types::detail::tag_ice
126       < ::boost::function_types::detail::bits<Tag>::value
127       , ::boost::function_types::detail::mask<Tag>::value
128       , ::boost::function_types::detail::bits<QueryTag>::value
129       , ::boost::function_types::detail::mask<QueryTag>::value
130       >::extracted_bits
131   > bits;
132 
133   typedef detail::constant<
134     ::boost::function_types::detail::mask<QueryTag>::value
135   > mask;
136 };
137 
138 /*
139 
140   The following is a metafunction which checks whether a
141   property tag is in a possibly compounded tag type.
142 
143   Here both the possibly compounded tag type and a property tag
144   is given.
145 
146 */
147 
148 template<class Tag, class PropertyTag> struct has_property_tag
149   : detail::represents_impl<Tag,  PropertyTag>
150 { };
151 
152 } } // namespace ::boost::function_types
153 
154 #include <boost/function_types/detail/pp_tags/preprocessed.hpp>
155 
156 namespace boost { namespace function_types {
157 #define BOOST_FT_cc_file <boost/function_types/detail/pp_tags/cc_tag.hpp>
158 #include <boost/function_types/detail/pp_loop.hpp>
159 
160 /*
161 
162   The following are metafunctions which check whether the
163   specific property tag is in a possibly compounded tag type.
164   Here only the possibly compounded tag type is given.
165 
166 */
167 
168 template<class Tag> struct has_property_tag<Tag,null_tag>
169   : ::boost::is_same<Tag, null_tag>
170 { };
171 
172 template<class Tag> struct has_variadic_property_tag
173   : has_property_tag<Tag,  variadic>
174 { };
175 
176 template<class Tag> struct has_default_cc_property_tag
177   : has_property_tag<Tag,  default_cc>
178 { };
179 
180 template<class Tag> struct has_const_property_tag
181   : has_property_tag<Tag,  const_qualified>
182 { };
183 
184 template<class Tag> struct has_volatile_property_tag
185   : has_property_tag<Tag,  volatile_qualified>
186 { };
187 
188 template<class Tag> struct has_cv_property_tag
189   : has_property_tag<Tag,  cv_qualified>
190 { };
191 
192 template<class Tag> struct has_null_property_tag
193   : has_property_tag<Tag,  null_tag>
194 { };
195 
196 } } // namespace boost::function_types
197 
198 #endif
199 
200