[Ns-developers] [ns3] wrapper classes in the Attributes API

Raj Bhattacharjea raj.b at gatech.edu
Tue May 20 15:44:49 PDT 2008


Looking through the ns-3 point-to-point examples, I found many lines
like the following:

p2p.SetChannelParameter ("BitRate", StringValue ("1500kbps"));
p2p.SetChannelParameter ("Delay", StringValue ("10ms"));
OR my favorite
p2p.SetChannelParameter ("BitRate", DataRateValue (DataRate(100000)));

Initially, my main question was "are these wrappers really
necessary?".  In thinking about how such an API came about, it's
obvious that these APIs that take a wrapper class instance as a
parameter are generic enough to work with many different classes, and
so they need a way to differentiate exactly what beast is being passed
in, and possibly behave differently for each type that can be passed
in.  Using polymorphism and inheritance is one way to do so, and
indeed all of the *Value classes are subclasses of the AttributeValue
class.  BUT this looks really redundant, especially in the latter case
of DataRateValue (DataRate(100000)).  I beleive there is a good c++
alternative, but more on that later.

So, redundancy notwithstanding, if you look at just where classes like
 StringValue and DataRateValue are defined, you might be a little
puzzled...it appears that there are no lines of code in any file that
reads "class StringValue" or "class DataRateValue".  That is, there is
no class declaration to be found...and that's because of this fact
which makes me shudder, both of these classes (as well as the majority
of the wrapper classes, primitives not withstanding) ARE GENERATED BY
MACROS.  I'm not trying to flame here, but the file attribute-helper.h
is an abomination that defines macros which are intended to take a
typename, and abuse the preprocessor and its ## concatenation operator
to generate a wrapper class for that type (i.e. class
typename##Value).

The problem this code tries to solve is to have a convenient way to
autogenerate some classes which are similar enough that a
find-and-replace on a single typename is all they need to
differentiate them.  Were we writing in c, I could see where perhaps
we had no choice in the matter, but in c++ WE HAVE TEMPLATES.

I really think the whole of the attributes design needs a reworking
with templates.  The main upside is readability and "good" design
instead of what seems to be a series of ugly hacks and c++ abuses.

To be clear then, all of the AttributeValue subclasses could then be
template instantiations/specializations instead of some being of
macro-created, and all the APIs which take an AttributeValue as a
parameter could be templated with the type.  I'm envisioning the
current AttributeValue class to be renamed to AttributeValueBase, with
subclasses AttributeValue<T>, and APIs like AddAttribute and the
helper APIs maybe looking like the following:

p2p.SetChannelParameter<DataRate>("BitRate", "1500kbps");
TypeId ("ns3::RajClass").AddAttribute<bool> ("TrueFalse", "help", false, ...);

The "checker" and "accessor" classes are also similarly
macro-generated, and although I didn't look into the details, I
suspect they could be refactored with a templated design as well.

-- 
Raj Bhattacharjea
Georgia Institute of Technology
School of Electrical and Computer Engineering
Systems Analyst
404.894.2955


More information about the Ns-developers mailing list