diff --git a/doc/doxygen.conf b/doc/doxygen.conf
index 05f7d0662..7a40ca3ef 100644
--- a/doc/doxygen.conf
+++ b/doc/doxygen.conf
@@ -2267,6 +2267,7 @@ PREDEFINED = NS3_ASSERT_ENABLE \
NS_LOG_COMPONENT_DEFINE_MASK()=1 \
NS_OBJECT_ENSURE_REGISTERED()=1 \
NS_OBJECT_TEMPLATE_CLASS_DEFINE()=1 \
+ NS_OBJECT_TEMPLATE_CLASS_TWO_DEFINE()=1 \
NS3_BUILD_PROFILE_DEBUG \
NS3_BUILD_PROFILE_RELEASE \
NS3_BUILD_PROFILE_OPTIMIZED \
diff --git a/src/core/model/object-base.h b/src/core/model/object-base.h
index 50050ced5..197eaf511 100644
--- a/src/core/model/object-base.h
+++ b/src/core/model/object-base.h
@@ -55,53 +55,100 @@
/**
* \ingroup object
- * \brief Explicitly instantiate a template class and register the resulting
- * instance with the TypeId system.
+ * \brief Explicitly instantiate a template class with one template parameter
+ * and register the resulting instance with the TypeId system.
*
* This macro should be invoked once for every required instance of a template
- * class which derives from the Object class and defines a new GetTypeId method.
+ * class with one template parameter which derives from the Object class and
+ * defines a new GetTypeId method.
*
* If the template class is in a namespace, then the macro call should also be
* in the namespace.
+ *
+ * \note The type names used as arguments for this macro, being used to form a
+ * class name and a variable name, CANNOT contain the scope resolution
+ * operator (::)
+ *
+ * \tparam type the template class
+ * \tparam param the first template parameter
*/
-#define NS_OBJECT_TEMPLATE_CLASS_DEFINE(type,param) \
- template class type; \
- template <> std::string DoGetTypeParamName > () \
- { \
- return #param; \
- } \
- static struct Object ## type ## param ## RegistrationClass \
- { \
- Object ## type ## param ## RegistrationClass () { \
- ns3::TypeId tid = type::GetTypeId (); \
- tid.SetSize (sizeof (type)); \
- tid.GetParent (); \
- } \
+#define NS_OBJECT_TEMPLATE_CLASS_DEFINE(type,param) \
+ template class type; \
+ template <> std::string DoGetTemplateClassName > () \
+ { \
+ return std::string ("ns3::") + std::string (#type) \
+ + std::string ("<") + std::string (#param) + std::string (">"); \
+ } \
+ static struct Object ## type ## param ## RegistrationClass \
+ { \
+ Object ## type ## param ## RegistrationClass () { \
+ ns3::TypeId tid = type::GetTypeId (); \
+ tid.SetSize (sizeof (type)); \
+ tid.GetParent (); \
+ } \
} Object ## type ## param ## RegistrationVariable
+/**
+ * \ingroup object
+ * \brief Explicitly instantiate a template class with two template parameters
+ * and register the resulting instance with the TypeId system.
+ *
+ * This macro should be invoked once for every required instance of a template
+ * class with two template parameters which derives from the Object class and
+ * defines a new GetTypeId method.
+ *
+ * If the template class is in a namespace, then the macro call should also be
+ * in the namespace.
+ *
+ * \note The type names used as arguments for this macro, being used to form a
+ * class name and a variable name, CANNOT contain the scope resolution
+ * operator (::)
+ *
+ * \tparam type the template class
+ * \tparam param1 the first template parameter
+ * \tparam param2 the second template parameter
+ */
+#define NS_OBJECT_TEMPLATE_CLASS_TWO_DEFINE(type,param1,param2) \
+ template class type; \
+ template <> std::string DoGetTemplateClassName > () \
+ { \
+ return std::string ("ns3::") + std::string (#type) \
+ + std::string ("<") + std::string (#param1) + std::string (",") \
+ + std::string (#param2) + std::string (">"); \
+ } \
+ static struct Object ## type ## param1 ## param2 ## RegistrationClass \
+ { \
+ Object ## type ## param1 ## param2 ## RegistrationClass () { \
+ ns3::TypeId tid = type::GetTypeId (); \
+ tid.SetSize (sizeof (type)); \
+ tid.GetParent (); \
+ } \
+ } Object ## type ## param1 ## param2 ## RegistrationVariable
+
+
namespace ns3 {
/**
- * \brief Helper function to get the name (as a string) of the type parameter
+ * \brief Helper function to get the name (as a string) of the type
* of a template class
- * \return the name of the type parameter as a string
+ * \return the name of the type of a template class as a string
*
* A specialization of this function is defined by the
* NS_OBJECT_TEMPLATE_CLASS_DEFINE macro.
*/
template
-std::string DoGetTypeParamName (void);
+std::string DoGetTemplateClassName (void);
/**
- * \brief Helper function to get the name (as a string) of the type parameter
+ * \brief Helper function to get the name (as a string) of the type
* of a template class
- * \return the name of the type parameter as a string
+ * \return the name of the type of a template class as a string
*/
template
-std::string GetTypeParamName (void)
+std::string GetTemplateClassName (void)
{
- return DoGetTypeParamName ();
+ return DoGetTemplateClassName ();
}
class AttributeConstructionList;
diff --git a/src/network/utils/drop-tail-queue.h b/src/network/utils/drop-tail-queue.h
index 4401cb344..7096937f1 100644
--- a/src/network/utils/drop-tail-queue.h
+++ b/src/network/utils/drop-tail-queue.h
@@ -71,7 +71,7 @@ template
TypeId
DropTailQueue- ::GetTypeId (void)
{
- static TypeId tid = TypeId ("ns3::DropTailQueue<" + GetTypeParamName > () + ">")
+ static TypeId tid = TypeId (GetTemplateClassName> ())
.SetParent > ()
.SetGroupName ("Network")
.template AddConstructor > ()
diff --git a/src/network/utils/queue.h b/src/network/utils/queue.h
index f26732b77..6dae907a3 100644
--- a/src/network/utils/queue.h
+++ b/src/network/utils/queue.h
@@ -464,25 +464,29 @@ template
TypeId
Queue
- ::GetTypeId (void)
{
- std::string name = GetTypeParamName > ();
- static TypeId tid = TypeId ("ns3::Queue<" + name + ">")
+ std::string name = GetTemplateClassName> ();
+ auto startPos = name.find ('<') + 1;
+ auto endPos = name.find ('>');
+ std::string tcbName = "ns3::" + name.substr (startPos, endPos - startPos) + "::TracedCallback";
+
+ static TypeId tid = TypeId (name)
.SetParent ()
.SetGroupName ("Network")
.AddTraceSource ("Enqueue", "Enqueue a packet in the queue.",
MakeTraceSourceAccessor (&Queue
- ::m_traceEnqueue),
- "ns3::" + name + "::TracedCallback")
+ tcbName)
.AddTraceSource ("Dequeue", "Dequeue a packet from the queue.",
MakeTraceSourceAccessor (&Queue
- ::m_traceDequeue),
- "ns3::" + name + "::TracedCallback")
+ tcbName)
.AddTraceSource ("Drop", "Drop a packet (for whatever reason).",
MakeTraceSourceAccessor (&Queue
- ::m_traceDrop),
- "ns3::" + name + "::TracedCallback")
+ tcbName)
.AddTraceSource ("DropBeforeEnqueue", "Drop a packet before enqueue.",
MakeTraceSourceAccessor (&Queue
- ::m_traceDropBeforeEnqueue),
- "ns3::" + name + "::TracedCallback")
+ tcbName)
.AddTraceSource ("DropAfterDequeue", "Drop a packet after dequeue.",
MakeTraceSourceAccessor (&Queue
- ::m_traceDropAfterDequeue),
- "ns3::" + name + "::TracedCallback")
+ tcbName)
;
return tid;
}
diff --git a/src/nix-vector-routing/model/nix-vector-routing.cc b/src/nix-vector-routing/model/nix-vector-routing.cc
index 4bc6966e2..656589ef6 100644
--- a/src/nix-vector-routing/model/nix-vector-routing.cc
+++ b/src/nix-vector-routing/model/nix-vector-routing.cc
@@ -58,9 +58,16 @@ template
TypeId
NixVectorRouting::GetTypeId (void)
{
- std::string Tname = GetTypeParamName > ();
- std::string name = (Tname == "Ipv4RoutingProtocol" ? "Ipv4" : "Ipv6");
- static TypeId tid = TypeId ("ns3::" + name + "NixVectorRouting")
+ std::string name;
+ if constexpr (std::is_same_v)
+ {
+ name = "Ipv4";
+ }
+ else
+ {
+ name = "Ipv6";
+ }
+ static TypeId tid = TypeId (("ns3::" + name + "NixVectorRouting"))
.SetParent ()
.SetGroupName ("NixVectorRouting")
.template AddConstructor > ()