src/core/default-value.h
changeset 439 fed13fb45eef
child 538 3cc417842b5f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/default-value.h	Thu Apr 26 11:36:05 2007 -0400
@@ -0,0 +1,423 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+#ifndef DEFAULT_VALUE_H
+#define DEFAULT_VALUE_H
+
+#include <string>
+#include <list>
+#include "callback.h"
+
+namespace ns3 {
+
+class DefaultValueBase
+{
+public:
+  virtual ~DefaultValueBase ();
+  std::string GetName (void) const;
+  std::string GetHelp (void) const;
+  // 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:
+  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;
+};
+
+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);
+ private:
+  typedef std::list<DefaultValueBase *> List;
+  static List *GetList (void);
+};
+
+/**
+ * \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);
+
+/**
+ * \brief A Boolean variable for ns3::Bind
+ *
+ * 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 An Integer variable for ns3::Bind
+ *
+ * Every instance of this type is automatically 
+ * registered in the variable pool which is used
+ * by ns3::Bind. 
+ */
+template <typename T>
+class IntegerDefaultValue : 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.
+   */
+  IntegerDefaultValue (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
+   * \param maxValue the maximum value which can be set in this
+   *        variable.
+   */
+  IntegerDefaultValue (std::string name,
+		       std::string help,
+		       T defaultValue,
+		       T minValue,
+		       T maxValue);
+
+
+  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 m_defaultValue;
+  T m_minValue;
+  T m_maxValue;
+  T m_value;
+};
+
+class StringEnumDefaultValue : public DefaultValueBase
+{
+public:
+  StringEnumDefaultValue (const std::string &name,
+                          const std::string &help);
+  void AddDefaultValue (const std::string &value);
+  void AddPossibleValue (const std::string &value);
+  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
+ *
+ * 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);
+ 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;
+};
+
+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>
+IntegerDefaultValue<T>::IntegerDefaultValue (std::string name,
+					     std::string help,
+					     T defaultValue)
+  : DefaultValueBase (name, help),
+    m_defaultValue (defaultValue),
+    m_minValue (std::numeric_limits<T>::min ()),
+    m_maxValue (std::numeric_limits<T>::max ()),
+    m_value (defaultValue)
+{
+  DefaultValueList::Add (this);
+}
+template <typename T>
+IntegerDefaultValue<T>::IntegerDefaultValue (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_defaultValue <= m_maxValue &&
+	     m_defaultValue >= m_minValue);
+}
+
+template <typename T>
+T
+IntegerDefaultValue<T>::GetValue (void) const
+{
+  return m_value;
+}
+
+template <typename T>
+bool
+IntegerDefaultValue<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
+IntegerDefaultValue<T>::DoGetType (void) const
+{
+  std::ostringstream oss;
+  oss << TypeNameGet<T> () << "("
+      << m_minValue << ":" 
+      << m_maxValue << ")";
+  return oss.str ();
+}
+
+template <typename T>
+std::string
+IntegerDefaultValue<T>::DoGetDefaultValue (void) const
+{
+  std::ostringstream oss;
+  oss << m_defaultValue;
+  return oss.str ();
+}
+
+/**************************************************************
+ **************************************************************/
+
+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>
+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 */