From 1f834b569c8a39f44882c2f2010a9f0ecffdaab1 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 7 Feb 2007 22:11:30 -0800 Subject: Get rid of the gross operator,()/variadic macro hack that made ccprintf and friends work, turn it into a normal function (though it still has a slightly strange implementation.) All instances of variadic macros are not yet removed, but I know how, and it will happen. One side effect of this new implementation is that a cprintf statement can now only have 16 parameters, though it's easy enough to raise this number if needed. --HG-- extra : convert_revision : 85cb3c17f8e2ecf9cd2f31ea80a760a28ea127a7 --- src/base/varargs.hh | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 src/base/varargs.hh (limited to 'src/base/varargs.hh') diff --git a/src/base/varargs.hh b/src/base/varargs.hh new file mode 100644 index 000000000..2ba8c240a --- /dev/null +++ b/src/base/varargs.hh @@ -0,0 +1,292 @@ +/* + * 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 a01 = VarArgs::Null(), \ + VarArgs::Argument a02 = VarArgs::Null(), \ + VarArgs::Argument a03 = VarArgs::Null(), \ + VarArgs::Argument a04 = VarArgs::Null(), \ + VarArgs::Argument a05 = VarArgs::Null(), \ + VarArgs::Argument a06 = VarArgs::Null(), \ + VarArgs::Argument a07 = VarArgs::Null(), \ + VarArgs::Argument a08 = VarArgs::Null(), \ + VarArgs::Argument a09 = VarArgs::Null(), \ + VarArgs::Argument a10 = VarArgs::Null(), \ + VarArgs::Argument a11 = VarArgs::Null(), \ + VarArgs::Argument a12 = VarArgs::Null(), \ + VarArgs::Argument a13 = VarArgs::Null(), \ + VarArgs::Argument a14 = VarArgs::Null(), \ + VarArgs::Argument a15 = VarArgs::Null(), \ + VarArgs::Argument a16 = VarArgs::Null() + +#define VARARGS_DEFINITION(receiver) \ + VarArgs::Argument a01, \ + VarArgs::Argument a02, \ + VarArgs::Argument a03, \ + VarArgs::Argument a04, \ + VarArgs::Argument a05, \ + VarArgs::Argument a06, \ + VarArgs::Argument a07, \ + VarArgs::Argument a08, \ + VarArgs::Argument a09, \ + VarArgs::Argument a10, \ + VarArgs::Argument a11, \ + VarArgs::Argument a12, \ + VarArgs::Argument a13, \ + VarArgs::Argument a14, \ + VarArgs::Argument a15, \ + VarArgs::Argument 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 +struct Traits +{ + enum { enabled = true }; +}; + +template <> +struct Traits +{ + enum { enabled = false }; +}; + +template +struct Base : public RefCounted +{ + virtual void add_arg(RECV &receiver) const = 0; +}; + +template +struct Any : public Base +{ + const T &argument; + + Any(const T &arg) : argument(arg) {} + + virtual void + add_arg(RECV &receiver) const + { + receiver.add_arg(argument); + } +}; + +template +struct Argument : public RefCountingPtr > +{ + typedef RefCountingPtr > Base; + + Argument() { } + Argument(const Null &null) { } + template + Argument(const T& arg) : Base(new Any(arg)) { } + + void + add_arg(RECV &receiver) const + { + if (this->data) + this->data->add_arg(receiver); + } +}; + +template +class List +{ + public: + typedef Argument Argument; + typedef std::list 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 + void + push_back(const T &arg) + { + if (Traits::enabled) + l.push_back(arg); + } + + template + void + push_front(const T &arg) + { + if (Traits::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(); + } +}; + +/* end namespace VarArgs */ } + +#endif /* __BASE_VARARGS_HH__ */ -- cgit v1.2.3