622 lines
16 KiB
C++
622 lines
16 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/*
|
|
* Copyright (c) 2007 INRIA
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation;
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
|
*/
|
|
#ifndef DEFAULT_VALUE_H
|
|
#define DEFAULT_VALUE_H
|
|
|
|
#include <string>
|
|
#include <list>
|
|
#include "callback.h"
|
|
|
|
/**
|
|
* \ingroup core
|
|
* \defgroup config Simulation configuration
|
|
*
|
|
*/
|
|
|
|
namespace ns3 {
|
|
|
|
namespace DefaultValue
|
|
{
|
|
|
|
/**
|
|
* \ingroup config
|
|
* \param name name of variable to bind
|
|
* \param value value to bind to the specified variable
|
|
*
|
|
* If the variable name does not match any existing
|
|
* variable or if the value is not compatible with
|
|
* the variable type, this function will abort
|
|
* at runtime and print an error message detailing
|
|
* which variable or value triggered the problem.
|
|
*/
|
|
void Bind (std::string name, std::string value);
|
|
|
|
}
|
|
|
|
|
|
class DefaultValueBase
|
|
{
|
|
public:
|
|
virtual ~DefaultValueBase ();
|
|
std::string GetName (void) const;
|
|
std::string GetHelp (void) const;
|
|
|
|
/**
|
|
* \returns true if this value is dirty, false otherwise.
|
|
*
|
|
* A value becomes dirty when ParseValue is invoked
|
|
* and it successfully completes. Dirtyness indicates
|
|
* that the state of the value was changed by a user.
|
|
*/
|
|
bool IsDirty (void) const;
|
|
/**
|
|
* Clear the dirty state.
|
|
*/
|
|
void ClearDirtyFlag (void);
|
|
// parse a matching parameter
|
|
// return true in case of success, false otherwise.
|
|
bool ParseValue (const std::string &value);
|
|
std::string GetType (void) const;
|
|
std::string GetDefaultValue (void) const;
|
|
protected:
|
|
DefaultValueBase (const std::string &name,
|
|
const std::string &help);
|
|
private:
|
|
DefaultValueBase ();
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value) = 0;
|
|
virtual std::string DoGetType (void) const = 0;
|
|
virtual std::string DoGetDefaultValue (void) const = 0;
|
|
std::string m_name;
|
|
std::string m_help;
|
|
bool m_dirty;
|
|
};
|
|
|
|
class DefaultValueList
|
|
{
|
|
public:
|
|
typedef std::list<DefaultValueBase *>::iterator Iterator;
|
|
|
|
static Iterator Begin (void);
|
|
static Iterator End (void);
|
|
static void Remove (const std::string &name);
|
|
static void Add (DefaultValueBase *defaultValue);
|
|
|
|
template <typename T>
|
|
static const T* Get (const std::string &name)
|
|
{
|
|
for (Iterator iter = Begin (); iter != End (); iter++)
|
|
{
|
|
const DefaultValueBase *value = *iter;
|
|
if (value->GetName () == name)
|
|
{
|
|
return dynamic_cast<const T*> (value);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
private:
|
|
typedef std::list<DefaultValueBase *> List;
|
|
static List *GetList (void);
|
|
};
|
|
|
|
/**
|
|
* \brief A Boolean variable for ns3::Bind
|
|
* \ingroup config
|
|
*
|
|
* Every instance of this type is automatically
|
|
* registered in the variable pool which is used
|
|
* by ns3::Bind.
|
|
*/
|
|
class BooleanDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
/**
|
|
* \param name name of variable
|
|
* \param help help text which explains the purpose
|
|
* and the semantics of this variable
|
|
* \param defaultValue the default value to assign
|
|
* to this variable.
|
|
*
|
|
* Unless the user invokes ns3::Bind with the right arguments,
|
|
* the GetValue method will return the default value. Otherwise,
|
|
* it will return the user-specified value.
|
|
*/
|
|
BooleanDefaultValue (std::string name,
|
|
std::string help,
|
|
bool defaultValue);
|
|
/**
|
|
* \returns the default value for this variable or a
|
|
* user-provided overriden variable.
|
|
*/
|
|
bool GetValue (void) const;
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
bool m_defaultValue;
|
|
bool m_value;
|
|
};
|
|
|
|
/**
|
|
* \brief A Numeric variable for ns3::Bind
|
|
* \ingroup config
|
|
*
|
|
* Every instance of this type is automatically
|
|
* registered in the variable pool which is used
|
|
* by ns3::Bind.
|
|
*/
|
|
template <typename T>
|
|
class NumericDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
/**
|
|
* \param name the name of the variable
|
|
* \param help help text which explains the purpose
|
|
* and the semantics of this variable
|
|
* \param defaultValue the default value assigned
|
|
* to this variable
|
|
*
|
|
* By default, the set of allowed values is the entire range
|
|
* of values which can be stored and retrieved from the underlying
|
|
* type.
|
|
*/
|
|
NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue);
|
|
/**
|
|
* \param name the name of the variable
|
|
* \param help help text which explains the purpose
|
|
* and the semantics of this variable
|
|
* \param defaultValue the default value assigned to this
|
|
* variable
|
|
* \param minValue the minimum value which can be set
|
|
* in this variable
|
|
*/
|
|
NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue,
|
|
T minValue);
|
|
|
|
/**
|
|
* \param name the name of the variable
|
|
* \param help help text which explains the purpose
|
|
* and the semantics of this variable
|
|
* \param defaultValue the default value assigned to this
|
|
* variable
|
|
* \param minValue the minimum value which can be set
|
|
* in this variable
|
|
* \param maxValue the maximum value which can be set in this
|
|
* variable.
|
|
*/
|
|
NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue,
|
|
T minValue,
|
|
T maxValue);
|
|
|
|
void SetValue (T v);
|
|
|
|
T GetValue (void) const;
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
T RealMin (void) const;
|
|
T m_defaultValue;
|
|
T m_minValue;
|
|
T m_maxValue;
|
|
T m_value;
|
|
};
|
|
|
|
/**
|
|
* \brief Named enumeration defaults
|
|
* \ingroup config
|
|
*
|
|
* Every instance of this type is automatically
|
|
* registered in the variable pool which is used
|
|
* by ns3::Bind.
|
|
*/
|
|
class StringEnumDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
/**
|
|
* \param name The name of the variable
|
|
* \param help The help string
|
|
*/
|
|
StringEnumDefaultValue (const std::string &name,
|
|
const std::string &help);
|
|
/**
|
|
* \brief Add a default value to this enumeration of strings
|
|
* \param value The string to make the default for this
|
|
*/
|
|
void AddDefaultValue (const std::string &value);
|
|
/**
|
|
* \brief Add a possible value to accept for this default value
|
|
*/
|
|
void AddPossibleValue (const std::string &value);
|
|
/**
|
|
* \brief Get the value of this default value.
|
|
* \return The string that has been assigned to this default value, either by
|
|
* Bind() or by a command line setting
|
|
*/
|
|
std::string GetValue (void) const;
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
|
|
bool m_oneDefault;
|
|
std::list<std::string> m_possibleValues;
|
|
std::string m_defaultValue;
|
|
std::string m_value;
|
|
};
|
|
|
|
/**
|
|
* \brief An enum variable for ns3::Bind
|
|
* \ingroup config
|
|
*
|
|
* Every instance of this type is automatically
|
|
* registered in the variable pool which is used
|
|
* by ns3::Bind.
|
|
*/
|
|
template <typename T>
|
|
class EnumDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
/**
|
|
* \param name the name of this variable
|
|
* \param help help text which explains the purpose
|
|
* and the semantics of this variable
|
|
* \param defaultValue the default value assigned to this
|
|
* variable unless it is overriden with ns3::Bind
|
|
* \param defaultValueString the string which represents
|
|
* the default value which should be used by ns3::Bind
|
|
*
|
|
* This method takes a variable number of arguments. The list of
|
|
* arguments is terminated by the pair of values 0 and (void *)0.
|
|
* Each pair of extra argument is assumed to be of the form
|
|
* (enum value, string representing enum value). If ns3::Bind
|
|
* is invoked on this variable, it will check that the user-provided
|
|
* values are within the set of values specified in this constructor.
|
|
*
|
|
* Typical useage of this method will look like this:
|
|
* \code
|
|
* enum MyEnum {
|
|
* MY_ENUM_A,
|
|
* MY_ENUM_B,
|
|
* MY_ENUM_C,
|
|
* };
|
|
* // set default value to be "B".
|
|
* static EnumDefaultValue<enum MyEnum>
|
|
* g_myDefaultValue ("my", "my help",
|
|
* MY_ENUM_B, "B",
|
|
* MY_ENUM_A, "A",
|
|
* MY_ENUM_C, "C",);
|
|
* 0, (void*)0);
|
|
* \endcode
|
|
* Note that to ensure portability to 64 bit systems, make sure that
|
|
* the last element in the variable list of arguments is (void *)0.
|
|
*/
|
|
EnumDefaultValue (const std::string &name, const std::string &help,
|
|
T defaultValue, const char *defaultValueString,
|
|
...);
|
|
void AddPossibleValue (T value, const std::string &valueString);
|
|
/**
|
|
* \returns the default value or any other value specified by the
|
|
* user with ns3::Bind
|
|
*/
|
|
T GetValue (void);
|
|
/**
|
|
* \param value the new default value.
|
|
*/
|
|
void SetValue (T value);
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
|
|
typedef std::list<std::pair<T,std::string> > PossibleValues;
|
|
|
|
T m_defaultValue;
|
|
PossibleValues m_possibleValues;
|
|
T m_value;
|
|
};
|
|
|
|
/**
|
|
* \brief A string variable for ns3::Bind
|
|
* \ingroup config
|
|
*
|
|
* Every instance of this type is automatically
|
|
* registered in the variable pool which is used
|
|
* by ns3::Bind.
|
|
*/
|
|
class StringDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
StringDefaultValue (const std::string &name,
|
|
const std::string &help,
|
|
const std::string defaultValue);
|
|
StringDefaultValue (const std::string &name,
|
|
const std::string &help,
|
|
const std::string defaultValue,
|
|
int maxSize);
|
|
StringDefaultValue (const std::string &name,
|
|
const std::string &help,
|
|
const std::string defaultValue,
|
|
int minSize,
|
|
int maxSize);
|
|
|
|
std::string GetValue (void) const;
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
|
|
std::string m_defaultValue;
|
|
std::string m_value;
|
|
int m_minSize;
|
|
int m_maxSize;
|
|
};
|
|
|
|
/**
|
|
* \brief Class used to call a certain function during the configuration of the
|
|
* simulation
|
|
* \ingroup config
|
|
*/
|
|
class CommandDefaultValue : public DefaultValueBase
|
|
{
|
|
public:
|
|
CommandDefaultValue (const std::string &name,
|
|
const std::string &help,
|
|
Callback<void> cb);
|
|
private:
|
|
virtual bool DoParseValue (const std::string &value);
|
|
virtual std::string DoGetType (void) const;
|
|
virtual std::string DoGetDefaultValue (void) const;
|
|
Callback<void> m_cb;
|
|
};
|
|
|
|
}//namespace ns3
|
|
|
|
#include "type-name.h"
|
|
#include "assert.h"
|
|
#include <sstream>
|
|
#include <stdarg.h>
|
|
#include <limits>
|
|
|
|
namespace ns3 {
|
|
|
|
/**************************************************************
|
|
**************************************************************/
|
|
|
|
|
|
template <typename T>
|
|
NumericDefaultValue<T>::NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue)
|
|
: DefaultValueBase (name, help),
|
|
m_defaultValue (defaultValue),
|
|
m_minValue (RealMin ()),
|
|
m_maxValue (std::numeric_limits<T>::max ()),
|
|
m_value (defaultValue)
|
|
{
|
|
DefaultValueList::Add (this);
|
|
NS_ASSERT (m_minValue < m_maxValue);
|
|
}
|
|
template <typename T>
|
|
NumericDefaultValue<T>::NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue,
|
|
T minValue)
|
|
: DefaultValueBase (name, help),
|
|
m_defaultValue (defaultValue),
|
|
m_minValue (minValue),
|
|
m_maxValue (std::numeric_limits<T>::max ()),
|
|
m_value (defaultValue)
|
|
{
|
|
DefaultValueList::Add (this);
|
|
NS_ASSERT (m_minValue < m_maxValue);
|
|
NS_ASSERT (m_defaultValue <= m_maxValue &&
|
|
m_defaultValue >= m_minValue);
|
|
}
|
|
template <typename T>
|
|
NumericDefaultValue<T>::NumericDefaultValue (std::string name,
|
|
std::string help,
|
|
T defaultValue,
|
|
T minValue,
|
|
T maxValue)
|
|
: DefaultValueBase (name, help),
|
|
m_defaultValue (defaultValue),
|
|
m_minValue (minValue),
|
|
m_maxValue (maxValue),
|
|
m_value (defaultValue)
|
|
{
|
|
DefaultValueList::Add (this);
|
|
NS_ASSERT (m_minValue < m_maxValue);
|
|
NS_ASSERT (m_defaultValue <= m_maxValue &&
|
|
m_defaultValue >= m_minValue);
|
|
}
|
|
|
|
template <typename T>
|
|
void
|
|
NumericDefaultValue<T>::SetValue (T v)
|
|
{
|
|
NS_ASSERT (v <= m_maxValue &&
|
|
v >= m_minValue);
|
|
m_value = v;
|
|
}
|
|
|
|
template <typename T>
|
|
T
|
|
NumericDefaultValue<T>::GetValue (void) const
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
template <typename T>
|
|
bool
|
|
NumericDefaultValue<T>::DoParseValue (const std::string &value)
|
|
{
|
|
std::istringstream iss;
|
|
iss.str (value);
|
|
iss >> m_value;
|
|
if (m_value > m_maxValue ||
|
|
m_value < m_minValue)
|
|
{
|
|
return false;
|
|
}
|
|
return !iss.bad () && !iss.fail ();
|
|
}
|
|
|
|
template <typename T>
|
|
std::string
|
|
NumericDefaultValue<T>::DoGetType (void) const
|
|
{
|
|
std::ostringstream oss;
|
|
oss << TypeNameGet<T> () << "("
|
|
<< m_minValue << ":"
|
|
<< m_maxValue << ")";
|
|
return oss.str ();
|
|
}
|
|
|
|
template <typename T>
|
|
std::string
|
|
NumericDefaultValue<T>::DoGetDefaultValue (void) const
|
|
{
|
|
std::ostringstream oss;
|
|
oss << m_defaultValue;
|
|
return oss.str ();
|
|
}
|
|
|
|
template <typename T>
|
|
T
|
|
NumericDefaultValue<T>::RealMin (void) const
|
|
{
|
|
if (std::numeric_limits<T>::is_integer)
|
|
{
|
|
return std::numeric_limits<T>::min ();
|
|
}
|
|
else
|
|
{
|
|
return -std::numeric_limits<T>::max ();
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************
|
|
**************************************************************/
|
|
|
|
template <typename T>
|
|
EnumDefaultValue<T>::EnumDefaultValue (const std::string &name, const std::string &help,
|
|
T defaultValue, const char *defaultValueString,
|
|
...)
|
|
: DefaultValueBase (name, help),
|
|
m_defaultValue (defaultValue),
|
|
m_value (defaultValue)
|
|
{
|
|
AddPossibleValue (defaultValue, defaultValueString);
|
|
va_list list;
|
|
va_start (list, defaultValueString);
|
|
while (true)
|
|
{
|
|
T v = (T) va_arg (list, int);
|
|
const char *str = va_arg (list, const char *);
|
|
if (v == 0 && str == 0)
|
|
{
|
|
break;
|
|
}
|
|
AddPossibleValue (v, str);
|
|
}
|
|
DefaultValueList::Add (this);
|
|
}
|
|
template <typename T>
|
|
void
|
|
EnumDefaultValue<T>::AddPossibleValue (T value, const std::string &valueString)
|
|
{
|
|
m_possibleValues.push_back (std::make_pair (value, valueString));
|
|
}
|
|
template <typename T>
|
|
T
|
|
EnumDefaultValue<T>::GetValue (void)
|
|
{
|
|
return m_value;
|
|
}
|
|
template <typename T>
|
|
void
|
|
EnumDefaultValue<T>::SetValue (T value)
|
|
{
|
|
m_value = value;
|
|
}
|
|
template <typename T>
|
|
bool
|
|
EnumDefaultValue<T>::DoParseValue (const std::string &value)
|
|
{
|
|
for (typename PossibleValues::iterator i = m_possibleValues.begin ();
|
|
i != m_possibleValues.end (); i++)
|
|
{
|
|
if (value == i->second)
|
|
{
|
|
m_value = i->first;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
template <typename T>
|
|
std::string
|
|
EnumDefaultValue<T>::DoGetType (void) const
|
|
{
|
|
std::string retval;
|
|
retval += "(";
|
|
for (typename PossibleValues::const_iterator i = m_possibleValues.begin ();
|
|
i != m_possibleValues.end (); i++)
|
|
{
|
|
if (i != m_possibleValues.begin ())
|
|
{
|
|
retval += "|";
|
|
}
|
|
retval += i->second;
|
|
}
|
|
retval += ")";
|
|
return retval;
|
|
}
|
|
template <typename T>
|
|
std::string
|
|
EnumDefaultValue<T>::DoGetDefaultValue (void) const
|
|
{
|
|
for (typename PossibleValues::const_iterator i = m_possibleValues.begin ();
|
|
i != m_possibleValues.end (); i++)
|
|
{
|
|
if (i->first == m_defaultValue)
|
|
{
|
|
return i->second;
|
|
}
|
|
}
|
|
// cannot happen theoretically.
|
|
NS_ASSERT (false);
|
|
return ""; // quiet compiler
|
|
}
|
|
|
|
}//namespace ns3
|
|
|
|
#endif /* DEFAULT_VALUE_H */
|