base: Replace the internal varargs stuff with C++11 constructs
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>
Tue, 26 Aug 2014 14:13:45 +0000 (10:13 -0400)
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>
Tue, 26 Aug 2014 14:13:45 +0000 (10:13 -0400)
We currently use our own home-baked support for type-safe variadic
functions. This is confusing and somewhat limited (e.g., cprintf only
supports a limited number of arguments). This changeset converts all
uses of our internal varargs support to use C++11 variadic macros.

src/arch/generic/debugfaults.hh
src/arch/x86/bios/intelmp.cc
src/base/cprintf.hh
src/base/misc.cc
src/base/misc.hh
src/base/trace.cc
src/base/trace.hh
src/base/varargs.hh [deleted file]

index c42f87c25204acedb15134785213cb58beaaae16..fcfdfb9e1dae99935817553991423c1da6f7c66e 100644 (file)
@@ -112,8 +112,9 @@ template <int Func>
 class M5VarArgsFault : public M5DebugFault
 {
   public:
-    M5VarArgsFault(const std::string &format, CPRINTF_DECLARATION) :
-        M5DebugFault((DebugFunc)Func, csprintf(format, VARARGS_ALLARGS))
+    template<typename ...Args>
+    M5VarArgsFault(const std::string &format, const Args &...args) :
+        M5DebugFault((DebugFunc)Func, csprintf(format, args...))
     {}
 };
 
