blob: 60cace27f69bcac6b3d037e6aa0b0ee4ffd64f95 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// file : CCF/IDL2/Traversal/Elements.tpp
// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
// cvs-id : $Id$
#include <iostream>
using std::cerr;
using std::endl;
namespace CCF
{
namespace IDL2
{
namespace Traversal
{
// Traverser
//
//
template<typename T>
Traverser<T>::
~Traverser ()
{
}
// Dispatcher
//
//
template <typename T>
Dispatcher<T>::
~Dispatcher ()
{
}
template <typename T>
void Dispatcher<T>::
traverse (T& n)
{
LevelMap levels;
unsigned long max = compute_levels (n.type_info (), 0, levels);
//cerr << "starting dispatch process for "
// << n.type_info ().type_id () << " with "
// << max << " levels" << endl;
for (unsigned long l = 0; l < max + 1; ++l)
{
TypeInfoSet dispatched;
for (typename LevelMap::const_iterator
i (levels.begin ()), e (levels.end ());
i != e; ++i)
{
if (i->second == l)
{
typename TraversalMap::const_iterator v (
traversal_map_.find (i->first.type_id ()));
if (v != traversal_map_.end ())
{
//cerr << "dispatching traversers for "
// << n.type_info ().type_id () << " as "
// << i->first.type_id () << endl;
Traversers const& traversers (v->second);
for (typename Traversers::const_iterator
ti (traversers.begin ()), te (traversers.end ());
ti != te; ++ti)
{
(*ti)->trampoline (n);
}
flatten_tree (i->first, dispatched);
}
}
}
// Remove traversed types from level map.
//
for (typename TypeInfoSet::const_iterator i = dispatched.begin ();
i != dispatched.end ();
++i)
{
levels.erase (*i);
}
}
}
template <typename T>
unsigned long Dispatcher<T>::
compute_levels (Introspection::TypeInfo const& ti,
unsigned long cur,
LevelMap& map)
{
unsigned long ret = cur;
if (map.find (ti) == map.end () || map[ti] < cur) map[ti] = cur;
for (Introspection::TypeInfo::BaseIterator i = ti.begin_base ();
i != ti.end_base ();
i++)
{
unsigned long t = compute_levels (i->type_info (), cur + 1, map);
if (t > ret) ret = t;
}
return ret;
}
template <typename T>
void Dispatcher<T>::
flatten_tree (Introspection::TypeInfo const& ti, TypeInfoSet& set)
{
set.insert (ti);
for (Introspection::TypeInfo::BaseIterator i = ti.begin_base ();
i != ti.end_base ();
i++)
{
flatten_tree (i->type_info (), set);
}
}
}
}
}
|