summaryrefslogtreecommitdiff
path: root/trunk/CIAO/CCF/Example/ComponentDeploymentDescriptor/Traversal.cpp
blob: 8f6a20649bc977a9ce89899965b7f4e4a23437f9 (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
// file      : CCF/Example/ComponentDeploymentDescriptor/Traversal.cpp
// author    : Boris Kolpackov <boris@dre.vanderbilt.edu>
// cvs-id    : $Id$

#include "Traversal.hpp"

using namespace Introspection;

namespace CDD
{
  namespace Traversal
  {

    // Dispatcher
    //
    //

    struct TypeInfoComparator
    {
      bool
      operator () (TypeInfo const& x, TypeInfo const& y) const
      {
        return x.type_id () < y.type_id ();
      }
    };

    typedef
    std::map<TypeInfo, unsigned long, TypeInfoComparator>
    LevelMap;

    typedef
    std::set<TypeInfo, TypeInfoComparator>
    TypeInfoSet;

    unsigned long
    compute_levels (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 (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;
    }

    void
    flatten_tree (TypeInfo const& ti, TypeInfoSet& set)
    {
      set.insert (ti);

      for (TypeInfo::BaseIterator i = ti.begin_base ();
           i != ti.end_base ();
           i++)
      {
        flatten_tree (i->type_info (), set);
      }
    }

    void Dispatcher::
    dispatch (SyntaxTree::NodePtr const& 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 (LevelMap::const_iterator i = levels.begin ();
             i != levels.end ();
             i++)
        {
          if (i->second == l)
          {
            TraversalMap::const_iterator v =
              traversal_map_.find (i->first.type_id ());

            if (v != traversal_map_.end () && !(v->second.suppressed))
            {
              //cerr << "dispatching traverser for "
              //     << n->type_info ().type_id () << " as "
              //     << i->first.type_id () << endl;

              v->second.traverser->traverse (n);
              flatten_tree (i->first, dispatched);
            }
          }
        }

        // Remove traversed types from level map.
        for (TypeInfoSet::const_iterator i = dispatched.begin ();
             i != dispatched.end ();
             i++)
        {
          levels.erase (*i);
        }
      }
    }
  }
}