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.hxx | 170 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 libcutl/compiler/traversal.hxx (limited to 'libcutl/compiler/traversal.hxx') diff --git a/libcutl/compiler/traversal.hxx b/libcutl/compiler/traversal.hxx new file mode 100644 index 0000000..dffb22d --- /dev/null +++ b/libcutl/compiler/traversal.hxx @@ -0,0 +1,170 @@ +// file : libcutl/compiler/traversal.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_COMPILER_TRAVERSAL_HXX +#define LIBCUTL_COMPILER_TRAVERSAL_HXX + +#include +#include +#include + +#include + +namespace cutl +{ + namespace compiler + { + // + // + template + class traverser + { + public: + virtual + ~traverser (); + + virtual void + trampoline (B&) = 0; + }; + + // + // + template + class traverser_map + { + public: + typedef std::vector*> traversers; + + struct map_type: std::map + { + map_type () {} + + // Don't copy traverser maps. We do it here instead of in + // traverser_map to pacify GCC's -Wextra insisting we must + // explicitly initialize virtual bases in copy constructor. + // + map_type (map_type const&): std::map () {} + map_type& operator= (map_type const&) {return *this;} + }; + + typedef typename map_type::const_iterator iterator; + + iterator + begin () const + { + return map_.begin (); + } + + iterator + end () const + { + return map_.end (); + } + + void + add (type_id const& id, traverser& t) + { + traversers& travs (map_[id]); + travs.push_back (&t); + } + + protected: + map_type map_; + }; + + // + // + template + class traverser_impl: public traverser, + public virtual traverser_map + { + public: + typedef X type; + + traverser_impl () + { + this->add (typeid (type), *this); + } + + traverser_impl (traverser_impl const&) + { + this->add (typeid (type), *this); + } + + virtual void + traverse (type&) = 0; + + public: + virtual void + trampoline (B&); + }; + + // + // + template + class dispatcher: public virtual traverser_map + { + public: + virtual + ~dispatcher (); + + void + traverser (traverser_map&); + + virtual void + dispatch (B&); + + public: + template + static void + iterate_and_dispatch (I begin, I end, dispatcher& d) + { + for (; begin != end; ++begin) + { + d.dispatch (*begin); + } + } + + template + static void + iterate_and_dispatch (I begin, + I end, + dispatcher& d, + T& t, + void (T::*next)(A&), + A& a) + { + for (; begin != end;) + { + d.dispatch (*begin); + + if (++begin != end && next != 0) + (t.*next) (a); + } + } + + private: + struct comparator + { + bool + operator () (type_info const& a, type_info const& b) const + { + return a.type_id () < b.type_id (); + } + }; + + typedef std::map level_map; + typedef std::set type_info_set; + + static std::size_t + compute_levels (type_info const&, std::size_t current, level_map&); + + static void + flatten_tree (type_info const&, type_info_set&); + }; + } +} + +#include + +#endif // LIBCUTL_COMPILER_TRAVERSAL_HXX -- cgit v1.1