index 645c51b3653ea43792ca6dace281e66ca852ea13..c907a63fe9cb8f5d5bfd381ec6a1b886ac072480 100644 (file)
@@ -92,7 +92,7 @@ writeOutString(PortProxy& proxy, Addr addr, string str, int length)
     if (str.length() > length) {
         memcpy(cleanedString, str.c_str(), length);
         warn("Intel MP configuration table string \"%s\" "
-                "will be truncated to \"%s\".\n", str, cleanedString);
+             "will be truncated to \"%s\".\n", str, (char *)&cleanedString);
     } else {
         memcpy(cleanedString, str.c_str(), str.length());
         memset(cleanedString + str.length(), 0, length - str.length());
index e702fa3a6ef06cc65301e0f51917e3f1895922c6..94a74728da6266407943259a89b70f078c68cfb5 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2014 ARM Limited
  * Copyright (c) 2002-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -27,6 +28,7 @@
  *
  * Authors: Nathan Binkert
  *          Steve Reinhardt
+ *          Andreas Sandberg
  */
 
 #ifndef __BASE_CPRINTF_HH__
 #include <string>
 
 #include "base/cprintf_formats.hh"
-#include "base/varargs.hh"
 
 namespace cp {
 
-#define CPRINTF_DECLARATION VARARGS_DECLARATION(cp::Print)
-#define CPRINTF_DEFINITION VARARGS_DEFINITION(cp::Print)
-
 struct Print
 {
   protected:
@@ -128,33 +126,42 @@ struct Print
 
 } // namespace cp
 
-typedef VarArgs::List<cp::Print> CPrintfArgsList;
-
 inline void
-ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
+ccprintf(cp::Print &print)
 {
-    cp::Print print(stream, format);
-    args.add_args(print);
+    print.end_args();
 }
 
-inline void
-ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
+
+template<typename T, typename ...Args> void
+ccprintf(cp::Print &print, const T &value, const Args &...args)
+{
+    print.add_arg(value);
+
+    ccprintf(print, args...);
+}
+
+
+template<typename ...Args> void
+ccprintf(std::ostream &stream, const char *format, const Args &...args)
 {
     cp::Print print(stream, format);
-    VARARGS_ADDARGS(print);
+
+    ccprintf(print, args...);
 }
 
-inline void
-cprintf(const char *format, CPRINTF_DECLARATION)
+
+template<typename ...Args> void
+cprintf(const char *format, const Args &...args)
 {
-    ccprintf(std::cout, format, VARARGS_ALLARGS);
+    ccprintf(std::cout, format, args...);
 }
 
-inline std::string
-csprintf(const char *format, CPRINTF_DECLARATION)
+template<typename ...Args> std::string
+csprintf(const char *format, const Args &...args)
 {
     std::stringstream stream;
-    ccprintf(stream, format, VARARGS_ALLARGS);
+    ccprintf(stream, format, args...);
     return stream.str();
 }
 
@@ -163,31 +170,22 @@ csprintf(const char *format, CPRINTF_DECLARATION)
  * time converting const char * to std::string since we don't take
  * advantage of it.
  */
-inline void
-ccprintf(std::ostream &stream, const std::string &format,
-         const CPrintfArgsList &args)
-{
-    ccprintf(stream, format.c_str(), args);
-}
-
-inline void
-ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
+template<typename ...Args> void
+ccprintf(std::ostream &stream, const std::string &format, const Args &...args)
 {
-    ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
+    ccprintf(stream, format.c_str(), args...);
 }
 
-inline void
-cprintf(const std::string &format, CPRINTF_DECLARATION)
+template<typename ...Args> void
+cprintf(const std::string &format, const Args &...args)
 {
-    ccprintf(std::cout, format.c_str(), VARARGS_ALLARGS);
+    ccprintf(std::cout, format.c_str(), args...);
 }
 
-inline std::string
-csprintf(const std::string &format, CPRINTF_DECLARATION)
+template<typename ...Args> std::string
+csprintf(const std::string &format, const Args &...args)
 {
-    std::stringstream stream;
-    ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
-    return stream.str();
+    return csprintf(format.c_str(), args...);
 }
 
 #endif // __CPRINTF_HH__
index 1a8b8ff1ece01513af7e85e7d28b4c4b12c15e7e..d95c2ff53951af9807a223a24a20ed23bda8c78f 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Nathan Binkert
+ *          Andreas Sandberg
  */
 
 #include <cstdlib>
-#include <iostream>
+#include <cstring>
 #include <string>
 
 #include "base/cprintf.hh"
@@ -38,7 +51,6 @@
 #include "base/output.hh"
 #include "base/trace.hh"
 #include "base/types.hh"
-#include "base/varargs.hh"
 #include "sim/core.hh"
 
 using namespace std;
@@ -51,34 +63,32 @@ bool warn_verbose = false;
 bool info_verbose = false;
 bool hack_verbose = false;
 
-void
-__exit_message(const char *prefix, int code,
-    const char *func, const char *file, int line,
-    const char *fmt, CPRINTF_DEFINITION)
+static void
+newline_if_needed(std::ostream &stream, const char *format)
 {
-    CPrintfArgsList args(VARARGS_ALLARGS);
+    const size_t format_len(strlen(format));
 
-    string format = prefix;
-    format += ": ";
-    format += fmt;
-    switch (format[format.size() - 1]) {
+    switch (format_len ? format[format_len - 1] : '\0') {
       case '\n':
       case '\r':
         break;
       default:
-        format += "\n";
+        stream << std::endl;
     }
+}
 
-    format += " @ tick %d\n[%s:%s, line %d]\n";
-    format += "Memory Usage: %ld KBytes\n";
-
-    args.push_back(curTick());
-    args.push_back(func);
-    args.push_back(file);
-    args.push_back(line);
-    args.push_back(memUsage());
+void
+__exit_epilogue(int code,
+                const char *func, const char *file, int line,
+                const char *format)
+{
+    newline_if_needed(std::cerr, format);
 
-    ccprintf(cerr, format.c_str(), args);
+    ccprintf(std::cerr,
+             " @ tick %d\n"
+             "[%s:%s, line %d]\n"
+             "Memory Usage: %ld KBytes\n",
+             curTick(), func, file, line, memUsage());
 
     if (code < 0)
         abort();
@@ -87,30 +97,14 @@ __exit_message(const char *prefix, int code,
 }
 
 void
-__base_message(std::ostream &stream, const char *prefix, bool verbose,
-    const char *func, const char *file, int line,
-    const char *fmt, CPRINTF_DEFINITION)
+__base_message_epilogue(std::ostream &stream, bool verbose,
+                        const char *func, const char *file, int line,
+                        const char *format)
 {
-    CPrintfArgsList args(VARARGS_ALLARGS);
-
-    string format = prefix;
-    format += ": ";
-    format += fmt;
-    switch (format[format.size() - 1]) {
-      case '\n':
-      case '\r':
-        break;
-      default:
-        format += "\n";
-    }
+    newline_if_needed(stream, format);
 
     if (verbose) {
-        format += " @ cycle %d\n[%s:%s, line %d]\n";
-        args.push_back(curTick());
-        args.push_back(func);
-        args.push_back(file);
-        args.push_back(line);
+        ccprintf(stream, " @ cycle %d\n[%s:%s, line %d]\n",
+                 curTick(), func, file, line);
     }
-
-    ccprintf(stream, format.c_str(), args);
 }
index de44dc3f57ee92357840f88f5b261c038dccdf46..23ecf736b5cc89c4a837032b57c4d43f593bc201 100644 (file)
  *
  * Authors: Nathan Binkert
  *          Dave Greene
+ *          Andreas Sandberg
  */
 
 #ifndef __BASE_MISC_HH__
 #define __BASE_MISC_HH__
 
+#include <iostream>
+
 #include "base/compiler.hh"
 #include "base/cprintf.hh"
-#include "base/varargs.hh"
 
 #if defined(__SUNPRO_CC)
 #define __FUNCTION__ "how to fix me?"
 #endif
 
+void __exit_epilogue(int code,
+                     const char *func, const char *file, int line,
+                     const char *format) M5_ATTR_NORETURN;
+
 // General exit message, these functions will never return and will
 // either abort() if code is < 0 or exit with the code if >= 0
-void __exit_message(const char *prefix, int code,
-    const char *func, const char *file, int line,
-    const char *format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+template<typename ...Args> void
+__exit_message(const char *prefix, int code,
+               const char *func, const char *file, int line,
+               const char *format, const Args &...args) M5_ATTR_NORETURN;
+template<typename ...Args> void
+__exit_message(const char *prefix, int code,
+               const char *func, const char *file, int line,
+               const std::string &format, const Args &...args) M5_ATTR_NORETURN;
+
+template<typename ...Args> void
+__exit_message(const char *prefix, int code,
+               const char *func, const char *file, int line,
+               const char *format, const Args &...args)
+{
+    std::cerr << prefix << ": ";
+    ccprintf(std::cerr, format, args...);
 
-void __exit_message(const char *prefix, int code,
-    const char *func, const char *file, int line,
-    const std::string &format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+    __exit_epilogue(code, func, file, line, format);
+}
 
-inline void
+template<typename ...Args> void
 __exit_message(const char *prefix, int code,
-    const char *func, const char *file, int line,
-    const std::string& format, CPRINTF_DEFINITION)
+               const char *func, const char *file, int line,
+               const std::string &format, const Args &...args)
 {
     __exit_message(prefix, code, func, file, line, format.c_str(),
-                   VARARGS_ALLARGS);
+                   args...);
 }
 
-#define exit_message(prefix, code, ...)                            \
-    __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
+#define exit_message(prefix, code, ...)                                 \
+    __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__,      \
                    __VA_ARGS__)
 
 //
@@ -125,17 +143,28 @@ __exit_message(const char *prefix, int code,
 
 
 void
+__base_message_epilogue(std::ostream &stream, bool verbose,
+                        const char *func, const char *file, int line,
+                        const char *format);
+
+template<typename ...Args> void
 __base_message(std::ostream &stream, const char *prefix, bool verbose,
-          const char *func, const char *file, int line,
-          const char *format, CPRINTF_DECLARATION);
+               const char *func, const char *file, int line,
+               const char *format, const Args &...args)
+{
+    stream << prefix << ": ";
+    ccprintf(stream, format, args...);
+
+    __base_message_epilogue(stream, verbose, func, file, line, format);
+}
 
-inline void
+template<typename ...Args> void
 __base_message(std::ostream &stream, const char *prefix, bool verbose,
-          const char *func, const char *file, int line,
-          const std::string &format, CPRINTF_DECLARATION)
+               const char *func, const char *file, int line,
+               const std::string &format, const Args &...args)
 {
     __base_message(stream, prefix, verbose, func, file, line, format.c_str(),
-              VARARGS_ALLARGS);
+                   args...);
 }
 
 #define base_message(stream, prefix, verbose, ...)                      \
index fa55e42a9008fe4a62a77a648f59dff0ab529c23..00a4c3e6b887aeb487d8906d05340295216ae313 100644 (file)
@@ -38,7 +38,6 @@
 #include "base/output.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
-#include "base/varargs.hh"
 
 using namespace std;
 
@@ -70,59 +69,35 @@ setOutput(const string &filename)
 
 ObjectMatch ignore;
 
-void
-dprintf(Tick when, const std::string &name, const char *format,
-        CPRINTF_DEFINITION)
+
+bool
+__dprintf_prologue(Tick when, const std::string &name)
 {
     if (!name.empty() && ignore.match(name))
-        return;
+        return false;
 
     std::ostream &os = *dprintf_stream;
 
-    string fmt = "";
-    CPrintfArgsList args(VARARGS_ALLARGS);
+    if (when != MaxTick)
+        ccprintf(os, "%7d: ", when);
 
-    if (!name.empty()) {
-        fmt = "%s: " + fmt;
-        args.push_front(name);
-    }
-
-    if (when != (Tick)-1) {
-        fmt = "%7d: " + fmt;
-        args.push_front(when);
-    }
+    if (!name.empty())
+        os << name << ": ";
 
-    fmt += format;
-
-    ccprintf(os, fmt.c_str(), args);
-    os.flush();
+    return true;
 }
 
 void
 dump(Tick when, const std::string &name, const void *d, int len)
 {
-    if (!name.empty() && ignore.match(name))
-        return;
-
-    std::ostream &os = *dprintf_stream;
-
-    string fmt = "";
-    CPrintfArgsList args;
-
-    if (!name.empty()) {
-        fmt = "%s: " + fmt;
-        args.push_front(name);
-    }
-
-    if (when != (Tick)-1) {
-        fmt = "%7d: " + fmt;
-        args.push_front(when);
-    }
-
     const char *data = static_cast<const char *>(d);
+    std::ostream &os = *dprintf_stream;
     int c, i, j;
+
     for (i = 0; i < len; i += 16) {
-        ccprintf(os, fmt, args);
+        if (!__dprintf_prologue(when, name))
+            return;
+
         ccprintf(os, "%08x  ", i);
         c = len - i;
         if (c > 16) c = 16;
index eb0ab9daecd3c1ae4e45839778f2fca74d3c03ee..3e6e37bd3aee302bff45fef14b150c46811e065c 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2001-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -55,8 +67,20 @@ void dumpStatus();
 extern ObjectMatch ignore;
 extern const std::string DefaultName;
 
-void dprintf(Tick when, const std::string &name, const char *format,
-             CPRINTF_DECLARATION);
+bool __dprintf_prologue(Tick when, const std::string &name);
+
+template<typename ...Args> void
+dprintf(Tick when, const std::string &name, const char *format,
+        const Args &...args)
+{
+    if (!__dprintf_prologue(when, name))
+        return;
+
+    std::ostream &os(output());
+    ccprintf(os, format, args...);
+    os.flush();
+}
+
 void dump(Tick when, const std::string &name, const void *data, int len);
 
 } // namespace Trace
diff --git a/src/base/varargs.hh b/src/base/varargs.hh
deleted file mode 100644 (file)
index 87c98d0..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Nathan Binkert
- */
-
-#ifndef __BASE_VARARGS_HH__
-#define __BASE_VARARGS_HH__
-
-#include "base/refcnt.hh"
-
-#define VARARGS_DECLARATION(receiver)                  \
-    VarArgs::Argument<receiver> a01 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a02 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a03 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a04 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a05 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a06 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a07 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a08 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a09 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a10 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a11 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a12 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a13 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a14 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a15 = VarArgs::Null(), \
-    VarArgs::Argument<receiver> a16 = VarArgs::Null()
-
-#define VARARGS_DEFINITION(receiver) \
-    VarArgs::Argument<receiver> a01, \
-    VarArgs::Argument<receiver> a02, \
-    VarArgs::Argument<receiver> a03, \
-    VarArgs::Argument<receiver> a04, \
-    VarArgs::Argument<receiver> a05, \
-    VarArgs::Argument<receiver> a06, \
-    VarArgs::Argument<receiver> a07, \
-    VarArgs::Argument<receiver> a08, \
-    VarArgs::Argument<receiver> a09, \
-    VarArgs::Argument<receiver> a10, \
-    VarArgs::Argument<receiver> a11, \
-    VarArgs::Argument<receiver> a12, \
-    VarArgs::Argument<receiver> a13, \
-    VarArgs::Argument<receiver> a14, \
-    VarArgs::Argument<receiver> a15, \
-    VarArgs::Argument<receiver> a16
-
-#define VARARGS_ALLARGS                     \
-    a01, a02, a03, a04, a05, a06, a07, a08, \
-    a09, a10, a11, a12, a13, a14, a15, a16
-
-#define VARARGS_ADDARGS(receiver) do { \
-    do {                           \
-        if (!a01) break;           \
-        a01.add_arg(receiver);     \
-        if (!a02) break;           \
-        a02.add_arg(receiver);     \
-        if (!a03) break;           \
-        a03.add_arg(receiver);     \
-        if (!a04) break;           \
-        a04.add_arg(receiver);     \
-        if (!a05) break;           \
-        a05.add_arg(receiver);     \
-        if (!a06) break;           \
-        a06.add_arg(receiver);     \
-        if (!a07) break;           \
-        a07.add_arg(receiver);     \
-        if (!a08) break;           \
-        a08.add_arg(receiver);     \
-        if (!a09) break;           \
-        a09.add_arg(receiver);     \
-        if (!a10) break;           \
-        a10.add_arg(receiver);     \
-        if (!a11) break;           \
-        a11.add_arg(receiver);     \
-        if (!a12) break;           \
-        a12.add_arg(receiver);     \
-        if (!a13) break;           \
-        a13.add_arg(receiver);     \
-        if (!a14) break;           \
-        a14.add_arg(receiver);     \
-        if (!a15) break;           \
-        a15.add_arg(receiver);     \
-        if (!a16) break;           \
-        a16.add_arg(receiver);     \
-    } while (0);                   \
-    receiver.end_args();           \
-} while (0)
-
-namespace VarArgs {
-
-struct Null {};
-
-template <typename T>
-struct Traits
-{
-    enum { enabled = true };
-};
-
-template <>
-struct Traits<Null>
-{
-    enum { enabled = false };
-};
-
-template <class RECV>
-struct Base : public RefCounted
-{
-    virtual void add_arg(RECV &receiver) const = 0;
-};
-
-template <typename T, class RECV>
-struct Any : public Base<RECV>
-{
-    const T &argument;
-
-    Any(const T &arg) : argument(arg) {}
-
-    virtual void
-    add_arg(RECV &receiver) const
-    {
-        receiver.add_arg(argument);
-    }
-};
-
-template <typename T, class RECV>
-struct Any<T *, RECV> : public Base<RECV>
-{
-    const T *argument;
-
-    Any(const T *arg) : argument(arg) {}
-
-    virtual void
-    add_arg(RECV &receiver) const
-    {
-        receiver.add_arg(argument);
-    }
-};
-
-template <class RECV>
-struct Argument : public RefCountingPtr<Base<RECV> >
-{
-    typedef RefCountingPtr<VarArgs::Base<RECV> > Base;
-
-    Argument() { }
-    Argument(const Null &null) { }
-    template <typename T>
-    Argument(const T& arg) : Base(new Any<T, RECV>(arg)) { }
-    template <typename T>
-    Argument(const T* arg) : Base(new Any<T *, RECV>(arg)) { }
-
-    void
-    add_arg(RECV &receiver) const
-    {
-        if (this->data)
-            this->data->add_arg(receiver);
-    }
-};
-
-template<class RECV>
-class List
-{
-  public:
-    typedef VarArgs::Argument<RECV> Argument;
-    typedef std::list<Argument> list;
-    typedef typename list::iterator iterator;
-    typedef typename list::const_iterator const_iterator;
-    typedef typename list::size_type size_type;
-
-  protected:
-    list l;
-
-  public:
-    List() {}
-    List(Argument a01, Argument a02, Argument a03, Argument a04,
-         Argument a05, Argument a06, Argument a07, Argument a08,
-         Argument a09, Argument a10, Argument a11, Argument a12,
-         Argument a13, Argument a14, Argument a15, Argument a16)
-    {
-        if (!a01) return;
-        l.push_back(a01);
-        if (!a02) return;
-        l.push_back(a02);
-        if (!a03) return;
-        l.push_back(a03);
-        if (!a04) return;
-        l.push_back(a04);
-        if (!a05) return;
-        l.push_back(a05);
-        if (!a06) return;
-        l.push_back(a06);
-        if (!a07) return;
-        l.push_back(a07);
-        if (!a08) return;
-        l.push_back(a08);
-        if (!a09) return;
-        l.push_back(a09);
-        if (!a10) return;
-        l.push_back(a10);
-        if (!a11) return;
-        l.push_back(a11);
-        if (!a12) return;
-        l.push_back(a12);
-        if (!a13) return;
-        l.push_back(a13);
-        if (!a14) return;
-        l.push_back(a14);
-        if (!a15) return;
-        l.push_back(a15);
-        if (!a16) return;
-        l.push_back(a16);
-    }
-
-    size_type size() const { return l.size(); }
-    bool empty() const { return l.empty(); }
-
-    iterator begin() { return l.begin(); }
-    const_iterator begin() const { return l.begin(); }
-
-    iterator end() { return l.end(); }
-    const_iterator end() const { return l.end(); }
-
-    void
-    push_back(const Argument &arg)
-    {
-        if (arg)
-            l.push_back(arg);
-    }
-
-    void
-    push_front(const Argument &arg)
-    {
-        if (arg)
-            l.push_front(arg);
-    }
-
-    template <typename T>
-    void
-    push_back(const T &arg)
-    {
-        if (Traits<T>::enabled)
-            l.push_back(arg);
-    }
-
-    template <typename T>
-    void
-    push_front(const T &arg)
-    {
-        if (Traits<T>::enabled)
-            l.push_front(arg);
-    }
-
-    Argument& front() { return l.front(); }
-    const Argument& front() const { return l.front(); }
-    Argument& back() { return l.back(); }
-    const Argument& back() const { return l.back(); }
-
-    void erase(iterator position) { return l.erase(position); }
-    void erase(iterator first, iterator last) { return l.erase(first, last); }
-    void clear() { return l.clear(); }
-    void pop_front() { return l.pop_front(); }
-    void pop_back() { return l.pop_back(); }
-    void reverse() { l.reverse(); }
-
-    /*
-     * Functions specific to variable arguments
-     */
-    void
-    add_args(RECV &recv) const
-    {
-        const_iterator i = l.begin();
-        const_iterator end = l.end();
-        while (i != end) {
-            i->add_arg(recv);
-            ++i;
-        }
-
-        recv.end_args();
-    }
-};
-
-} // namespace VarArgs
-
-#endif /* __BASE_VARARGS_HH__ */