From 8e761289a2446367267c6c0d9a26e734f0f78306 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 16 Dec 2020 20:29:05 +0300 Subject: Get rid of legacy build systems and rename cutl/ to libcutl/ --- libcutl/compiler/traversal.txx | 143 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 libcutl/compiler/traversal.txx (limited to 'libcutl/compiler/traversal.txx') diff --git a/libcutl/compiler/traversal.txx b/libcutl/compiler/traversal.txx new file mode 100644 index 0000000..67e7f4d --- /dev/null +++ b/libcutl/compiler/traversal.txx @@ -0,0 +1,143 @@ +// file : libcutl/compiler/traversal.txx +// license : MIT; see accompanying LICENSE file + +namespace cutl +{ + namespace compiler + { + // traverser + // + template + traverser:: + ~traverser () + { + } + + // traverser_impl + // + + template + void traverser_impl:: + trampoline (B& x) + { + this->traverse (dynamic_cast (x)); + } + + // dispatcher + // + + template + dispatcher:: + ~dispatcher () + { + } + + template + void dispatcher:: + traverser (traverser_map& m) + { + // Copy entries from m to our map. + // + for (typename traverser_map::iterator + i (m.begin ()), e (m.end ()); i != e; ++i) + { + typename traverser_map::traversers& travs (this->map_[i->first]); + + for (typename traverser_map::traversers::const_iterator + t (i->second.begin ()), e (i->second.end ()); t != e; ++t) + { + travs.push_back (*t); + } + } + } + + template + void dispatcher:: + dispatch (B& x) + { + using std::size_t; + + level_map levels; + type_info const& ti (lookup (x)); + size_t max (compute_levels (ti, 0, levels)); + + // cerr << "starting dispatch process for " << ti.type_id ().name () + // << " with " << max << " levels" << endl; + + for (size_t l (0); l < max + 1; ++l) + { + type_info_set dispatched; + + for (typename level_map::const_iterator + i (levels.begin ()), e (levels.end ()); i != e; ++i) + { + if (i->second == l) + { + typename traverser_map::map_type::const_iterator v ( + this->map_.find (i->first.type_id ())); + + if (v != this->map_.end ()) + { + // cerr << "dispatching traversers for " << ti.type_id ().name () + // << " as " << i->first.type_id ().name () << endl; + + typename traverser_map::traversers const& travs (v->second); + + for (typename traverser_map::traversers::const_iterator + ti (travs.begin ()), te (travs.end ()); ti != te; ++ti) + { + (*ti)->trampoline (x); + } + + flatten_tree (i->first, dispatched); + } + } + } + + // Remove traversed types from the level map. + // + for (typename type_info_set::const_iterator i (dispatched.begin ()); + i != dispatched.end (); ++i) + { + levels.erase (*i); + } + } + } + + template + std::size_t dispatcher:: + compute_levels (type_info const& ti, std::size_t cur, level_map& map) + { + using std::size_t; + + size_t ret (cur); + + if (map.find (ti) == map.end () || map[ti] < cur) + map[ti] = cur; + + for (type_info::base_iterator i (ti.begin_base ()); + i != ti.end_base (); ++i) + { + size_t tmp (compute_levels (i->type_info (), cur + 1, map)); + + if (tmp > ret) + ret = tmp; + } + + return ret; + } + + template + void dispatcher:: + flatten_tree (type_info const& ti, type_info_set& set) + { + set.insert (ti); + + for (type_info::base_iterator i (ti.begin_base ()); + i != ti.end_base (); ++i) + { + flatten_tree (i->type_info (), set); + } + } + } +} -- cgit v1.1