00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_BIT_MASKING_INCLUDE
00013 #define MTL_BIT_MASKING_INCLUDE
00014
00015 #include <boost/type_traits.hpp>
00016 #include <boost/mpl/if.hpp>
00017
00018 #include <boost/numeric/mtl/utility/tag.hpp>
00019
00020 namespace mtl {
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 template <unsigned long N>
00096 struct lsb_mask
00097 {
00098 static const unsigned long value= (lsb_mask<N-1>::value << 1) | 1;
00099 };
00100
00101
00102 template <>
00103 struct lsb_mask<0>
00104 {
00105 static const unsigned long value= 0;
00106 };
00107
00108
00110 template <unsigned long N, unsigned long Value>
00111 struct lsb_bits
00112 {
00113 static const unsigned long value= lsb_mask<N>::value & Value;
00114 };
00115
00116
00118 template <unsigned long Mask1, unsigned long Mask2>
00119 struct same_mask
00120 {
00121 static const bool value= false;
00122 };
00123
00124 template <unsigned long Mask>
00125 struct same_mask<Mask, Mask>
00126 {
00127 static const bool value= true;
00128 };
00129
00130
00132 template <unsigned long K>
00133 struct row_major_mask
00134 {
00135 static const unsigned long value= lsb_mask<K>::value << K;
00136 };
00137
00138
00140 template <unsigned long K>
00141 struct col_major_mask
00142 : public lsb_mask<K>
00143 {};
00144
00145
00147 template <unsigned long K, unsigned long Mask>
00148 struct is_k_power_base_case_row_major
00149 {
00150 static const bool value= same_mask<lsb_bits<2*K, Mask>::value, row_major_mask<K>::value>::value;
00151
00152 };
00153
00154
00156 template <unsigned long K, unsigned long Mask>
00157 struct is_k_power_base_case_col_major
00158 {
00159 static const bool value= same_mask<lsb_bits<2*K, Mask>::value, col_major_mask<K>::value>::value;
00160 };
00161
00162
00164 template <unsigned long Mask>
00165 struct is_32_base_case_row_major
00166 : public is_k_power_base_case_row_major<5, Mask>
00167 {};
00168
00169
00171 template <unsigned long Mask>
00172 struct is_32_base_case_col_major
00173 : public is_k_power_base_case_col_major<5, Mask>
00174 {};
00175
00176
00178 template <unsigned long K, unsigned long T>
00179 struct row_major_shark_mask
00180 {
00181 static const unsigned long value= (lsb_mask<K-T>::value << (K+T)) | lsb_mask<T>::value;
00182 };
00183
00184
00186 template <unsigned long K, unsigned long T>
00187 struct col_major_shark_mask
00188 {
00189 static const unsigned long value= lsb_mask<K>::value << T;
00190 };
00191
00192
00196 template <unsigned long K, unsigned long T, unsigned long Mask>
00197 struct is_k_power_base_case_row_major_t_shark
00198 {
00199 static const bool value= same_mask<lsb_bits<2*K, Mask>::value, row_major_shark_mask<K, T>::value>::value;
00200 };
00201
00202
00206 template <unsigned long K, unsigned long T, unsigned long Mask>
00207 struct is_k_power_base_case_col_major_t_shark
00208 {
00209 static const bool value= same_mask<lsb_bits<2*K, Mask>::value, col_major_shark_mask<K, T>::value>::value;
00210 };
00211
00212
00214 template <unsigned long N>
00215 struct i_order_mask
00216 {
00217
00218 static const unsigned long value= (i_order_mask<N-2>::value << 2) | 1;
00219 };
00220
00221 template<> struct i_order_mask<0> : public lsb_mask<0> {};
00222
00223
00225 template <unsigned long N>
00226 struct z_order_mask
00227 {
00228
00229 static const unsigned long value= (z_order_mask<N-2>::value << 2) | 2;
00230 };
00231
00232 template<> struct z_order_mask<0> : public lsb_mask<0> {};
00233
00234
00241 template <bool IOrder, unsigned long K, typename Orientation, unsigned long T>
00242 class generate_mask
00243 {
00244 static const unsigned long rec_size= 8 * sizeof(unsigned long) - 2 * K,
00245 rec_part= (IOrder ? i_order_mask<rec_size>::value : z_order_mask<rec_size>::value) << 2*K;
00246 typedef typename boost::mpl::if_<
00247 boost::is_same<Orientation, row_major>
00248 , row_major_shark_mask<K, T>
00249 , col_major_shark_mask<K, T>
00250 >::type base_part_type;
00251 public:
00252 static const unsigned long value= rec_part | base_part_type::value;
00253 };
00254
00255
00256 }
00257
00258 #endif // MTL_BIT_MASKING_INCLUDE