From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- .../frontend-elements/traversal.txx | 135 +++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 libfrontend-elements/frontend-elements/traversal.txx (limited to 'libfrontend-elements/frontend-elements/traversal.txx') diff --git a/libfrontend-elements/frontend-elements/traversal.txx b/libfrontend-elements/frontend-elements/traversal.txx new file mode 100644 index 0000000..6e6bfa3 --- /dev/null +++ b/libfrontend-elements/frontend-elements/traversal.txx @@ -0,0 +1,135 @@ +// file : frontend-elements/traversal.txx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace FrontendElements +{ + namespace Traversal + { + // TraverserBase + // + + template + TraverserBase:: + ~TraverserBase () + { + } + + // DispatcherBase + // + + template + DispatcherBase:: + ~DispatcherBase () + { + } + + template + Void DispatcherBase:: + dispatch (X& x) + { + dispatch_ (x); + } + + template + void DispatcherBase:: + dispatch (X const& x) + { + dispatch_ (x); + } + + template + template + void DispatcherBase:: + dispatch_ (Y& y) + { + LevelMap levels; + + TypeInfo const& ti (Cult::RTTI::lookup (typeid (y))); + + UnsignedLong max (compute_levels (ti, 0, levels)); + + tout << "starting dispatch process for " << ti.type_id ().name () + << " with " << max << " levels"; + + for (UnsignedLong l (0); l < max + 1; ++l) + { + TypeInfoSet dispatched; + + for (typename LevelMap::ConstIterator + i (levels.begin ()), e (levels.end ()); i != e; ++i) + { + if (i->second == l) + { + typename TraversalMap::ConstIterator v ( + traversal_map_.find (i->first.type_id ())); + + if (v != traversal_map_.end ()) + { + tout << "dispatching traversers for " << ti.type_id ().name () + << " as " << i->first.type_id ().name (); + + Traversers const& traversers (v->second); + + for (typename Traversers::ConstIterator + ti (traversers.begin ()), te (traversers.end ()); ti != te; ++ti) + { + (*ti)->trampoline (y); + } + + flatten_tree (i->first, dispatched); + } + } + } + + // Remove traversed types from the level map. + // + for (typename TypeInfoSet::ConstIterator i (dispatched.begin ()); + i != dispatched.end (); ++i) + { + levels.erase (*i); + } + } + } + + + template + UnsignedLong DispatcherBase:: + compute_levels (TypeInfo const& ti, UnsignedLong cur, LevelMap& map) + { + UnsignedLong 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) + { + UnsignedLong tmp (compute_levels (i->type_info (), cur + 1, map)); + + if (tmp > ret) + ret = tmp; + } + + return ret; + } + + template + Void DispatcherBase:: + 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); + } + } + + template + Cult::Trace::Stream DispatcherBase:: + tout ("frontend-elements::traversal", 5); + } +} + -- cgit v1.2.3