00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00037 #ifndef RC_PORTMAP_H_
00038 #define RC_PORTMAP_H_
00039
00040 #include "ReChannel/core/rc_common_header.h"
00041 #include "ReChannel/core/rc_report_ids.h"
00042 #include "ReChannel/util/rc_object_handle.h"
00043 #include "ReChannel/util/rc_port_handle.h"
00044 #include "ReChannel/util/rc_export_handle.h"
00045
00046 #include <boost/type_traits/is_base_of.hpp>
00047
00048 namespace ReChannel {
00049
00053 class rc_portmap_base
00054 {
00055 private:
00056 typedef rc_portmap_base this_type;
00057
00058 public:
00059 enum { portmap_size = 0 };
00060
00061 protected:
00062 rc_portmap_base()
00063 : p_arr(NULL), p_size(0)
00064 { }
00065
00066 public:
00067 int size() const
00068 { return p_size; }
00069
00070 rc_object_handle get(int index) const;
00071
00072 rc_object_handle operator[](int index) const
00073 { return this->get(index); }
00074
00075 sc_object& get_object(int index) const;
00076
00077 sc_interface* get_interface(int index) const;
00078
00079 virtual bool is_compatible(this_type& portmap) const = 0;
00080
00081 protected:
00082
00083 virtual ~rc_portmap_base() {}
00084
00085
00086
00087 void _rc_init(rc_object_handle arr[], int size);
00088
00089 private:
00090 rc_object_handle* p_arr;
00091 int p_size;
00092 };
00093
00097 template<
00098 class ID, class P0,
00099 class P1=void, class P2=void, class P3=void, class P4=void,
00100 class P5=void, class P6=void, class P7=void, class P8=void,
00101 class P9=void, class P10=void, class P11=void, class P12=void,
00102 class P13=void, class P14=void, class P15=void, class P16=void,
00103 class P17=void, class P18=void, class P19=void, class P20=void,
00104 class P21=void, class P22=void, class P23=void, class P24=void,
00105 class P25=void, class P26=void, class P27=void, class P28=void,
00106 class P29=void, class P30=void, class P31=void, class P32=void,
00107 class P33=void, class P34=void, class P35=void, class P36=void,
00108 class P37=void, class P38=void, class P39=void, class P40=void,
00109 class P41=void, class P42=void, class P43=void, class P44=void,
00110 class P45=void, class P46=void, class P47=void, class P48=void,
00111 class P49=void, class P50=void, class P51=void, class P52=void,
00112 class P53=void, class P54=void, class P55=void, class P56=void,
00113 class P57=void, class P58=void, class P59=void, class P60=void,
00114 class P61=void, class P62=void>
00115 class rc_portmap
00116 : public rc_portmap_base
00117 {
00118 private:
00119 typedef rc_portmap<
00120 ID,
00121 P0, P1, P2, P3, P4, P5, P6, P7, P8, P9,
00122 P10, P11, P12, P13, P14, P15, P16, P17, P18, P19,
00123 P20, P21, P22, P23, P24, P25, P26, P27, P28, P29,
00124 P30, P31, P32, P33, P34, P35, P36, P37, P38, P39,
00125 P40, P41, P42, P43, P44, P45, P46, P47, P48, P49,
00126 P50, P51, P52, P53, P54, P55, P56, P57, P58, P59,
00127 P60, P61, P62> this_type;
00128 typedef rc_portmap_base base_type;
00129
00130 #define _RC_TMP_undef_check(class_name) \
00131 !(boost::is_base_of<sc_port_base, class_name>::value == true \
00132 || boost::is_base_of<sc_export_base, class_name>::value == true \
00133 || (boost::is_base_of<sc_object, class_name>::value == true \
00134 && boost::is_base_of<sc_interface, class_name>::value == true))
00135 enum {
00136 N = (_RC_TMP_undef_check(P0) ? 0 :(_RC_TMP_undef_check(P1) ? 1 :
00137 (_RC_TMP_undef_check(P2) ? 2 :(_RC_TMP_undef_check(P3) ? 3 :
00138 (_RC_TMP_undef_check(P4) ? 4 :(_RC_TMP_undef_check(P5) ? 5 :
00139 (_RC_TMP_undef_check(P6) ? 6 :(_RC_TMP_undef_check(P7) ? 7 :
00140 (_RC_TMP_undef_check(P8) ? 8 :(_RC_TMP_undef_check(P9) ? 9 :
00141 (_RC_TMP_undef_check(P10)? 10 :(_RC_TMP_undef_check(P11)? 11 :
00142 (_RC_TMP_undef_check(P12)? 12 :(_RC_TMP_undef_check(P13)? 13 :
00143 (_RC_TMP_undef_check(P14)? 14 :(_RC_TMP_undef_check(P15)? 15 :
00144 (_RC_TMP_undef_check(P16)? 16 :(_RC_TMP_undef_check(P17)? 17 :
00145 (_RC_TMP_undef_check(P18)? 18 :(_RC_TMP_undef_check(P19)? 19 :
00146 (_RC_TMP_undef_check(P20)? 20 :(_RC_TMP_undef_check(P21)? 21 :
00147 (_RC_TMP_undef_check(P22)? 22 :(_RC_TMP_undef_check(P23)? 23 :
00148 (_RC_TMP_undef_check(P24)? 24 :(_RC_TMP_undef_check(P25)? 25 :
00149 (_RC_TMP_undef_check(P26)? 26 :(_RC_TMP_undef_check(P27)? 27 :
00150 (_RC_TMP_undef_check(P28)? 28 :(_RC_TMP_undef_check(P29)? 29 :
00151 (_RC_TMP_undef_check(P30)? 30 :(_RC_TMP_undef_check(P31)? 31 :
00152 (_RC_TMP_undef_check(P32)? 32 :(_RC_TMP_undef_check(P33)? 33 :
00153 (_RC_TMP_undef_check(P34)? 34 :(_RC_TMP_undef_check(P35)? 35 :
00154 (_RC_TMP_undef_check(P36)? 36 :(_RC_TMP_undef_check(P37)? 37 :
00155 (_RC_TMP_undef_check(P38)? 38 :(_RC_TMP_undef_check(P39)? 39 :
00156 (_RC_TMP_undef_check(P40)? 40 :(_RC_TMP_undef_check(P41)? 41 :
00157 (_RC_TMP_undef_check(P42)? 42 :(_RC_TMP_undef_check(P43)? 43 :
00158 (_RC_TMP_undef_check(P44)? 44 :(_RC_TMP_undef_check(P45)? 45 :
00159 (_RC_TMP_undef_check(P46)? 46 :(_RC_TMP_undef_check(P47)? 47 :
00160 (_RC_TMP_undef_check(P48)? 48 :(_RC_TMP_undef_check(P49)? 49 :
00161 (_RC_TMP_undef_check(P50)? 50 :(_RC_TMP_undef_check(P51)? 51 :
00162 (_RC_TMP_undef_check(P52)? 52 :(_RC_TMP_undef_check(P53)? 53 :
00163 (_RC_TMP_undef_check(P54)? 54 :(_RC_TMP_undef_check(P55)? 55 :
00164 (_RC_TMP_undef_check(P56)? 56 :(_RC_TMP_undef_check(P57)? 57 :
00165 (_RC_TMP_undef_check(P58)? 58 :(_RC_TMP_undef_check(P59)? 59 :
00166 (_RC_TMP_undef_check(P60)? 60 :(_RC_TMP_undef_check(P61)? 61 :
00167 (_RC_TMP_undef_check(P62)? 62 : 63
00168 )))))))))))))))))))))))))))))))
00169 ))))))))))))))))))))))))))))))))
00170 };
00171 #undef _RC_TMP_undef_check
00172
00173 public:
00174 enum { portmap_size = N };
00175 RC_STATIC_ASSERT_T(portmap_size_check, portmap_size > 0);
00176
00177 public:
00178
00179 #define _RC_TMP_arg(i) \
00180 const typename internals::template arg<P##i, (bool)(i < N)>& \
00181 p##i=internals::UNDEF
00182
00183 inline rc_portmap(
00184 P0& p0,
00185 _RC_TMP_arg(1), _RC_TMP_arg(2), _RC_TMP_arg(3), _RC_TMP_arg(4),
00186 _RC_TMP_arg(5), _RC_TMP_arg(6), _RC_TMP_arg(7), _RC_TMP_arg(8),
00187 _RC_TMP_arg(9), _RC_TMP_arg(10), _RC_TMP_arg(11), _RC_TMP_arg(12),
00188 _RC_TMP_arg(13), _RC_TMP_arg(14), _RC_TMP_arg(15), _RC_TMP_arg(16),
00189 _RC_TMP_arg(17), _RC_TMP_arg(18), _RC_TMP_arg(19), _RC_TMP_arg(20),
00190 _RC_TMP_arg(21), _RC_TMP_arg(22), _RC_TMP_arg(23), _RC_TMP_arg(24),
00191 _RC_TMP_arg(25), _RC_TMP_arg(26), _RC_TMP_arg(27), _RC_TMP_arg(28),
00192 _RC_TMP_arg(29), _RC_TMP_arg(30), _RC_TMP_arg(31), _RC_TMP_arg(32),
00193 _RC_TMP_arg(33), _RC_TMP_arg(34), _RC_TMP_arg(35), _RC_TMP_arg(36),
00194 _RC_TMP_arg(37), _RC_TMP_arg(38), _RC_TMP_arg(39), _RC_TMP_arg(40),
00195 _RC_TMP_arg(41), _RC_TMP_arg(42), _RC_TMP_arg(43), _RC_TMP_arg(44),
00196 _RC_TMP_arg(45), _RC_TMP_arg(46), _RC_TMP_arg(47), _RC_TMP_arg(48),
00197 _RC_TMP_arg(49), _RC_TMP_arg(50), _RC_TMP_arg(51), _RC_TMP_arg(52),
00198 _RC_TMP_arg(53), _RC_TMP_arg(54), _RC_TMP_arg(55), _RC_TMP_arg(56),
00199 _RC_TMP_arg(57), _RC_TMP_arg(58), _RC_TMP_arg(59), _RC_TMP_arg(60),
00200 _RC_TMP_arg(61), _RC_TMP_arg(62))
00201 {
00202 p_arr[0] = p0;
00203 this->_rc_set(1, p1); this->_rc_set(2, p2);
00204 this->_rc_set(3, p3); this->_rc_set(4, p4);
00205 this->_rc_set(5, p5); this->_rc_set(6, p6);
00206 this->_rc_set(7, p7); this->_rc_set(8, p8);
00207 this->_rc_set(9, p9); this->_rc_set(10, p10);
00208 this->_rc_set(11, p11); this->_rc_set(12, p12);
00209 this->_rc_set(13, p13); this->_rc_set(14, p14);
00210 this->_rc_set(15, p15); this->_rc_set(16, p16);
00211 this->_rc_set(17, p17); this->_rc_set(18, p18);
00212 this->_rc_set(19, p19); this->_rc_set(20, p20);
00213 this->_rc_set(21, p21); this->_rc_set(22, p22);
00214 this->_rc_set(23, p23); this->_rc_set(24, p24);
00215 this->_rc_set(25, p25); this->_rc_set(26, p26);
00216 this->_rc_set(27, p27); this->_rc_set(28, p28);
00217 this->_rc_set(29, p29); this->_rc_set(30, p30);
00218 this->_rc_set(31, p31); this->_rc_set(32, p32);
00219 this->_rc_set(33, p33); this->_rc_set(34, p34);
00220 this->_rc_set(35, p35); this->_rc_set(36, p36);
00221 this->_rc_set(37, p37); this->_rc_set(38, p38);
00222 this->_rc_set(39, p39); this->_rc_set(40, p40);
00223 this->_rc_set(41, p41); this->_rc_set(42, p42);
00224 this->_rc_set(43, p43); this->_rc_set(44, p44);
00225 this->_rc_set(45, p45); this->_rc_set(46, p46);
00226 this->_rc_set(47, p47); this->_rc_set(48, p48);
00227 this->_rc_set(49, p49); this->_rc_set(50, p50);
00228 this->_rc_set(51, p51); this->_rc_set(52, p52);
00229 this->_rc_set(53, p53); this->_rc_set(54, p54);
00230 this->_rc_set(55, p55); this->_rc_set(56, p56);
00231 this->_rc_set(57, p57); this->_rc_set(58, p58);
00232 this->_rc_set(59, p59); this->_rc_set(60, p60);
00233 this->_rc_set(61, p61); this->_rc_set(62, p62);
00234 base_type::_rc_init(p_arr, N);
00235 }
00236 #undef _RC_TMP_arg
00237
00238 virtual bool is_compatible(base_type& portmap) const
00239 { return (typeid(portmap) == typeid(*this)); }
00240
00241 private:
00242 template<class T>
00243 inline void _rc_set(
00244 int i_, const typename internals::template arg<T, true>& arg_)
00245 {
00246 T* value_ = arg_;
00247 if (value_ != NULL) {
00248 p_arr[i_] = *value_;
00249 }
00250 }
00251
00252 template<class T>
00253 inline void _rc_set(
00254 int i_,
00255 const typename internals::template arg<T, false>& arg_) const
00256 { }
00257
00258 inline void _rc_set(
00259 int i_,
00260 const typename internals::template arg<void, true>& arg_) const
00261 { }
00262
00263 private:
00264 rc_object_handle p_arr[(N > 0 ? N : 1)];
00265 };
00266
00267 }
00268
00269
00270 #if (defined(_MSC_VER) && _MSC_VER < 1400)
00271
00272 #include "ReChannel/core/rc_portmap_macros.h"
00273
00274
00275 #define _RC_DECLARE_PORTMAP(name_, portmap_size_, port_list_) \
00276 struct _RC_PORTMAP_TYPE_ID_##name_; \
00277 typedef ::ReChannel::rc_portmap< \
00278 _RC_PORTMAP_TYPE_ID_##name_, \
00279 _RC_PM_PARAMS_##portmap_size_ port_list_ \
00280 > name_
00281
00282
00283 #define _RC_DECLARE_PORTMAP_T(name_, portmap_size_, port_list_) \
00284 struct _RC_PORTMAP_TYPE_ID_##name_; \
00285 typedef typename ::ReChannel::template rc_portmap< \
00286 _RC_PORTMAP_TYPE_ID_##name_, \
00287 _RC_PM_PARAMS_##portmap_size_ port_list_ \
00288 > name_
00289
00290 #else
00291
00292
00293 #define _RC_DECLARE_PORTMAP(name_, portmap_size_, port_types_) \
00294 struct _RC_PORTMAP_TYPE_ID_##name_; \
00295 typedef ::ReChannel::rc_portmap< \
00296 _RC_PORTMAP_TYPE_ID_##name_, \
00297 _RC_PORTMAP_REMOVE_BRACKETS port_types_ \
00298 > name_; \
00299 RC_STATIC_ASSERT(portmap_validity_check, \
00300 (portmap_size_ == name_::portmap_size))
00301
00302
00303 #define _RC_DECLARE_PORTMAP_T(name_, portmap_size_, port_types_) \
00304 struct _RC_PORTMAP_TYPE_ID_##name_; \
00305 typedef typename ::ReChannel::template rc_portmap< \
00306 _RC_PORTMAP_TYPE_ID_##name_, \
00307 _RC_PORTMAP_REMOVE_BRACKETS port_types_ \
00308 > name_; \
00309 RC_STATIC_ASSERT_T(portmap_validity_check, \
00310 (portmap_size_ == name_::portmap_size))
00311
00312 #define _RC_PORTMAP_REMOVE_BRACKETS(...) __VA_ARGS__
00313
00314 #endif // (defined(_MSC_VER) && _MSC_VER < 1400)
00315
00316 #define RC_PORTMAP(name_, portmap_size_, port_types_) \
00317 _RC_DECLARE_PORTMAP(name_, portmap_size_, port_types_)
00318
00319 #define RC_PORTMAP_T(name_, portmap_size_, port_types_) \
00320 _RC_DECLARE_PORTMAP_T(name_, portmap_size_, port_types_)
00321
00322 #define RC_PORT_TYPES
00323
00324 #define RC_PORT_TYPES_T
00325
00326 #endif // RC_PORTMAP_H_
00327
00328
00329
00330
00331