base: Replace the internal varargs stuff with C++11 constructs
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.
This commit is contained in:
@@ -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...))
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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__
|
||||
@@ -38,13 +40,9 @@
|
||||
#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)
|
||||
{
|
||||
print.end_args();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
args.add_args(print);
|
||||
|
||||
ccprintf(print, args...);
|
||||
}
|
||||
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
|
||||
|
||||
template<typename ...Args> void
|
||||
cprintf(const char *format, const Args &...args)
|
||||
{
|
||||
cp::Print print(stream, format);
|
||||
VARARGS_ADDARGS(print);
|
||||
ccprintf(std::cout, format, args...);
|
||||
}
|
||||
|
||||
inline void
|
||||
cprintf(const char *format, CPRINTF_DECLARATION)
|
||||
{
|
||||
ccprintf(std::cout, format, VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
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)
|
||||
template<typename ...Args> void
|
||||
ccprintf(std::ostream &stream, const std::string &format, const Args &...args)
|
||||
{
|
||||
ccprintf(stream, format.c_str(), args);
|
||||
ccprintf(stream, format.c_str(), args...);
|
||||
}
|
||||
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
|
||||
template<typename ...Args> void
|
||||
cprintf(const std::string &format, const Args &...args)
|
||||
{
|
||||
ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
|
||||
ccprintf(std::cout, format.c_str(), args...);
|
||||
}
|
||||
|
||||
inline void
|
||||
cprintf(const std::string &format, CPRINTF_DECLARATION)
|
||||
template<typename ...Args> std::string
|
||||
csprintf(const std::string &format, const Args &...args)
|
||||
{
|
||||
ccprintf(std::cout, format.c_str(), VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
csprintf(const std::string &format, CPRINTF_DECLARATION)
|
||||
{
|
||||
std::stringstream stream;
|
||||
ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
|
||||
return stream.str();
|
||||
return csprintf(format.c_str(), args...);
|
||||
}
|
||||
|
||||
#endif // __CPRINTF_HH__
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -26,10 +38,11 @@
|
||||
* 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";
|
||||
void
|
||||
__exit_epilogue(int code,
|
||||
const char *func, const char *file, int line,
|
||||
const char *format)
|
||||
{
|
||||
newline_if_needed(std::cerr, format);
|
||||
|
||||
args.push_back(curTick());
|
||||
args.push_back(func);
|
||||
args.push_back(file);
|
||||
args.push_back(line);
|
||||
args.push_back(memUsage());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -39,40 +39,58 @@
|
||||
*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
|
||||
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 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)
|
||||
{
|
||||
__exit_message(prefix, code, func, file, line, format.c_str(),
|
||||
VARARGS_ALLARGS);
|
||||
std::cerr << prefix << ": ";
|
||||
ccprintf(std::cerr, format, args...);
|
||||
|
||||
__exit_epilogue(code, func, file, line, format);
|
||||
}
|
||||
|
||||
#define exit_message(prefix, code, ...) \
|
||||
__exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
|
||||
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)
|
||||
{
|
||||
__exit_message(prefix, code, func, file, line, format.c_str(),
|
||||
args...);
|
||||
}
|
||||
|
||||
#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(std::ostream &stream, const char *prefix, bool verbose,
|
||||
const char *func, const char *file, int line,
|
||||
const char *format, CPRINTF_DECLARATION);
|
||||
__base_message_epilogue(std::ostream &stream, bool verbose,
|
||||
const char *func, const char *file, int line,
|
||||
const char *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 char *format, const Args &...args)
|
||||
{
|
||||
stream << prefix << ": ";
|
||||
ccprintf(stream, format, args...);
|
||||
|
||||
__base_message_epilogue(stream, verbose, func, file, line, format);
|
||||
}
|
||||
|
||||
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, const Args &...args)
|
||||
{
|
||||
__base_message(stream, prefix, verbose, func, file, line, format.c_str(),
|
||||
VARARGS_ALLARGS);
|
||||
args...);
|
||||
}
|
||||
|
||||
#define base_message(stream, prefix, verbose, ...) \
|
||||
|
||||
@@ -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 (!name.empty())
|
||||
os << name << ": ";
|
||||
|
||||
if (when != (Tick)-1) {
|
||||
fmt = "%7d: " + fmt;
|
||||
args.push_front(when);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
Reference in New Issue
Block a user