Bugzilla – Bug 2780
Pass an arbitrary number of arguments to ObjectFactory::Set
Last modified: 2020-05-06 10:54:34 UTC
Created attachment 2911 [details] C++11 version of the patch Variadic templates allow to pass an arbitrary number of arguments to ObjectFactory::Set, so that helper functions (and CreateObjectWithAttributes<T>()) can be greatly simplified and allow arbitrary number of arguments. For instance: template<typename T> Ptr<T> CreateObjectWithAttributes (std::string n1, const AttributeValue & v1, std::string n2, const AttributeValue & v2, std::string n3, const AttributeValue & v3, std::string n4, const AttributeValue & v4, std::string n5, const AttributeValue & v5, std::string n6, const AttributeValue & v6, std::string n7, const AttributeValue & v7, std::string n8, const AttributeValue & v8, std::string n9, const AttributeValue & v9) { ObjectFactory factory; factory.SetTypeId (T::GetTypeId ()); factory.Set (n1, v1); factory.Set (n2, v2); factory.Set (n3, v3); factory.Set (n4, v4); factory.Set (n5, v5); factory.Set (n6, v6); factory.Set (n7, v7); factory.Set (n8, v8); factory.Set (n9, v9); return factory.Create<T> (); } becomes template<typename T, typename... Args> Ptr<T> CreateObjectWithAttributes (Args... args) { ObjectFactory factory; factory.SetTypeId (T::GetTypeId ()); factory.Set (args...); return factory.Create<T> (); } I did not implement the "recursive" approach (Set consumes two arguments and calls itself), but an approach where all the name-value pairs are used to initialize a map and then set by calling the DoSet member function (which is exactly the current Set member function). I used this approach to simplify the traffic-control helper and verified that the python bindings can be scanned (with castxml, 64-bit only) and ns-3 builds on Linux (g++-4.9 and g++-7.1) and Mac OSX (clang 8.1). I also prepared a C++14 version of the patch, where I could avoid defining index_sequence and make_index_sequence and reuse std::index_sequence and std::make_index_sequence. I switched ns-3 to using C++14 and: - ns-3 builds on Mac OSX (clang 8.1) and Linux (g++ 7.1) - ns-3 does not build on Linux with g++ 4.9, not because of this patch but because of the pattern below used in the emulation devices: char control[CMSG_SPACE (msg_size)]; ... msg.msg_controllen = sizeof (control); "error: taking sizeof array of runtime bound" I think it is anyway safe to replace msg.msg_controllen = sizeof (control); with msg.msg_controllen = CMSG_SPACE (msg_size) * sizeof (char); After that, everything builds and runs just fine.
Created attachment 2912 [details] C++14 version of the patch
Comment on attachment 2912 [details] C++14 version of the patch In object-factory.h for the SetImpl declaration you use the following. Is the \tparam in the DOXYGEN declaration intentional? \tparam T \explicit The requested Object type.
(In reply to Robert Ammon from comment #2) > Comment on attachment 2912 [details] > C++14 version of the patch > > In object-factory.h for the SetImpl declaration you use the following. Is > the \tparam in the DOXYGEN declaration intentional? > > \tparam T \explicit The requested Object type. It was already there, I didn't add it intentionally. Anyway, I didn't pay much attention to doxygen and documentation for now. Should this patch be accepted, I will of course fix doxygen and documentation.
Moved to GitLab: https://gitlab.com/nsnam/ns-3-dev/-/merge_requests/276