]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
subrify some constructor magic.
authorRoland McGrath <roland@redhat.com>
Sat, 4 Jul 2009 09:03:38 +0000 (02:03 -0700)
committerRoland McGrath <roland@redhat.com>
Sat, 4 Jul 2009 09:03:38 +0000 (02:03 -0700)
libdw/c++/dwarf_data
libdw/c++/dwarf_edit
libdw/c++/dwarf_output
libdw/c++/subr.hh

index 8e765c5ed5c127da8ec2ddee60c834f2149acfaf..76a44e014c1816a74c990185310f769bdd096b4a 100644 (file)
@@ -669,8 +669,6 @@ namespace elfutils
     };
 
   public:
-    struct nothing {};
-
     template<typename impl>
     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<typename value, typename arg_type = const nothing>
+      template<typename value, typename arg_type = const subr::nothing>
       struct init
       {
        inline init (attr_value *av,
index da730623337b0c1f0e4cf0c61994f2cfb95631bf..40873e4b29da14a65f048eeee45994f6ac812cda 100644 (file)
@@ -105,6 +105,8 @@ namespace elfutils
 
     class debug_info_entry
     {
+      friend class subr::create_container;
+
     public:
 
       class children_type : public std::list<debug_info_entry>
@@ -113,20 +115,18 @@ namespace elfutils
       private:
         inline children_type () {}
 
+       template<typename input, typename tracker>
+       static inline void
+       equivalence (const iterator &out,
+                    const typename input::const_iterator &in, tracker &t)
+       {
+         t.equivalence (out, in);
+       }
+
        template<typename input, typename tracker>
        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<input, tracker>);
        }
 
       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<compile_unit>
     {
       friend class dwarf_edit;
+      friend class subr::create_container;
 
     private:
       typedef std::list<compile_unit> _base;
@@ -305,17 +307,9 @@ namespace elfutils
       template<typename input, typename tracker>
       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<typename input, typename tracker>
       inline compile_units (const input &units, tracker &t)
index d8c7b9c567a8520f3f6c40302a8bd63c9d7dcf2b..4202fb16d8bd557facfc30af7e1df9a7292f8ba0 100644 (file)
@@ -331,7 +331,7 @@ namespace elfutils
 
       template<typename flavor, typename input>
       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<typename input>
        inline children_type (const input &other, dwarf_output_collector &c)
index b768abe705a7d5282971383daab8f753d578b0a2..02d95b3811db5822ff44d8dcad988c94d1e39556 100644 (file)
@@ -784,6 +784,34 @@ namespace elfutils
          _m_tracker->abort ();
       }
     };
+
+    struct nothing
+    {
+      template<typename... args>
+      inline void operator () (args&&...) const {}
+    };
+
+    // Class instead of function so it can be a friend.
+    struct create_container
+    {
+      template<typename container, typename input, typename arg_type,
+              typename hook_type = const nothing>
+      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);
+           }
+       }
+    };
   };
 };