00001
00002
00003
00004
00005
00006
00007
00008
00018 #ifndef array_promotions_h
00019 #define array_promotions_h
00020
00021 #include <cml/core/cml_meta.h>
00022 #include <cml/et/scalar_promotions.h>
00023
00024 namespace cml {
00025 namespace et {
00026
00027 #define VAL_MAX(_a_,_b_) ( ((_a_)>(_b_))?(_a_):(_b_) )
00028
00029 namespace detail {
00030
00031
00032 template<class A1, class A2, typename DTag1, typename DTag2,
00033 typename PromotedSizeTag> struct promote;
00034
00035
00036 template<class A1, class A2>
00037 struct promote<A1,A2,oned_tag,oned_tag,fixed_size_tag>
00038 {
00039 typedef typename A1::value_type left_scalar;
00040 typedef typename A2::value_type right_scalar;
00041
00042
00043 typedef typename ScalarPromote<
00044 left_scalar,right_scalar>::type promoted_scalar;
00045
00046
00047 enum { Size = VAL_MAX((size_t)A1::array_size, (size_t)A2::array_size) };
00048
00049
00050 typedef fixed_1D<promoted_scalar,Size> type;
00051 };
00052
00053
00054 template<class A1, class A2>
00055 struct promote<A1,A2,oned_tag,oned_tag,dynamic_size_tag>
00056 {
00057 typedef typename A1::value_type left_scalar;
00058 typedef typename A2::value_type right_scalar;
00059
00060
00061 typedef typename ScalarPromote<
00062 left_scalar,right_scalar>::type promoted_scalar;
00063
00064
00065 typedef typename CML_DEFAULT_ARRAY_ALLOC
00066 ::rebind<promoted_scalar>::other allocator;
00067
00068
00069 typedef dynamic_1D<promoted_scalar,allocator> type;
00070 };
00071
00072
00073 template<class A1, class A2>
00074 struct promote<A1,A2,twod_tag,oned_tag,fixed_size_tag>
00075 {
00076 typedef typename A1::value_type left_scalar;
00077 typedef typename A2::value_type right_scalar;
00078
00079
00080 typedef typename ScalarPromote<
00081 left_scalar,right_scalar>::type promoted_scalar;
00082
00083
00084 enum { Size = (size_t)A1::array_rows };
00085
00086
00087 typedef fixed_1D<promoted_scalar,Size> type;
00088 };
00089
00090
00091 template<class A1, class A2>
00092 struct promote<A1,A2,oned_tag,twod_tag,fixed_size_tag>
00093 {
00094 typedef typename A1::value_type left_scalar;
00095 typedef typename A2::value_type right_scalar;
00096
00097
00098 typedef typename ScalarPromote<
00099 left_scalar,right_scalar>::type promoted_scalar;
00100
00101
00102 enum { Size = (size_t)A2::array_cols };
00103
00104
00105 typedef fixed_1D<promoted_scalar,Size> type;
00106 };
00107
00108
00109 template<class A1, class A2>
00110 struct promote<A1,A2,twod_tag,oned_tag,dynamic_size_tag>
00111 {
00112 typedef typename A1::value_type left_scalar;
00113 typedef typename A2::value_type right_scalar;
00114
00115
00116 typedef typename ScalarPromote<
00117 left_scalar,right_scalar>::type promoted_scalar;
00118
00119
00120 typedef typename CML_DEFAULT_ARRAY_ALLOC
00121 ::rebind<promoted_scalar>::other allocator;
00122
00123
00124 typedef dynamic_1D<promoted_scalar,allocator> type;
00125 };
00126
00127
00128 template<class A1, class A2>
00129 struct promote<A1,A2,oned_tag,twod_tag,dynamic_size_tag>
00130 {
00131 typedef typename A1::value_type left_scalar;
00132 typedef typename A2::value_type right_scalar;
00133
00134
00135 typedef typename ScalarPromote<
00136 left_scalar,right_scalar>::type promoted_scalar;
00137
00138
00139 typedef typename CML_DEFAULT_ARRAY_ALLOC
00140 ::rebind<promoted_scalar>::other allocator;
00141
00142
00143 typedef dynamic_1D<promoted_scalar,allocator> type;
00144 };
00145
00146
00147
00148 template<typename LeftL, typename RightL> struct deduce_layout {
00149 #if defined(CML_ALWAYS_PROMOTE_TO_DEFAULT_LAYOUT)
00150 typedef CML_DEFAULT_ARRAY_LAYOUT promoted_layout;
00151 #else
00152 typedef typename select_if<
00153 same_type<LeftL,RightL>::is_true, LeftL,
00154 CML_DEFAULT_ARRAY_LAYOUT>::result promoted_layout;
00155 #endif
00156 };
00157
00158
00159
00160
00161
00162 template<class A1, class A2>
00163 struct promote<A1,A2,twod_tag,twod_tag,fixed_size_tag>
00164 {
00165 typedef typename A1::value_type left_scalar;
00166 typedef typename A2::value_type right_scalar;
00167
00168
00169 typedef typename ScalarPromote<
00170 left_scalar,right_scalar>::type promoted_scalar;
00171
00172
00173 enum {
00174 Rows = (size_t)A1::array_rows,
00175 Cols = (size_t)A2::array_cols
00176 };
00177
00178
00179 typedef typename A1::layout left_layout;
00180 typedef typename A2::layout right_layout;
00181 typedef typename deduce_layout<left_layout,right_layout>
00182 ::promoted_layout promoted_layout;
00183
00184
00185 typedef fixed_2D<promoted_scalar,Rows,Cols,promoted_layout> type;
00186 };
00187
00188
00189 template<class A1, class A2>
00190 struct promote<A1,A2,twod_tag,twod_tag,dynamic_size_tag>
00191 {
00192 typedef typename A1::value_type left_scalar;
00193 typedef typename A2::value_type right_scalar;
00194
00195
00196 typedef typename ScalarPromote<
00197 left_scalar,right_scalar>::type promoted_scalar;
00198
00199
00200 typedef typename CML_DEFAULT_ARRAY_ALLOC
00201 ::rebind<promoted_scalar>::other allocator;
00202
00203
00204 typedef typename A1::layout left_layout;
00205 typedef typename A2::layout right_layout;
00206 typedef typename deduce_layout<left_layout,right_layout>
00207 ::promoted_layout promoted_layout;
00208
00209
00210 typedef dynamic_2D<promoted_scalar,promoted_layout,allocator> type;
00211 };
00212
00213 }
00214
00224 template<class A1, class A2>
00225 struct ArrayPromote
00226 {
00227
00228
00229
00230 typedef typename A1::dimension_tag left_dtag;
00231 typedef typename A2::dimension_tag right_dtag;
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 typedef typename select_if<
00268 (same_type<typename A1::size_tag, fixed_size_tag>::is_true
00269 && same_type<typename A2::size_tag, fixed_size_tag>::is_true),
00270 fixed_size_tag,
00271 dynamic_size_tag
00272 >::result promoted_size_tag;
00273
00274
00275 typedef typename detail::promote<
00276 A1, A2, left_dtag, right_dtag, promoted_size_tag>::type type;
00277 };
00278
00279
00280 #undef VAL_MAX
00281
00282 }
00283 }
00284
00285 #endif
00286
00287
00288