diff --git a/src/core/model/attribute-container-accessor-helper.h b/src/core/model/attribute-container-accessor-helper.h new file mode 100644 index 000000000..afa599fcd --- /dev/null +++ b/src/core/model/attribute-container-accessor-helper.h @@ -0,0 +1,101 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 { + +/** + * \ingroup attributeimpl + * + * DoMakeAccessorHelperOne specialization for member containers + * + * The template parameter list contains an extra parameter that disambiguates + * the templated Ptr type from container types by taking advantage of the fact + * that container types have multiple template arguments and Ptr has only one. + * This disambiguation works but is not sufficiently robust as a long term solution. + * + * \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< (sizeof...(I) > 1), 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 \ No newline at end of file diff --git a/src/core/model/attribute-container.cc b/src/core/model/attribute-container.cc new file mode 100644 index 000000000..b3f47203f --- /dev/null +++ b/src/core/model/attribute-container.cc @@ -0,0 +1,27 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 + * Note: Need this file for library to be built + */ + +#include "attribute-container.h" + +namespace ns3 { + + +} // namespace ns3 diff --git a/src/core/model/attribute-container.h b/src/core/model/attribute-container.h new file mode 100644 index 000000000..d3396d131 --- /dev/null +++ b/src/core/model/attribute-container.h @@ -0,0 +1,384 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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_H +#define ATTRIBUTE_CONTAINER_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace ns3 { + +class AttributeChecker; + +// A = attribute value type, C = container type to return +template class C=std::list> +class AttributeContainerValue : public AttributeValue +{ +public: + typedef A attribute_type; + typedef Ptr value_type; + typedef std::list container_type; + typedef typename container_type::const_iterator const_iterator; + typedef typename container_type::iterator iterator; + typedef typename container_type::size_type size_type; + typedef typename AttributeContainerValue::const_iterator Iterator; // NS3 type + + // use underlying AttributeValue to get return element type + typedef typename std::result_of::type item_type; + typedef C result_type; + + AttributeContainerValue (char sep = ','); + + template + AttributeContainerValue (const CONTAINER &c); + + template + AttributeContainerValue (const ITER begin, const ITER end); + + ~AttributeContainerValue (); + + Ptr Copy (void) const; + + bool DeserializeFromString (std::string value, Ptr checker); + std::string SerializeToString (Ptr checker) const; + + // defacto pure virtuals to integrate with built-in accessor code + result_type Get (void) const; + template + void Set (const T &c); + + // NS3 interface + size_type GetN (void) const; + Iterator Begin (void); + Iterator End (void); + + size_type size (void) const; + iterator begin (void); + iterator end (void); + const_iterator begin (void) const; + const_iterator end (void) const; + +private: + template + Ptr > CopyFrom (const ITER begin, const ITER end); + + char m_sep; + container_type m_container; +}; + +template class C> +class AttributeContainerChecker : public AttributeChecker +{ +public: + virtual void SetItemChecker (Ptr itemchecker) = 0; + virtual Ptr GetItemChecker (void) const = 0; +}; + +/** + * Return checker using attribute value to provide types + */ +template class C> +Ptr > +MakeAttributeContainerChecker (const AttributeContainerValue &value); + +/** + * Return checker give types explicitly, defaults same + * as AttributeContainerValue defaults + */ +template class C=std::list> +Ptr > +MakeAttributeContainerChecker (Ptr itemchecker); + +template class C=std::list> +Ptr > MakeAttributeContainerChecker (void); + +template class C=std::list, typename T1> +Ptr MakeAttributeContainerAccessor (T1 a1); + +} // namespace ns3 + +/***************************************************************************** + * Implementation below + *****************************************************************************/ + +namespace ns3 { + +namespace internal { + +template class C> +class AttributeContainerChecker : public ns3::AttributeContainerChecker +{ +public: + AttributeContainerChecker (void); + explicit AttributeContainerChecker (Ptr itemchecker); + void SetItemChecker (Ptr itemchecker); + Ptr GetItemChecker (void) const; + +private: + Ptr m_itemchecker; +}; + +template class C> +AttributeContainerChecker::AttributeContainerChecker (void) + : m_itemchecker (0) +{} + +template class C> +AttributeContainerChecker::AttributeContainerChecker (Ptr itemchecker) + : m_itemchecker (itemchecker) +{} + +template class C> +void +AttributeContainerChecker::SetItemChecker (Ptr itemchecker) +{ + m_itemchecker = itemchecker; +} + +template class C> +Ptr +AttributeContainerChecker::GetItemChecker (void) const +{ + return m_itemchecker; +} + +} // namespace internal + +template class C> +Ptr > +MakeAttributeContainerChecker (const AttributeContainerValue &value) +{ + return MakeAttributeContainerChecker (); +} + +template class C> +Ptr > +MakeAttributeContainerChecker (Ptr itemchecker) +{ + auto checker = MakeAttributeContainerChecker (); + checker->SetItemChecker (itemchecker); + return checker; +} + +template class C> +Ptr > +MakeAttributeContainerChecker (void) +{ + std::string typeName, underlyingType; + typedef AttributeContainerValue T; + { + std::ostringstream oss; + oss << "ns3::AttributeContainerValue<" << typeid (typename T::attribute_type).name () + << ", " << typeid (typename T::container_type).name () << ">"; + typeName = oss.str (); + } + + { + std::ostringstream oss; + oss << "ns3::Ptr<" << typeid (typename T::attribute_type).name () << ">"; + underlyingType = oss.str (); + } + + return DynamicCast > ( + MakeSimpleAttributeChecker > (typeName, underlyingType) + ); +} + +template class C> +AttributeContainerValue::AttributeContainerValue (char sep) + : m_sep (sep) +{ + +} + +template class C> +template +AttributeContainerValue::AttributeContainerValue (const CONTAINER &c) + : AttributeContainerValue (c.begin (), c.end ()) +{ + +} + +template class C> +template +AttributeContainerValue::AttributeContainerValue (const ITER begin, const ITER end) + : AttributeContainerValue () +{ + CopyFrom (begin, end); +} + +template class C> +AttributeContainerValue::~AttributeContainerValue () +{ + m_container.clear (); +} + +template class C> +Ptr +AttributeContainerValue::Copy (void) const +{ + auto c = Create > (); + c->m_sep = m_sep; + c->m_container = m_container; + return c; +} + +template class C> +bool +AttributeContainerValue::DeserializeFromString (std::string value, Ptr checker) +{ + auto acchecker = DynamicCast > (checker); + if (!acchecker) return false; + + std::istringstream iss (value); // copies value + while (std::getline (iss, value, m_sep)) + { + auto avalue = acchecker->GetItemChecker ()->CreateValidValue (StringValue (value)); + if (!avalue) return false; + + auto attr = DynamicCast (avalue); + if (!attr) return false; + + // TODO(jared): make insertion more generic? + m_container.push_back (attr); + } + return true; +} + +template class C> +std::string +AttributeContainerValue::SerializeToString (Ptr checker) const +{ + std::ostringstream oss; + bool first = true; + for (auto attr: *this) + { + if (!first) oss << m_sep; + oss << attr->SerializeToString (checker); + first = false; + } + return oss.str (); +} + +template class C> +typename AttributeContainerValue::result_type +AttributeContainerValue::Get (void) const +{ + result_type c; + for (const value_type a: *this) + c.insert (c.end (), a->Get ()); + return c; +} + +template class C> +template +void +AttributeContainerValue::Set (const T &c) +{ + m_container.clear (); + CopyFrom (c.begin (), c.end ()); +} + +template class C> +typename AttributeContainerValue::size_type +AttributeContainerValue::GetN (void) const +{ + return size (); +} + +template class C> +typename AttributeContainerValue::Iterator +AttributeContainerValue::Begin (void) +{ + return begin (); +} + +template class C> +typename AttributeContainerValue::Iterator +AttributeContainerValue::End (void) +{ + return end (); +} + +template class C> +typename AttributeContainerValue::size_type +AttributeContainerValue::size (void) const +{ + return m_container.size (); +} + +template class C> +typename AttributeContainerValue::iterator +AttributeContainerValue::begin (void) +{ + return m_container.begin (); +} + +template class C> +typename AttributeContainerValue::iterator +AttributeContainerValue::end (void) +{ + return m_container.end (); +} + +template class C> +typename AttributeContainerValue::const_iterator +AttributeContainerValue::begin (void) const +{ + return m_container.cbegin (); +} + +template class C> +typename AttributeContainerValue::const_iterator +AttributeContainerValue::end (void) const +{ + return m_container.cend (); +} + +template class C> +template +Ptr > +AttributeContainerValue::CopyFrom (const ITER begin, const ITER end) +{ + for (ITER iter = begin; iter != end; ++iter) + { + m_container.push_back (Create (*iter)); + } + return this; +} + +template class C, typename T1> +Ptr MakeAttributeContainerAccessor (T1 a1) +{ + return MakeAccessorHelper > (a1); +} + +} // namespace ns3 + +#endif // ATTRIBUTE_CONTAINER_H \ No newline at end of file diff --git a/src/core/model/extended-attribute-helper.h b/src/core/model/extended-attribute-helper.h new file mode 100644 index 000000000..cd0ed0461 --- /dev/null +++ b/src/core/model/extended-attribute-helper.h @@ -0,0 +1,346 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 EXTENDED_ATTRIBUTE_HELPER_H +#define EXTENDED_ATTRIBUTE_HELPER_H + +#include "ns3/attribute-accessor-helper.h" + +namespace ns3 { +/** + * \ingroup attributeimpl + * + * MakeAccessorHelper implementation for a plain ole get functor. + * + * \tparam V \explicit The specific AttributeValue type to use to represent + * the Attribute. + * \tparam T \deduced The class whose object pointer will be passed to the get functor. + * \tparam U \deduced The return type of the get functor. + * \param [in] getter The address of the get functor. + * \returns The AttributeAccessor. + */ +template +inline +Ptr +DoMakeAccessorHelperOne (U (*getter)(const T*)) +{ + /* AttributeAccessor implementation with a plain ole functor method. */ + class POFunction : public AccessorHelper + { + public: + /* + * Construct from a class get functor method. + * \param [in] getter The class get functor method pointer. + */ + POFunction (U (*getter)(const T*)) + : AccessorHelper (), + m_getter (getter) + {} + private: + virtual bool DoSet (T *object, const V *v) const { + return false; + } + virtual bool DoGet (const T *object, V *v) const { + v->Set ((*m_getter)(object)); + return true; + } + virtual bool HasGetter (void) const { + return true; + } + virtual bool HasSetter (void) const { + return false; + } + U (*m_getter)(const T*); // The class get functor method pointer. + }; + return Ptr (new POFunction (getter), false); +} + +/** + * \ingroup attributeimpl + * + * MakeAccessorHelper implementation for a plain ole function returning void. + * + * \tparam V \explicit The specific AttributeValue type to use to represent + * the Attribute. + * \tparam T \deduced The class whose object pointer will be passed to the set functor. + * \tparam U \deduced The argument type of the set functor. + * \param [in] setter The address of the set functor, returning void. + * \returns The AttributeAccessor. + */ +template +inline +Ptr +DoMakeAccessorHelperOne (void (*setter)(T*, U)) +{ + /* AttributeAccessor implementation with a plain ole function returning void. */ + class POFunction : public AccessorHelper + { +public: + /* + * Construct from a class set method. + * \param [in] setter The class set method pointer. + */ + POFunction (void (*setter)(T*, U)) + : AccessorHelper (), + m_setter (setter) + {} +private: + virtual bool DoSet (T *object, const V *v) const { + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (*m_setter)(object, tmp); + return true; + } + virtual bool DoGet (const T *object, V *v) const { + return false; + } + virtual bool HasGetter (void) const { + return false; + } + virtual bool HasSetter (void) const { + return true; + } + void (*m_setter)(T*, U); // The class set method pointer, returning void. + }; + return Ptr (new POFunction (setter), false); +} + +/** + * \ingroup attributeimpl + * + * MakeAccessorHelper implementation for a ns3::Callback argument + * + * Using ns3::Callback functors gives the option of binding arguments + * \tparam V \explicit The specific AttributeValue type to use to represent + * the Attribute. + * \tparam T \deduced The class whose object pointer will be passed to the set functor. + * \tparam U \deduced The argument type of the set functor. + * \param [in] setter The set functor (type ns3::Callback), returning void. + * \returns The AttributeAccessor. + */ +template +inline +Ptr +DoMakeAccessorHelperOne (Callback setter) +{ + /* AttributeAccessor implementation with a plain ole function returning void. */ + class POFunction : public AccessorHelper + { +public: + /* + * Construct from a class set method. + * \param [in] setter The class set method pointer. + */ + POFunction (Callback setter) + : AccessorHelper (), + m_setter (setter) + {} +private: + virtual bool DoSet (T *object, const V *v) const { + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + m_setter(object, tmp); + return true; + } + virtual bool DoGet (const T *object, V *v) const { + return false; + } + virtual bool HasGetter (void) const { + return false; + } + virtual bool HasSetter (void) const { + return true; + } + Callback m_setter; // The class set method pointer, returning void. + }; + return Ptr (new POFunction (setter), false); +} + +/** + * \ingroup attributeimpl + * + * MakeAccessorHelper implementation with a get functor + * and a set functor returning void. + * + * The two versions of this function differ only in argument order. + * + * \tparam W \explicit The specific AttributeValue type to use to represent + * the Attribute. + * \tparam T \deduced The class whose object pointer is passed to the functors. + * \tparam U \deduced The argument type of the set method. + * \tparam V \deduced The return type of the get functor method. + * \param [in] setter The address of the set functor, returning void. + * \param [in] getter The address of the get functor. + * \returns The AttributeAccessor. + */ +template +inline +Ptr +DoMakeAccessorHelperTwo (void (*setter)(T*, U), V (*getter)(T*)) +{ + /* + * AttributeAccessor implementation with plain ole get functor and set functor, + * returning void. + */ + class POFunction : public AccessorHelper + { +public: + /* + * Construct from get and set functors. + * \param [in] setter The set functor pointer, returning void. + * \param [in] getter The get functor pointer. + */ + POFunction (void (*setter)(T*, U), V (*getter)(T*)) + : AccessorHelper (), + m_setter (setter), + m_getter (getter) + {} +private: + virtual bool DoSet (T *object, const W *v) const { + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (*m_setter)(object, tmp); + return true; + } + virtual bool DoGet (const T *object, W *v) const { + v->Set ((*m_getter)(object)); + return true; + } + virtual bool HasGetter (void) const { + return true; + } + virtual bool HasSetter (void) const { + return true; + } + void (*m_setter)(T*, U); // The class set method pointer, returning void. + V (*m_getter)(T*); // The class get functor method pointer. + }; + return Ptr (new POFunction (setter, getter), false); +} + + +/** + * \ingroup attributeimpl + * \copydoc DoMakeAccessorHelperTwo(void(*)(T*, U),V(*)(T*)) + */ +template +inline +Ptr +DoMakeAccessorHelperTwo (V (*getter)(T*), void (*setter)(T*, U)) +{ + return DoMakeAccessorHelperTwo (setter, getter); +} + + +/** + * \ingroup attributeimpl + * + * MakeAccessorHelper implementation with a get functor + * and a set functor returning \p bool. + * + * The two versions of this function differ only in argument order. + * + * \tparam W \explicit The specific AttributeValue type to use to represent + * the Attribute. + * \tparam T \deduced The class whose object pointer is passed to the functors. + * \tparam U \deduced The argument type of the set method. + * \tparam V \deduced The return type of the get functor method. + * \param [in] setter The address of the set functor, returning bool. + * \param [in] getter The address of the get functor. + * \returns The AttributeAccessor. + */ +template +inline +Ptr +DoMakeAccessorHelperTwo (bool (*setter)(T*, U), V (*getter)(T*)) +{ + /* + * AttributeAccessor implementation with plain ole get functor and + * set functor, returning bool. + */ + class POFunction : public AccessorHelper + { +public: + /* + * Construct from class get functor and set method, returning bool. + * \param [in] setter The class set method pointer, returning bool. + * \param [in] getter The class get functor method pointer. + */ + POFunction (bool (*setter)(T*, U), V (*getter)(T**)) + : AccessorHelper (), + m_setter (setter), + m_getter (getter) + {} +private: + virtual bool DoSet (T *object, const W *v) const { + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + ok = (*m_setter)(object, tmp); + return ok; + } + virtual bool DoGet (const T *object, W *v) const { + v->Set ((*m_getter)(object)); + return true; + } + virtual bool HasGetter (void) const { + return true; + } + virtual bool HasSetter (void) const { + return true; + } + bool (*m_setter)(T*, U); // The set method pointer, returning bool. + V (*m_getter)(T*); // The get functor method pointer. + }; + return Ptr (new POFunction (setter, getter), false); +} + + +/** + * \ingroup attributeimpl + * \copydoc ns3::DoMakeAccessorHelperTwo(bool(*)(T*, U),V(*)(T*)) + */ +template +inline +Ptr +DoMakeAccessorHelperTwo (V (*getter)(T*), bool (*setter)(T*, U)) +{ + return DoMakeAccessorHelperTwo (setter, getter); +} + +} // namespace ns3 + + +#endif // EXTENDED_ATTRIBUTE_HELPER_H \ No newline at end of file diff --git a/src/core/model/pair.cc b/src/core/model/pair.cc new file mode 100644 index 000000000..35a339971 --- /dev/null +++ b/src/core/model/pair.cc @@ -0,0 +1,27 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 + * Note: Need this file for library to be built + */ + +#include "pair.h" + +namespace ns3 { + + +} // namespace ns3 diff --git a/src/core/model/pair.h b/src/core/model/pair.h new file mode 100644 index 000000000..a5b3e0f37 --- /dev/null +++ b/src/core/model/pair.h @@ -0,0 +1,292 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 PAIR_H +#define PAIR_H + +#include +#include +#include + +#include +#include +#include +#include + +namespace ns3 { + +class AttributeChecker; + +// TODO(jared): useful to maybe define global to be the pair separator +// for serialization / deserialization? +template +std::ostream & +operator << (std::ostream &os, const std::pair &p) +{ + os << p.first << " " << p.second; + return os; +} + +// A = attribute value type, C = container type to return +template +class PairValue : public AttributeValue +{ +public: + typedef std::pair, Ptr > value_type; + typedef typename std::result_of::type first_type; + typedef typename std::result_of::type second_type; + typedef typename std::pair result_type; + typedef typename std::pair map_value_type; + + PairValue (); + PairValue (const result_type &value); // "import" constructor + + Ptr Copy (void) const; + + bool DeserializeFromString (std::string value, Ptr checker); + std::string SerializeToString (Ptr checker) const; + + result_type Get (void) const; + void Set (const result_type &value); + + template + bool GetAccessor (T &value) const; + +private: + value_type m_value; +}; + +template +class PairChecker : public AttributeChecker +{ +public: + typedef std::pair, Ptr > checker_pair_type; + + virtual void SetCheckers (Ptr firstchecker, Ptr secondchecker) = 0; + virtual checker_pair_type GetCheckers (void) const = 0; +}; + +template +Ptr > +MakePairChecker (const PairValue &value); + +template +Ptr > +MakePairChecker (Ptr firstchecker, Ptr secondchecker); + +template +Ptr > MakePairChecker (void); + +template +Ptr MakePairAccessor (T1 a1); + +} // namespace ns3 + +/***************************************************************************** + * Implementation below + *****************************************************************************/ + +namespace ns3 { + +namespace internal { + +template +class PairChecker : public ns3::PairChecker +{ +public: + PairChecker (void); + explicit PairChecker (Ptr firstchecker, Ptr secondchecker); + void SetCheckers (Ptr firstchecker, Ptr secondchecker); + typename ns3::PairChecker::checker_pair_type GetCheckers (void) const; + +private: + Ptr m_firstchecker; + Ptr m_secondchecker; +}; + +template +PairChecker::PairChecker (void) + : m_firstchecker (0) + , m_secondchecker (0) +{ + +} + +template +PairChecker::PairChecker (Ptr firstchecker, Ptr secondchecker) + : m_firstchecker (firstchecker) + , m_secondchecker (secondchecker) +{ + +} + +template +void +PairChecker::SetCheckers (Ptr firstchecker, Ptr secondchecker) +{ + m_firstchecker = firstchecker; + m_secondchecker = secondchecker; +} + +template +typename ns3::PairChecker::checker_pair_type +PairChecker::GetCheckers (void) const +{ + return std::make_pair (m_firstchecker, m_secondchecker); +} + +} // namespace internal + +template +Ptr > +MakePairChecker (const PairValue &value) +{ + return MakePairChecker (); +} + +template +Ptr > +MakePairChecker (Ptr firstchecker, Ptr secondchecker) +{ + auto checker = MakePairChecker (); + checker->SetCheckers (firstchecker, secondchecker); + return checker; +} + +template +Ptr > +MakePairChecker (void) +{ + std::string typeName, underlyingType; + typedef PairValue T; + std::string first_type_name = typeid (typename T::value_type::first_type).name (); + std::string second_type_name = typeid (typename T::value_type::second_type).name (); + { + std::ostringstream oss; + oss << "ns3::PairValue<" << first_type_name << ", " << second_type_name << ">"; + typeName = oss.str (); + } + + { + std::ostringstream oss; + oss << typeid (typename T::value_type).name (); + underlyingType = oss.str (); + } + + return DynamicCast > ( + MakeSimpleAttributeChecker > (typeName, underlyingType) + ); +} + +template +PairValue::PairValue () + : m_value (std::make_pair (Create (), Create ())) +{ + +} + +template +PairValue::PairValue (const typename PairValue::result_type &value) +{ + Set (value); +} + +template +Ptr +PairValue::Copy (void) const +{ + auto p = Create > (); + // deep copy if non-null + if (m_value.first) + p->m_value = std::make_pair (DynamicCast (m_value.first->Copy ()), + DynamicCast (m_value.second->Copy ())); + return p; +} + +template +bool +PairValue::DeserializeFromString (std::string value, Ptr checker) +{ + auto pchecker = DynamicCast > (checker); + if (!pchecker) return false; + + std::istringstream iss (value); // copies value + iss >> value; + auto first = pchecker->GetCheckers ().first->CreateValidValue (StringValue (value)); + if (!first) return false; + + auto firstattr = DynamicCast (first); + if (!firstattr) return false; + + iss >> value; + auto second = pchecker->GetCheckers ().second->CreateValidValue (StringValue (value)); + if (!second) return false; + + auto secondattr = DynamicCast (second); + if (!secondattr) return false; + + m_value = std::make_pair (firstattr, secondattr); + return true; +} + +template +std::string +PairValue::SerializeToString (Ptr checker) const +{ + std::ostringstream oss; + oss << m_value.first->SerializeToString (checker); + oss << " "; + oss << m_value.second->SerializeToString (checker); + + return oss.str (); +} + +template +typename PairValue::result_type +PairValue::Get (void) const +{ + return std::make_pair (m_value.first->Get (), m_value.second->Get ()); +} + +template +void +PairValue::Set (const typename PairValue::result_type &value) +{ + m_value = std::make_pair (Create (value.first), Create (value.second)); +} + +template +template +bool +PairValue::GetAccessor (T &value) const +{ + value = T (Get ()); + return true; +} + +template +Ptr MakePairAccessor (T1 a1) +{ + return MakeAccessorHelper > (a1); +} + +} // namespace ns3 + +#endif // PAIR_H \ No newline at end of file diff --git a/src/core/test/attribute-container-test-suite.cc b/src/core/test/attribute-container-test-suite.cc new file mode 100644 index 000000000..c5fab35f9 --- /dev/null +++ b/src/core/test/attribute-container-test-suite.cc @@ -0,0 +1,430 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("AttributeContainerTestSuite"); + +class AttributeContainerObject : public Object +{ +public: + AttributeContainerObject (); + virtual ~AttributeContainerObject (); + + void ReverseList (); + + static + TypeId GetTypeId (); + + friend std::ostream &operator <<(std::ostream &os, const AttributeContainerObject &obj); + +private: + std::list m_doublelist; + std::vector m_intvec; + // TODO(jared): need PairValue attributevalue to handle std::pair elements + std::map m_map; +}; + +AttributeContainerObject::AttributeContainerObject () +{ + +} + +AttributeContainerObject::~AttributeContainerObject () +{ + +} + +TypeId +AttributeContainerObject::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::AttributeContainerObject") + .SetParent () + .SetGroupName("Test") + .AddConstructor () + .AddAttribute ("DoubleList", "List of doubles", + AttributeContainerValue (), + MakeAttributeContainerAccessor (&AttributeContainerObject::m_doublelist), + MakeAttributeContainerChecker (MakeDoubleChecker ())) + .AddAttribute ("IntegerVector", "Vector of integers", + // the container value container differs from the underlying object + AttributeContainerValue (), + MakeAttributeContainerAccessor (&AttributeContainerObject::m_intvec), + MakeAttributeContainerChecker (MakeIntegerChecker ())) + .AddAttribute ("MapStringInt", "Map of strings to ints", + // the container value container differs from the underlying object + AttributeContainerValue > (), + MakeAttributeContainerAccessor > (&AttributeContainerObject::m_map), + MakeAttributeContainerChecker > ( + MakePairChecker (MakeStringChecker (), MakeIntegerChecker ()))) + ; + return tid; +} + +void +AttributeContainerObject::ReverseList () +{ + m_doublelist.reverse (); + std::vector tmp; + std::copy_backward (m_intvec.begin (), m_intvec.end (), tmp.begin ()); + m_intvec = tmp; +} + +std::ostream & +operator << (std::ostream &os, const AttributeContainerObject &obj) +{ + os << "AttributeContainerObject: "; + bool first = true; + for (auto d: obj.m_doublelist) + { + if (!first) os << ", "; + os << d; + first = false; + } + return os; +} + +// this handles mixed constness and compatible, yet +// distinct numerical classes (like int and long) +template +bool +operator ==(const std::pair &x, const std::pair &y) +{ + return x.first == y.first && x.second == y.second; +} + +/* Test instantiation, initialization, access */ +class AttributeContainerTestCase : public TestCase +{ +public: + AttributeContainerTestCase (); + virtual ~AttributeContainerTestCase () {} + +private: + virtual void DoRun (); +}; + +AttributeContainerTestCase::AttributeContainerTestCase () + : TestCase ("test instantiation, initialization, access") +{ + +} + +void +AttributeContainerTestCase::DoRun () +{ + { + std::list ref = {1.0, 2.1, 3.145269}; + + AttributeContainerValue ac (ref); + + NS_TEST_ASSERT_MSG_EQ (ref.size (), ac.GetN (), "Container size mismatch"); + auto aciter = ac.Begin (); + for (auto rend = ref.end (), + riter= ref.begin (); riter != rend; ++riter) + { + NS_TEST_ASSERT_MSG_NE (true, (aciter == ac.End ()), "AC iterator reached end"); + NS_TEST_ASSERT_MSG_EQ (*riter, (*aciter)->Get (), "Incorrect value"); + ++aciter; + } + NS_TEST_ASSERT_MSG_EQ (true, (aciter == ac.End ()), "AC iterator did not reach end"); + } + + { + std::vector ref = {-2, 3, 10, -1042}; + + AttributeContainerValue ac (ref.begin (), ref.end ()); + + NS_TEST_ASSERT_MSG_EQ (ref.size (), ac.GetN (), "Container size mismatch"); + auto aciter = ac.Begin (); + for (auto rend = ref.end (), + riter= ref.begin (); riter != rend; ++riter) + { + NS_TEST_ASSERT_MSG_NE (true, (aciter == ac.End ()), "AC iterator reached end"); + NS_TEST_ASSERT_MSG_EQ (*riter, (*aciter)->Get (), "Incorrect value"); + ++aciter; + } + NS_TEST_ASSERT_MSG_EQ (true, (aciter == ac.End ()), "AC iterator did not reach end"); + } + + { + auto ref = {"one", "two", "three"}; + AttributeContainerValue ac (ref.begin (), ref.end ()); + + NS_TEST_ASSERT_MSG_EQ (3, ac.GetN (), "Container size mismatch"); + auto aciter = ac.Begin (); + for (auto v: ref) + { + NS_TEST_ASSERT_MSG_NE (true, (aciter == ac.End ()), "AC iterator reached end"); + NS_TEST_ASSERT_MSG_EQ (v, (*aciter)->Get (), "Incorrect value"); + ++aciter; + } + NS_TEST_ASSERT_MSG_EQ (true, (aciter == ac.End ()), "AC iterator did not reach end"); + } + + { + auto ref = {"one", "two", "three"}; + AttributeContainerValue ac (ref); + + NS_TEST_ASSERT_MSG_EQ (3, ac.GetN (), "Container size mismatch"); + auto aciter = ac.Begin (); + for (auto v: ref) + { + NS_TEST_ASSERT_MSG_NE (true, (aciter == ac.End ()), "AC iterator reached end"); + NS_TEST_ASSERT_MSG_EQ (v, (*aciter)->Get (), "Incorrect value"); + ++aciter; + } + NS_TEST_ASSERT_MSG_EQ (true, (aciter == ac.End ()), "AC iterator did not reach end"); + } + + { + // use int64_t which is default for IntegerValue + std::map ref = { {"one", 1}, {"two", 2}, {"three", 3}}; + AttributeContainerValue > ac (ref); + + NS_TEST_ASSERT_MSG_EQ (3, ac.GetN (), "Container size mismatch"); + auto aciter = ac.Begin (); + for (auto v: ref) + { + NS_TEST_ASSERT_MSG_NE (true, (aciter == ac.End ()), "AC iterator reached end"); + NS_TEST_ASSERT_MSG_EQ (v, (*aciter)->Get (), "Incorrect value"); + ++aciter; + } + NS_TEST_ASSERT_MSG_EQ (true, (aciter == ac.End ()), "AC iterator did not reach end"); + + } +} + +// test serdes functions +class AttributeContainerSerializationTestCase : public TestCase +{ +public: + AttributeContainerSerializationTestCase (); + virtual ~AttributeContainerSerializationTestCase () {} + +private: + virtual void DoRun (void); +}; + +AttributeContainerSerializationTestCase::AttributeContainerSerializationTestCase () + : TestCase ("test serialization and deserialization") +{ + +} + +void +AttributeContainerSerializationTestCase::DoRun (void) +{ + { + // notice embedded spaces + std::string doubles = "1.0001, 20.53, -102.3"; + + AttributeContainerValue attr; + auto checker = MakeAttributeContainerChecker (attr); + //auto acchecker = DynamicCast > (checker); + checker->SetItemChecker (MakeDoubleChecker ()); + NS_TEST_ASSERT_MSG_EQ (attr.DeserializeFromString (doubles, checker), true, "Deserialize failed"); + NS_TEST_ASSERT_MSG_EQ (attr.GetN (), 3, "Incorrect container size"); + + std::string reserialized = attr.SerializeToString (checker); + std::string canonical = doubles; + canonical.erase (std::remove (canonical.begin (), canonical.end (), ' '), canonical.end ()); + NS_TEST_ASSERT_MSG_EQ (reserialized, canonical, "Reserialization failed"); + } + + { + // notice embedded spaces + std::string ints = "1, 2, -3, -4"; + + AttributeContainerValue attr; + auto checker = MakeAttributeContainerChecker (attr); + checker->SetItemChecker (MakeIntegerChecker ()); + NS_TEST_ASSERT_MSG_EQ (attr.DeserializeFromString (ints, checker), true, "Deserialize failed"); + NS_TEST_ASSERT_MSG_EQ (attr.GetN (), 4, "Incorrect container size"); + + std::string reserialized = attr.SerializeToString (checker); + std::string canonical = ints; + canonical.erase (std::remove (canonical.begin (), canonical.end (), ' '), canonical.end ()); + NS_TEST_ASSERT_MSG_EQ (reserialized, canonical, "Reserialization failed"); + } + + { + std::string strings = "this is a sentence with words"; + + AttributeContainerValue attr (' '); + auto checker = MakeAttributeContainerChecker (attr); + checker->SetItemChecker (MakeStringChecker ()); + NS_TEST_ASSERT_MSG_EQ (attr.DeserializeFromString (strings, checker), true, "Deserialize failed"); + NS_TEST_ASSERT_MSG_EQ (attr.GetN (), 6, "Incorrect container size"); + + std::string reserialized = attr.SerializeToString (checker); + std::string canonical = strings; + NS_TEST_ASSERT_MSG_EQ (reserialized, canonical, "Reserialization failed"); + } + + { + std::string pairs = "one 1,two 2,three 3"; + AttributeContainerValue > attr; + auto checker = MakeAttributeContainerChecker (attr); + checker->SetItemChecker (MakePairChecker ( + MakeStringChecker (), MakeIntegerChecker ())); + NS_TEST_ASSERT_MSG_EQ (attr.DeserializeFromString (pairs, checker), true, "Deserialization failed"); + NS_TEST_ASSERT_MSG_EQ (attr.GetN (), 3, "Incorrect container size"); + + std::string reserialized = attr.SerializeToString (checker); + std::string canonical = pairs; + NS_TEST_ASSERT_MSG_EQ (reserialized, canonical, "Reserealization failed"); + + } +} + +class AttributeContainerSetGetTestCase : public TestCase +{ +public: + AttributeContainerSetGetTestCase (); + virtual ~AttributeContainerSetGetTestCase () {} + +private: + virtual void DoRun (void); +}; + +AttributeContainerSetGetTestCase::AttributeContainerSetGetTestCase () + : TestCase ("test attribute set and get") +{ + +} + +void +AttributeContainerSetGetTestCase::DoRun (void) +{ + Ptr obj = CreateObject (); + { + std::ostringstream oss; + oss << *obj; + NS_TEST_ASSERT_MSG_EQ (oss.str (), "AttributeContainerObject: ", "DoubleList initialized incorrectly"); + } + + std::list doubles = {1.1, 2.22, 3.333}; + obj->SetAttribute ("DoubleList", AttributeContainerValue (doubles)); + { + std::ostringstream oss; + oss << *obj; + NS_TEST_ASSERT_MSG_EQ (oss.str (), "AttributeContainerObject: 1.1, 2.22, 3.333", "DoubleList incorrectly set"); + } + + obj->ReverseList (); + { + std::ostringstream oss; + oss << *obj; + NS_TEST_ASSERT_MSG_EQ (oss.str (), "AttributeContainerObject: 3.333, 2.22, 1.1", "DoubleList incorrectly reversed"); + + // NOTE: changing the return container here too! + AttributeContainerValue value; + obj->GetAttribute ("DoubleList", value); + NS_TEST_ASSERT_MSG_EQ (doubles.size (), value.GetN (), "AttributeContainerValue wrong size"); + + AttributeContainerValue::result_type doublevec = value.Get (); + NS_TEST_ASSERT_MSG_EQ (doubles.size (), doublevec.size (), "DoublesVec wrong size"); + auto iter = doubles.rbegin (); + for (auto d: doublevec) + { + NS_TEST_ASSERT_MSG_EQ (d, *iter, "Incorrect value in doublesvec"); + ++iter; + } + } + + std::vector ints = {-1, 0, 1, 2, 3}; + // NOTE: here the underlying attribute container type differs from the actual container + obj->SetAttribute ("IntegerVector", AttributeContainerValue (ints)); + + { + // NOTE: changing the container here too! + AttributeContainerValue value; + obj->GetAttribute ("IntegerVector", value); + NS_TEST_ASSERT_MSG_EQ (ints.size (), value.GetN (), "AttributeContainerValue wrong size"); + + AttributeContainerValue::result_type intlist = value.Get (); + NS_TEST_ASSERT_MSG_EQ (ints.size (), intlist.size (), "Intvec wrong size"); + auto iter = ints.begin (); + for (auto d: intlist) + { + NS_TEST_ASSERT_MSG_EQ (d, *iter, "Incorrect value in intvec"); + ++iter; + } + } + + std::map map = { {"one", 1}, {"two", 2}, {"three", 3}}; + obj->SetAttribute ("MapStringInt", AttributeContainerValue > (map)); + + { + AttributeContainerValue > value; + obj->GetAttribute ("MapStringInt", value); + NS_TEST_ASSERT_MSG_EQ (map.size (), value.GetN (), "AttributeContainerValue wrong size"); + + // could possibly make custom assignment operator to make assignment statement work + std::map mapstrint; + auto lst = value.Get (); + for (auto l: lst) mapstrint[l.first] = l.second; + + NS_TEST_ASSERT_MSG_EQ (map.size (), mapstrint.size (), "mapstrint wrong size"); + auto iter = map.begin (); + for (auto v: mapstrint) + { + NS_TEST_ASSERT_MSG_EQ (v, *iter, "Incorrect value in mapstrint"); + ++iter; + } + } +} + +class AttributeContainerTestSuite : public TestSuite +{ + public: + AttributeContainerTestSuite (); +}; + +AttributeContainerTestSuite::AttributeContainerTestSuite () + : TestSuite ("attribute-container-test-suite", UNIT) +{ + AddTestCase (new AttributeContainerTestCase (), TestCase::QUICK); + AddTestCase (new AttributeContainerSerializationTestCase (), TestCase::QUICK); + AddTestCase (new AttributeContainerSetGetTestCase (), TestCase::QUICK); +} + +static AttributeContainerTestSuite AttributeContainerTestSuite; //!< Static variable for test initialization diff --git a/src/core/test/pair-value-test-suite.cc b/src/core/test/pair-value-test-suite.cc new file mode 100644 index 000000000..974f960d3 --- /dev/null +++ b/src/core/test/pair-value-test-suite.cc @@ -0,0 +1,179 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2018 WPL, Inc. + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("PairTestSuite"); + +class PairObject : public Object +{ +public: + PairObject (); + virtual ~PairObject (); + + static + TypeId GetTypeId (); + + friend std::ostream &operator <<(std::ostream &os, const PairObject &obj); + +private: + std::pair m_stringpair; + std::pair m_addresspair; +}; + +PairObject::PairObject () +{ + +} + +PairObject::~PairObject () +{ + +} + +TypeId +PairObject::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::PairObject") + .SetParent () + .SetGroupName("Test") + .AddConstructor () + .AddAttribute ("StringPair", "Pair: string, string", + PairValue (), + MakePairAccessor (&PairObject::m_stringpair), + MakePairChecker (MakeStringChecker (), MakeStringChecker ())) + .AddAttribute ("AddressPair", "Pair: address int", + // the container value container differs from the underlying object + PairValue (), + MakePairAccessor (&PairObject::m_addresspair), + MakePairChecker (MakeAddressChecker (), MakeIntegerChecker ())) + ; + return tid; +} + +std::ostream & +operator << (std::ostream &os, const PairObject &obj) +{ + os << "StringPair = { " << obj.m_stringpair << " } "; + os << "AddressPair = { " << obj.m_addresspair << " }"; + return os; +} + +/* Test instantiation, initialization, access */ +class PairValueTestCase : public TestCase +{ +public: + PairValueTestCase (); + virtual ~PairValueTestCase () {} + +private: + virtual void DoRun (); +}; + +PairValueTestCase::PairValueTestCase () + : TestCase ("test instantiation, initialization, access") +{ + +} + +void +PairValueTestCase::DoRun () +{ + { + std::pair ref = {1, 2.4}; + + PairValue ac (ref); + + std::pair rv = ac.Get (); + NS_TEST_ASSERT_MSG_EQ (rv, ref, "Attribute value does not equal original"); + } + + { + std::pair ref = {"hello", Mac48Address::Allocate ()}; + + PairValue ac; + ac.Set (ref); + std::pair rv = ac.Get (); + NS_TEST_ASSERT_MSG_EQ (rv, ref, "Attribute value does not equal original"); + } + +} + +class PairValueSettingsTestCase : public TestCase +{ +public: + PairValueSettingsTestCase (); + + void DoRun (); +}; + +PairValueSettingsTestCase::PairValueSettingsTestCase () + : TestCase ("test setting through attribute interface") +{} + +void +PairValueSettingsTestCase::DoRun () +{ + Address addr = Mac48Address::Allocate (); + + auto p = CreateObject (); + p->SetAttribute ("StringPair", PairValue (std::make_pair ("hello", "world"))); + p->SetAttribute ("AddressPair", PairValue (std::make_pair (addr, 31))); + + std::ostringstream oss, ref; + oss << *p; + + ref << "StringPair = { hello world } AddressPair = { " << addr << " 31 }"; + + NS_TEST_ASSERT_MSG_EQ ((oss.str ()), (ref.str ()), "Pairs not correctly set"); +} + +class PairValueTestSuite : public TestSuite +{ + public: + PairValueTestSuite (); +}; + +PairValueTestSuite::PairValueTestSuite () + : TestSuite ("pair-value-test-suite", UNIT) +{ + AddTestCase (new PairValueTestCase (), TestCase::QUICK); + AddTestCase (new PairValueSettingsTestCase (), TestCase::QUICK); +} + +static PairValueTestSuite pairValueTestSuite; //!< Static variable for test initialization diff --git a/src/core/wscript b/src/core/wscript index 9dd0a5c33..fda2e117f 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -101,6 +101,10 @@ def configure(conf): conf.check_nonfatal(header_name='sys/stat.h', define_name='HAVE_SYS_STAT_H') conf.check_nonfatal(header_name='dirent.h', define_name='HAVE_DIRENT_H') + if conf.check_nonfatal(header_name='stdlib.h'): + conf.define('HAVE_STDLIB_H', 1) + conf.define('HAVE_GETENV', 1) + conf.check_nonfatal(header_name='signal.h', define_name='HAVE_SIGNAL_H') # Check for POSIX threads @@ -240,6 +244,8 @@ def build(bld): 'model/show-progress.cc', 'model/system-wall-clock-timestamp.cc', 'model/version.cc', + 'model/attribute-container.cc', + 'model/pair.cc', ] if (bld.env['ENABLE_EXAMPLES']): @@ -271,11 +277,6 @@ def build(bld): 'test/type-id-test-suite.cc', ] - if (bld.env['ENABLE_EXAMPLES']): - core_test.source.extend([ - 'test/examples-as-tests-test-suite.cc', - ]) - headers = bld(features='ns3header') headers.module = 'core' headers.source = [ @@ -290,7 +291,6 @@ def build(bld): 'model/map-scheduler.h', 'model/heap-scheduler.h', 'model/calendar-scheduler.h', - 'model/priority-queue-scheduler.h', 'model/simulation-singleton.h', 'model/singleton.h', 'model/timer.h', @@ -299,7 +299,6 @@ def build(bld): 'model/synchronizer.h', 'model/make-event.h', 'model/system-wall-clock-ms.h', - 'model/system-wall-clock-timestamp.h', 'model/empty.h', 'model/callback.h', 'model/object-base.h', @@ -369,6 +368,10 @@ def build(bld): 'model/time-printer.h', 'model/show-progress.h', 'model/version.h', + 'model/pair.h', + 'model/attribute-container-accessor-helper.h', + 'model/attribute-container.h', + 'model/extended-attribute-helper.h', ] if (bld.env['ENABLE_EXAMPLES']):