From: Roland McGrath Date: Sat, 4 Jul 2009 09:03:38 +0000 (-0700) Subject: subrify some constructor magic. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ea6ffc8471c499b9fb3fc5eef0a48899f4187d7;p=thirdparty%2Felfutils.git subrify some constructor magic. --- diff --git a/libdw/c++/dwarf_data b/libdw/c++/dwarf_data index 8e765c5ed..76a44e014 100644 --- a/libdw/c++/dwarf_data +++ b/libdw/c++/dwarf_data @@ -669,8 +669,6 @@ namespace elfutils }; public: - struct nothing {}; - template struct value { @@ -726,7 +724,7 @@ namespace elfutils object. This is what plain assignment does. This just uses this pointer, rather than translating it from another file into this one (which requires a tracker). */ - inline value_reference (const value_type &i, const nothing &) + inline value_reference (const value_type &i, const subr::nothing &) : ref (i) {} @@ -876,7 +874,7 @@ namespace elfutils typename vw::value_dispatch *_m_value; typedef typename impl::debug_info_entry::pointer die_ptr; - template + template struct init { inline init (attr_value *av, diff --git a/libdw/c++/dwarf_edit b/libdw/c++/dwarf_edit index da7306233..40873e4b2 100644 --- a/libdw/c++/dwarf_edit +++ b/libdw/c++/dwarf_edit @@ -105,6 +105,8 @@ namespace elfutils class debug_info_entry { + friend class subr::create_container; + public: class children_type : public std::list @@ -113,20 +115,18 @@ namespace elfutils private: inline children_type () {} + template + static inline void + equivalence (const iterator &out, + const typename input::const_iterator &in, tracker &t) + { + t.equivalence (out, in); + } + template inline children_type (const input &other, tracker &t) { - for (typename input::const_iterator in = other.begin (); - in != other.end (); - ++in) - { - /* Don't copy-construct the entry from *in here because that - copies it again into the list and destroys the first copy. */ - push_back (debug_info_entry ()); - iterator out = --end (); - out->set (*in, t); - t.equivalence (out, in); - } + subr::create_container (this, other, t, equivalence); } public: @@ -270,6 +270,7 @@ namespace elfutils class compile_unit : public debug_info_entry { + friend class subr::create_container; friend class compile_units; private: inline compile_unit () : debug_info_entry (::DW_TAG_compile_unit) {} @@ -294,6 +295,7 @@ namespace elfutils class compile_units : public std::list { friend class dwarf_edit; + friend class subr::create_container; private: typedef std::list _base; @@ -305,17 +307,9 @@ namespace elfutils template inline compile_units (const input &other, tracker &t) { - for (typename input::const_iterator in = other.begin (); - in != other.end (); - ++in) - { - /* Don't copy-construct the entry from *in here because that - copies it again into the list and destroys the first copy. */ - push_back (compile_unit ()); - iterator out = --end (); - out->set (*in, t); - } + subr::create_container (this, other, t); } + #if 0 // dwarf_output might use this (?) template inline compile_units (const input &units, tracker &t) diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index d8c7b9c56..4202fb16d 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -331,7 +331,7 @@ namespace elfutils template static inline value_dispatch * - make (flavor *&, const input &, const dwarf_data::nothing &) + make (flavor *&, const input &, const subr::nothing &) { throw std::logic_error ("dwarf_output cannot be default-constructed"); } @@ -366,7 +366,7 @@ namespace elfutils { friend class debug_info_entry; private: - children_type () {} + inline children_type () {} template inline children_type (const input &other, dwarf_output_collector &c) diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index b768abe70..02d95b381 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -784,6 +784,34 @@ namespace elfutils _m_tracker->abort (); } }; + + struct nothing + { + template + inline void operator () (args&&...) const {} + }; + + // Class instead of function so it can be a friend. + struct create_container + { + template + inline create_container (container *me, const input &other, + arg_type &arg, hook_type &hook = hook_type ()) + { + for (typename input::const_iterator in = other.begin (); + in != other.end (); + ++in) + { + /* Don't copy-construct the entry from *in here because that + copies it again into the list and destroys the first copy. */ + me->push_back (typename container::value_type ()); + typename container::iterator out = --me->end (); + out->set (*in, arg); + hook (out, in, arg); + } + } + }; }; };