Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
wire-cell-build
util
test
test_typeid.cxx
Go to the documentation of this file.
1
/**
2
* The idea is that there are objects of a base interface IComponent
3
* which may also implement some other interface, here IPort. The
4
* objects are initially known through IComponent and a templated
5
* function, transfer(), must be called on these objects but through a
6
* middle sublcass which contains some needed type info, here Port<T>.
7
*
8
* The solution is to create a context (CallTransfer and
9
* CallTransferT<> structs) which knows the type T and then register a
10
* number of instances of this context using the type_info::name() of
11
* the instantiated T.
12
*
13
* Then, the base interface IPort has a pure abstract method to return
14
* the type_info::name() supplied by the subclass. This is used to
15
* look up the corresponding context which takes the base IPort
16
* objects and dynamic_cast's them to the needed subclass.
17
*/
18
19
#include "
WireCellUtil/Testing.h
"
20
#include "
WireCellUtil/Interface.h
"
21
#include <iostream>
22
#include <typeinfo>
23
#include <map>
24
#include <string>
25
26
using namespace
std
;
27
28
29
struct
IPort
{
30
virtual
~IPort
() {};
31
virtual
std::string
port_type_name()
const
= 0;
32
};
33
34
template
<
typename
T>
35
struct
Port
:
public
IPort
{
36
typedef
T
port_type
;
37
virtual
~Port
() {}
38
virtual
std::string
port_type_name
()
const
{
39
return
typeid
(port_type).
name
();
40
}
41
virtual
bool
put
(
const
port_type& in) {
return
false
; }
42
virtual
bool
get
(port_type& out)
const
{
return
false
; }
43
virtual
T
make
()
const
{
return
0; }
44
};
45
46
struct
SubI
:
public
Port
<int> {
47
virtual
~SubI
() {}
48
virtual
bool
get
(
port_type
& out)
const
{
49
out = 42;
50
cerr <<
"SubI::get("
<< out <<
")"
<<
endl
;
51
return
true
;
52
}
53
};
54
struct
SubF
:
public
Port
<float> {
55
virtual
~SubF
() {}
56
virtual
bool
get
(
port_type
& out)
const
{
57
out = 6.9;
58
cerr <<
"SubF::get("
<< out <<
")"
<<
endl
;
59
return
true
;
60
}
61
};
62
63
struct
SubFIn
:
public
Port
<float> {
64
virtual
~SubFIn
() {}
65
virtual
bool
put
(
const
port_type
& in) {
66
cerr <<
"SubFIn::put("
<< in <<
")"
<<
endl
;
67
return
true
;
68
}
69
virtual
bool
get
(
port_type
& out)
const
{
70
cerr <<
"SubIn::get() can not provide data"
<<
endl
;
71
return
true
;
72
}
73
74
};
75
76
struct
SubFOut
:
public
Port
<float> {
77
virtual
~SubFOut
() {}
78
virtual
bool
put
(
const
port_type
& in) {
79
cerr <<
"SubFOut::put("
<< in <<
") can not accept data"
<<
endl
;
80
return
false
;
81
}
82
virtual
bool
get
(
port_type
& out)
const
{
83
out = 6.9;
84
cerr <<
"SubFOut::get("
<< out <<
")"
<<
endl
;
85
return
true
;
86
}
87
};
88
89
90
template
<
typename
A,
typename
B>
91
bool
transfer
(
const
A
&
a
,
B
&
b
)
92
{
93
cerr <<
"transfer: "
94
<<
typeid
(
A
).
name
() <<
"<->"
<<
typeid
(
a
).
name
() <<
" "
95
<<
typeid
(
B
).
name
() <<
"<->"
<<
typeid
(
b
).
name
() <<
endl
;
96
97
98
if
(a.port_type_name() != b.port_type_name()) {
99
cerr <<
"Port type mismatch: "
100
<< a.port_type_name() <<
" != "
<< b.port_type_name() <<
endl
;
101
return
false
;
102
}
103
typename
A::port_type
dat
;
104
if
(!a.get(dat)) {
105
cerr <<
"Failed to get output of type "
<< a.port_type_name() <<
endl
;
106
return
false
;
107
}
108
if
(!b.put(dat)) {
109
cerr <<
"Failed to put input of type "
<< b.port_type_name() <<
endl
;
110
return
false
;
111
}
112
return
true
;
113
}
114
115
struct
CallTransfer
{
116
virtual
~CallTransfer
() {}
117
virtual
bool
call(
const
IPort
&
a
,
IPort
&
b
) = 0;
118
};
119
120
template
<
typename
T>
121
struct
CallTransferT
:
public
CallTransfer
{
122
typedef
T
port_type
;
123
virtual
~CallTransferT
() {}
124
std::string
port_type_name
()
const
{
125
return
typeid
(port_type).
name
();
126
}
127
bool
call
(
const
IPort
&
a
,
IPort
&
b
) {
128
const
Port<port_type>
* pa =
dynamic_cast<
const
Port<port_type>
*
>
(&
a
);
129
Port<port_type>
*
pb
=
dynamic_cast<
Port<port_type>
*
>
(&
b
);
130
return
transfer
(*pa, *pb);
131
}
132
};
133
134
135
static
map<string, CallTransfer*>
callers
;
136
137
template
<
typename
T>
138
void
register_caller
()
139
{
140
CallTransferT<T>
*ct =
new
CallTransferT<T>
;
141
callers[ct->
port_type_name
()] = ct;
142
}
143
144
CallTransfer
*
get_caller
(
const
IPort
&
comp
)
145
{
146
const
IPort
* port =
dynamic_cast<
const
IPort
*
>
(&
comp
);
147
if
(!port) {
return
nullptr
; }
148
return
callers[port->
port_type_name
()];
149
}
150
151
152
int
main
()
153
{
154
155
IPort
* si =
new
SubI
;
156
IPort
* sf =
new
SubF
;
157
IPort
* sfi =
new
SubFIn
;
158
IPort
* sfo =
new
SubFOut
;
159
160
cout <<
"typeid(si) = "
<<
typeid
(si).
name
() <<
endl
;
161
cout <<
"typeid(*si) = "
<<
typeid
(*si).name() <<
endl
;
162
cout <<
"typeid(sf) = "
<<
typeid
(sf).
name
() <<
endl
;
163
cout <<
"typeid(*sf) = "
<<
typeid
(*sf).name() <<
endl
;
164
cout <<
"typeid(sfo) = "
<<
typeid
(sfo).
name
() <<
endl
;
165
cout <<
"typeid(*sfo) = "
<<
typeid
(*sfo).name() <<
endl
;
166
cout <<
"typeid(sfi) = "
<<
typeid
(sfi).
name
() <<
endl
;
167
cout <<
"typeid(*sfi) = "
<<
typeid
(*sfi).name() <<
endl
;
168
169
cout <<
"typeid(SubI::port_type) = "
<<
typeid
(
SubI::port_type
).
name
() <<
endl
;
170
cout <<
"typeid(SubF::port_type) = "
<<
typeid
(
SubF::port_type
).
name
() <<
endl
;
171
cout <<
"typeid(SubFOut::port_type) = "
<<
typeid
(
SubFOut::port_type
).
name
() <<
endl
;
172
cout <<
"typeid(SubFIn::port_type) = "
<<
typeid
(
SubFIn::port_type
).
name
() <<
endl
;
173
174
cout <<
"si->type_name() = "
<< si->
port_type_name
() <<
endl
;
175
cout <<
"sf->type_name() = "
<< sf->
port_type_name
() <<
endl
;
176
cout <<
"sfo->type_name() = "
<< sfo->
port_type_name
() <<
endl
;
177
cout <<
"sfi->type_name() = "
<< sfi->
port_type_name
() <<
endl
;
178
179
// given just Port*, how to know what to dynamic_cast to???
180
Port<float>
* bfi =
dynamic_cast<
Port<float>
*
>
(sfi);
181
Port<float>
* bfo =
dynamic_cast<
Port<float>
*
>
(sfo);
182
Assert
(bfi);
183
Assert
(bfo);
184
Assert
(
transfer
(*bfo, *bfi));
185
186
// okay, like this:
187
register_caller<int>();
188
register_caller<float>();
189
190
IPort
* ci =
new
SubFIn
;
191
IPort
* co =
new
SubFOut
;
192
193
194
195
CallTransfer
* ct =
get_caller
(*ci);
196
Assert
(ct);
197
Assert
(ct->
call
(*co, *ci));
198
199
return
0;
200
}
name
static QCString name
Definition:
declinfo.cpp:673
Port::~Port
virtual ~Port()
Definition:
test_typeid.cxx:37
Port::port_type
T port_type
Definition:
test_typeid.cxx:36
CallTransfer::~CallTransfer
virtual ~CallTransfer()
Definition:
test_typeid.cxx:116
B
Definition:
pointersEqual_t.cc:9
main
int main()
Definition:
test_typeid.cxx:152
IPort::~IPort
virtual ~IPort()
Definition:
test_typeid.cxx:30
string
std::string string
Definition:
nybbler.cc:12
CallTransfer::call
virtual bool call(const IPort &a, IPort &b)=0
wirecell.sigproc.paper.noise.dat
dat
Definition:
noise.py:64
transfer
bool transfer(const A &a, B &b)
Definition:
test_typeid.cxx:91
CallTransfer
Definition:
test_typeid.cxx:115
IPort::port_type_name
virtual std::string port_type_name() const =0
SubFOut::put
virtual bool put(const port_type &in)
Definition:
test_typeid.cxx:78
Port
Definition:
test_typeid.cxx:35
ValidateOpDetSimulation.T
T
Definition:
ValidateOpDetSimulation.py:48
std
STL namespace.
dbjson.comp
comp
Definition:
dbjson.py:31
SubFIn::put
virtual bool put(const port_type &in)
Definition:
test_typeid.cxx:65
CallTransferT::~CallTransferT
virtual ~CallTransferT()
Definition:
test_typeid.cxx:123
SubFIn
Definition:
test_typeid.cxx:63
IPort
Definition:
test_typeid.cxx:29
Assert
#define Assert
Definition:
Testing.h:7
SubFIn::~SubFIn
virtual ~SubFIn()
Definition:
test_typeid.cxx:64
Port::put
virtual bool put(const port_type &in)
Definition:
test_typeid.cxx:41
SubFOut::~SubFOut
virtual ~SubFOut()
Definition:
test_typeid.cxx:77
CallTransferT::port_type_name
std::string port_type_name() const
Definition:
test_typeid.cxx:124
genie::units::pb
static const double pb
Definition:
Units.h:90
register_caller
void register_caller()
Definition:
test_typeid.cxx:138
Testing.h
Port::port_type_name
virtual std::string port_type_name() const
Definition:
test_typeid.cxx:38
SubF::~SubF
virtual ~SubF()
Definition:
test_typeid.cxx:55
a
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition:
pointer.h:1124
SubI::~SubI
virtual ~SubI()
Definition:
test_typeid.cxx:47
Port::make
virtual T make() const
Definition:
test_typeid.cxx:43
get_caller
CallTransfer * get_caller(const IPort &comp)
Definition:
test_typeid.cxx:144
CallTransferT::port_type
T port_type
Definition:
test_typeid.cxx:122
CallTransferT
Definition:
test_typeid.cxx:121
B
Autolink_Test B
Definition:
autolink.cpp:95
CallTransferT::call
bool call(const IPort &a, IPort &b)
Definition:
test_typeid.cxx:127
A
#define A
Definition:
memgrp.cpp:38
b
static bool * b
Definition:
config.cpp:1043
SubI
Definition:
test_typeid.cxx:46
callers
static map< string, CallTransfer * > callers
Definition:
test_typeid.cxx:135
Interface.h
SubF
Definition:
test_typeid.cxx:54
SubFOut
Definition:
test_typeid.cxx:76
endl
QTextStream & endl(QTextStream &s)
Definition:
qtextstream.cpp:2030
Generated by
1.8.11