diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9621e944e..f48886de8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -231,7 +231,6 @@ set(header_files model/assert.h model/attribute-accessor-helper.h model/attribute-construction-list.h - model/attribute-container-accessor-helper.h model/attribute-container.h model/attribute-helper.h model/attribute.h diff --git a/src/core/model/attribute-container-accessor-helper.h b/src/core/model/attribute-container-accessor-helper.h deleted file mode 100644 index cbf8a7a68..000000000 --- a/src/core/model/attribute-container-accessor-helper.h +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2018 Caliola Engineering, LLC. - * - * 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: Jared Dulmage - */ - -#ifndef ATTRIBUTE_CONTAINER_ACCESSOR_HELPER_H -#define ATTRIBUTE_CONTAINER_ACCESSOR_HELPER_H - -#include "attribute-container.h" - -#include - - -#include -#include - -namespace ns3 { - -/** - * SFINAE compile time check if type T has const iterator. - */ -template -struct has_const_iterator -{ -private: - /// positive result - typedef char yes; - /// negative result - typedef struct - { - char array[2]; //!< Check value, its size must be different than the "yes" size - } no; - - /** - * Test function, compiled if type has a const_iterator - * \return A value indicating that this specialization has been compiled. - */ - template static yes test (typename C::const_iterator *); - /** - * Test function, compiled if type does not have a const_iterator - * \return A value indicating that this specialization has been compiled. - */ - template static no test (...); - -public: - /// Value of the test - true if type has a const_iterator - static const bool value = sizeof (test (0)) == sizeof (yes); - /// Equivalent name of the type T - typedef T type; -}; - -/** - * SFINAE compile time check if type T has begin() and end() methods. - */ -template -struct has_begin_end -{ - /** - * Compiled if type T has a begin() method. - * \return A value indicating that this specialization has been compiled. - */ - template static char (&f (typename std::enable_if< - std::is_same (&C::begin)), - typename C::const_iterator (C::*) () const>::value, void>::type *))[1]; - - /** - * Compiled if type T does not have a begin() method. - * \return A value indicating that this specialization has been compiled. - */ - template static char (&f (...))[2]; - - /** - * Compiled if type T has an end() method. - * \return A value indicating that this specialization has been compiled. - */ - template static char (&g (typename std::enable_if< - std::is_same (&C::end)), - typename C::const_iterator (C::*) () const>::value, void>::type *))[1]; - - /** - * Compiled if type T does not have an end() method. - * \return A value indicating that this specialization has been compiled. - */ - template static char (&g (...))[2]; - - /// True if type T has a begin() method. - static bool const beg_value = sizeof (f (0)) == 1; - /// True if type T has an end() method. - static bool const end_value = sizeof (g (0)) == 1; -}; - -/** - * Compile time check if type T is a container. - * - * Container here means has an iterator and supports begin() and end() - * methods. - * - * Can be used when defining specializations when a type T is an STL - * like container. - */ -template -struct is_container : std::integral_constant::value && has_begin_end::beg_value && has_begin_end::end_value> -{ }; - -/** - * \ingroup attributeimpl - * - * DoMakeAccessorHelperOne specialization for member containers - * - * The template parameter list contains an extra parameter that is - * intended to disambiguate an attribute container from any other - * templated attribute, e.g Ptr or Callback. Disambiguation is based - * on begin/end and iterator. - * - * \tparam V \explicit The specific AttributeValue type to use to represent - * the Attribute. - * \tparam T \deduced The class holding the data member. - * \tparam U \deduced The type of the container. - * \tparam I \deduced The type of item (s) within the container. - * \param [in] memberContainer The address of the data member. - * \returns The AttributeAccessor. - */ -template class U, typename ...I, - typename = typename std::enable_if< ( is_container< U >::value ), void>::type > -inline -Ptr -DoMakeAccessorHelperOne (U T::*memberContainer) -{ - /* AttributeAcessor implementation for a class member variable. */ - class MemberContainer : public AccessorHelper - { - public: - /* - * Construct from a class data member address. - * \param [in] memberContainer The class data member address. - */ - MemberContainer (U T::*memberContainer) - : AccessorHelper (), - m_memberContainer (memberContainer) - {} - private: - virtual bool DoSet (T *object, const V *v) const { - // typename AccessorTrait::value_type>::Result tmp; - // bool ok = v->GetAccessor (tmp); - // if (!ok) - // { - // return false; - // } - auto src = v->Get (); - (object->*m_memberContainer).clear (); - std::copy (src.begin (), src.end (), std::inserter ((object->*m_memberContainer), (object->*m_memberContainer).end ())); - return true; - } - virtual bool DoGet (const T *object, V *v) const { - v->Set (object->*m_memberContainer); - return true; - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return true; - } - - U T::*m_memberContainer; // Address of the class data member. - }; - return Ptr (new MemberContainer (memberContainer), false); -} - -} // namespace ns3 - -#endif // ATTRIBUTE_CONTAINER_ACCESSOR_HELPER_H diff --git a/src/core/model/attribute-container.h b/src/core/model/attribute-container.h index fc81e126d..6da3e029c 100644 --- a/src/core/model/attribute-container.h +++ b/src/core/model/attribute-container.h @@ -39,11 +39,11 @@ class AttributeChecker; // A = attribute value type, C = container type to return /** * A container for one type of attribute. - * + * * The container uses \p A to parse items into elements. * Internally the container is always a list but an instance * can return the items in a container specified by \p C. - * + * * @tparam A AttributeValue type to be contained. * @tparam C Possibly templated container class returned by Get. */ @@ -111,7 +111,7 @@ public: result_type Get (void) const; /** * Copy items from container c. - * + * * This method assumes \p c has stl-style begin and end methods. * The AttributeContainerValue value is cleared before copying from \p c. * @tparam T type of container. @@ -119,6 +119,17 @@ public: */ template void Set (const T &c); + /** + * Set the given variable to the values stored by this TupleValue object. + * + * \tparam T \deduced the type of the given variable (normally, the argument type + * of a set method or the type of a data member) + * \param value the given variable + * \return true if the given variable was set + */ + template + bool GetAccessor (T &value) const; + // NS3 interface /** @@ -166,8 +177,8 @@ public: private: /** - * Copy items from \ref begin to \ref end. - * + * Copy items from \ref begin to \ref end. + * * The internal container is cleared before values are copied * using the push_back method. * @tparam ITER \deduced iterator type @@ -232,12 +243,31 @@ Ptr MakeAttributeContainerChecker (void); * Make AttributeContainerAccessor using explicit types. * @tparam A AttributeValue type in container. * @tparam C Container type returned by Get. - * \param[in] a1 AttributeContainer to be used. + * \tparam T1 \deduced The type of the class data member, + * or the type of the class get functor or set method. + * \param [in] a1 The address of the data member, + * or the get or set method. * \return AttributeContainerAccessor. */ template class C=std::list, typename T1> Ptr MakeAttributeContainerAccessor (T1 a1); +/** + * Make AttributeContainerAccessor using explicit types. + * @tparam A AttributeValue type in container. + * @tparam C Container type returned by Get. + * \tparam T1 \deduced The type of the class data member, + * or the type of the class get functor or set method. + * + * \tparam T2 \deduced The type of the getter class functor method. + * \param [in] a2 The address of the class method to set the attribute. + * \param [in] a1 The address of the data member, + * or the get or set method. + * \return AttributeContainerAccessor. + */ +template class C=std::list, typename T1, typename T2> +Ptr MakeAttributeContainerAccessor (T1 a1, T2 a2); + } // namespace ns3 /***************************************************************************** @@ -423,6 +453,17 @@ AttributeContainerValue::Get (void) const return c; } +template class C> +template +bool +AttributeContainerValue::GetAccessor (T &value) const +{ + result_type src = Get (); + value.clear (); + std::copy (src.begin (), src.end (), std::inserter (value, value.end ())); + return true; +} + template class C> template void @@ -506,6 +547,12 @@ Ptr MakeAttributeContainerAccessor (T1 a1) return MakeAccessorHelper > (a1); } +template class C, typename T1, typename T2> +Ptr MakeAttributeContainerAccessor (T1 a1, T2 a2) +{ + return MakeAccessorHelper > (a1, a2); +} + } // namespace ns3 #endif // ATTRIBUTE_CONTAINER_H diff --git a/src/core/test/attribute-container-test-suite.cc b/src/core/test/attribute-container-test-suite.cc index 364c3aa3c..9a5941d8a 100644 --- a/src/core/test/attribute-container-test-suite.cc +++ b/src/core/test/attribute-container-test-suite.cc @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -66,10 +65,23 @@ public: /** * \brief Get the type ID. * \return The object TypeId. - */ + */ static TypeId GetTypeId (); + /** + * Set the vector of ints to the given vector + * + * \param vec the given vector + */ + void SetIntVec (std::vector vec); + /** + * Get the vector of ints + * + * \return the vector of ints + */ + std::vector GetIntVec (void) const; + /** * \brief Stream insertion operator. * @@ -110,7 +122,9 @@ AttributeContainerObject::GetTypeId () .AddAttribute ("IntegerVector", "Vector of integers", // the container value container differs from the underlying object AttributeContainerValue (), - MakeAttributeContainerAccessor (&AttributeContainerObject::m_intvec), + // the type of the underlying container cannot be deduced + MakeAttributeContainerAccessor (&AttributeContainerObject::SetIntVec, + &AttributeContainerObject::GetIntVec), MakeAttributeContainerChecker (MakeIntegerChecker ())) .AddAttribute ("MapStringInt", "Map of strings to ints", // the container value container differs from the underlying object @@ -131,6 +145,18 @@ AttributeContainerObject::ReverseList () m_intvec = tmp; } +void +AttributeContainerObject::SetIntVec (std::vector vec) +{ + m_intvec = vec; +} + +std::vector +AttributeContainerObject::GetIntVec (void) const +{ + return m_intvec; +} + std::ostream & operator << (std::ostream &os, const AttributeContainerObject &obj) { @@ -147,7 +173,7 @@ operator << (std::ostream &os, const AttributeContainerObject &obj) /** * \ingroup attribute-tests - * + * * This function handles mixed constness and compatible, yet * distinct numerical classes (like int and long) * \param x The left operand. @@ -163,7 +189,7 @@ operator ==(const std::pair &x, const std::pair &y) /** * \ingroup attribute-tests - * + * * Test AttributeContainer instantiation, initialization, access */ class AttributeContainerTestCase : public TestCase @@ -269,7 +295,7 @@ AttributeContainerTestCase::DoRun () /** * \ingroup attribute-tests - * + * * Attribute serialization and deserialization TestCase. */ class AttributeContainerSerializationTestCase : public TestCase @@ -359,7 +385,7 @@ AttributeContainerSerializationTestCase::DoRun (void) /** * \ingroup attribute-tests - * + * * Attribute set and get TestCase. */ class AttributeContainerSetGetTestCase : public TestCase @@ -462,7 +488,7 @@ AttributeContainerSetGetTestCase::DoRun (void) /** * \ingroup attribute-tests - * + * * Attribute attribute container TestCase. */ class AttributeContainerTestSuite : public TestSuite