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