A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
attribute-container.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Caliola Engineering, LLC.
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Jared Dulmage <jared.dulmage@caliola.com>
7 */
8
9#ifndef ATTRIBUTE_CONTAINER_H
10#define ATTRIBUTE_CONTAINER_H
11
12#include "attribute-helper.h"
13#include "string.h"
14
15#include <algorithm>
16#include <iterator>
17#include <list>
18#include <sstream>
19#include <type_traits>
20#include <typeinfo>
21#include <utility>
22
23namespace ns3
24{
25
26/*!
27 * @ingroup attributes
28 * @addtogroup attribute_AttributeContainer AttributeContainer Attribute
29 * AttributeValue implementation for AttributeContainer
30 */
31
32class AttributeChecker;
33
34// A = attribute value type, C = container type to return
35/**
36 * @ingroup attribute_AttributeContainer
37 *
38 * A container for one type of attribute.
39 *
40 * The container uses \p A to parse items into elements.
41 * Internally the container is always a list but an instance
42 * can return the items in a container specified by \p C.
43 *
44 * @tparam A AttributeValue type to be contained.
45 * @tparam Sep Character separator between elements for parsing.
46 * @tparam C Possibly templated container class returned by Get.
47 */
48template <class A, char Sep = ',', template <class...> class C = std::list>
50{
51 public:
52 /** AttributeValue (element) type. */
53 typedef A attribute_type;
54 /** Type actually stored within the container. */
56 /** Internal container type. */
57 typedef std::list<value_type> container_type;
58 /** stl-style Const iterator type. */
59 typedef typename container_type::const_iterator const_iterator;
60 /** stl-style Non-const iterator type. */
61 typedef typename container_type::iterator iterator;
62 /** Size type for container. */
63 typedef typename container_type::size_type size_type;
64 /** NS3 style iterator type. */
66
67 // use underlying AttributeValue to get return element type
68 /** Item type of container returned by Get. */
69 typedef typename std::invoke_result_t<decltype(&A::Get), A> item_type;
70 /** Type of container returned. */
71 typedef C<item_type> result_type;
72
73 /**
74 * Default constructor.
75 */
77
78 /**
79 * Construct from another container.
80 * @tparam CONTAINER \deduced type of container passed for initialization.
81 * @param c Instance of CONTAINER with which to initialize AttributeContainerValue.
82 */
83 template <class CONTAINER>
84 AttributeContainerValue(const CONTAINER& c);
85
86 /**
87 * Construct from iterators.
88 * @tparam ITER \deduced type of iterator.
89 * \param[in] begin Iterator that points to first initialization item.
90 * \param[in] end Iterator that points ones past last initialization item.
91 */
92 template <class ITER>
93 AttributeContainerValue(const ITER begin, const ITER end);
94
95 /** Destructor. */
96 ~AttributeContainerValue() override;
97
98 // Inherited
99 Ptr<AttributeValue> Copy() const override;
100 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
101 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
102
103 // defacto pure virtuals to integrate with built-in accessor code
104 /**
105 * Return a container of items.
106 * @return Container of items.
107 */
108 result_type Get() const;
109 /**
110 * Copy items from container c.
111 *
112 * This method assumes \p c has stl-style begin and end methods.
113 * The AttributeContainerValue value is cleared before copying from \p c.
114 * @tparam T type of container.
115 * @param c Container from which to copy items.
116 */
117 template <class T>
118 void Set(const T& c);
119 /**
120 * Set the given variable to the values stored by this TupleValue object.
121 *
122 * @tparam T \deduced the type of the given variable (normally, the argument type
123 * of a set method or the type of a data member)
124 * @param value the given variable
125 * @return true if the given variable was set
126 */
127 template <typename T>
128 bool GetAccessor(T& value) const;
129
130 // NS3 interface
131 /**
132 * NS3-style Number of items.
133 * @return Number of items in container.
134 */
135 size_type GetN() const;
136 /**
137 * NS3-style beginning of container.
138 * @return Iterator pointing to first time in container.
139 */
140 Iterator Begin();
141 /**
142 * NS3-style ending of container.
143 * @return Iterator pointing one past last item of container.
144 */
145 Iterator End();
146
147 // STL-interface
148 /**
149 * STL-style number of items in container
150 * @return number of items in container.
151 */
152 size_type size() const;
153 /**
154 * STL-style beginning of container.
155 * @return Iterator pointing to first item in container.
156 */
157 iterator begin();
158 /**
159 * STL-style end of container.
160 * @return Iterator pointing to one past last item in container.
161 */
162 iterator end();
163 /**
164 * STL-style const beginning of container.
165 * @return Const iterator pointing to first item in container.
166 */
167 const_iterator begin() const;
168 /**
169 * STL-style const end of container.
170 * @return Const iterator pointing to one past last item in container.
171 */
172 const_iterator end() const;
173
174 private:
175 /**
176 * Copy items from \ref begin to \ref end.
177 *
178 * The internal container is cleared before values are copied
179 * using the push_back method.
180 * @tparam ITER \deduced iterator type
181 * \param[in] begin Points to first item to copy
182 * \param[in] end Points to one after last item to copy
183 */
184 template <class ITER>
185 inline void CopyFrom(const ITER begin, const ITER end);
186
187 container_type m_container; //!< Internal container
188};
189
190/*!
191 * @ingroup attribute_AttributeContainer
192 *
193 * @class ns3::AttributeContainerChecker "attribute-container.h"
194 * AttributeChecker implementation for AttributeContainerValue.
195 * @see AttributeChecker
196 */
198{
199 public:
200 /**
201 * Set the item checker
202 * @param itemchecker The item checker
203 */
204 virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
205 /**
206 * Get the item checker
207 * @return The item checker
208 */
210};
211
212/**
213 * @ingroup attribute_AttributeContainer
214 *
215 * Make AttributeContainerChecker from AttributeContainerValue.
216 * @tparam A \deduced AttributeValue type in container.
217 * @tparam Sep \deduced Character separator between elements for parsing.
218 * @tparam C \deduced Container type returned by Get.
219 * \param[in] value AttributeContainerValue from which to deduce types.
220 * @return AttributeContainerChecker for value.
221 */
222template <class A, char Sep, template <class...> class C>
225
226/**
227 * @ingroup attribute_AttributeContainer
228 *
229 * Make AttributeContainerChecker using explicit types, initialize item checker.
230 * @tparam A AttributeValue type in container.
231 * @tparam Sep Character separator between elements for parsing.
232 * @tparam C Container type returned by Get.
233 * \param[in] itemchecker AttributeChecker used for each item in the container.
234 * @return AttributeContainerChecker.
235 */
236template <class A, char Sep = ',', template <class...> class C = std::list>
238
239/**
240 * @ingroup attribute_AttributeContainer
241 *
242 * Make uninitialized AttributeContainerChecker using explicit types.
243 * @tparam A AttributeValue type in container.
244 * @tparam Sep Character separator between elements for parsing.
245 * @tparam C Container type returned by Get.
246 * @return AttributeContainerChecker.
247 */
248template <class A, char Sep = ',', template <class...> class C = std::list>
250
251/**
252 * @ingroup attribute_AttributeContainer
253 *
254 * Make AttributeContainerAccessor using explicit types.
255 * @tparam A AttributeValue type in container.
256 * @tparam Sep Character separator between elements for parsing.
257 * @tparam C Container type returned by Get.
258 * @tparam T1 \deduced The type of the class data member,
259 * or the type of the class get functor or set method.
260 * @param [in] a1 The address of the data member,
261 * or the get or set method.
262 * @return AttributeContainerAccessor.
263 */
264template <typename A, char Sep = ',', template <typename...> class C = std::list, typename T1>
266
267/**
268 * @ingroup attribute_AttributeContainer
269 *
270 * Make AttributeContainerAccessor using explicit types.
271 * @tparam A AttributeValue type in container.
272 * @tparam Sep Character separator between elements for parsing.
273 * @tparam C Container type returned by Get.
274 * @tparam T1 \deduced The type of the class data member,
275 * or the type of the class get functor or set method.
276 *
277 * @tparam T2 \deduced The type of the getter class functor method.
278 * @param [in] a2 The address of the class method to set the attribute.
279 * @param [in] a1 The address of the data member,
280 * or the get or set method.
281 * @return AttributeContainerAccessor.
282 */
283template <typename A,
284 char Sep = ',',
285 template <typename...> class C = std::list,
286 typename T1,
287 typename T2>
289
290} // namespace ns3
291
292/*****************************************************************************
293 * Implementation below
294 *****************************************************************************/
295
296namespace ns3
297{
298
299namespace internal
300{
301
302/**
303 * @ingroup attribute_AttributeContainer
304 *
305 * @internal
306 *
307 * Templated AttributeContainerChecker class that is instantiated
308 * in MakeAttributeContainerChecker. The non-templated base ns3::AttributeContainerChecker
309 * is returned from that function. This is the same pattern as ObjectPtrContainer.
310 */
311template <class A, char Sep, template <class...> class C>
313{
314 public:
316 /**
317 * Explicit constructor
318 * @param itemchecker The AttributeChecker.
319 */
321 void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
323
324 private:
326};
327
328template <class A, char Sep, template <class...> class C>
333
334template <class A, char Sep, template <class...> class C>
336 Ptr<const AttributeChecker> itemchecker)
337 : m_itemchecker(itemchecker)
338{
339}
340
341template <class A, char Sep, template <class...> class C>
342void
344{
345 m_itemchecker = itemchecker;
346}
347
348template <class A, char Sep, template <class...> class C>
351{
352 return m_itemchecker;
353}
354
355} // namespace internal
356
357template <class A, char Sep, template <class...> class C>
363
364template <class A, char Sep, template <class...> class C>
365Ptr<const AttributeChecker>
367{
369 auto acchecker = DynamicCast<AttributeContainerChecker>(checker);
370 acchecker->SetItemChecker(itemchecker);
371 return checker;
372}
373
374template <class A, char Sep, template <class...> class C>
375Ptr<AttributeChecker>
377{
378 std::string containerType;
379 std::string underlyingType;
381 {
382 std::ostringstream oss;
383 oss << "ns3::AttributeContainerValue<" << typeid(typename T::attribute_type).name() << ", "
384 << typeid(typename T::container_type).name() << ">";
385 containerType = oss.str();
386 }
387
388 {
389 std::ostringstream oss;
390 oss << "ns3::Ptr<" << typeid(typename T::attribute_type).name() << ">";
391 underlyingType = oss.str();
392 }
393
395 containerType,
396 underlyingType);
397}
398
399template <class A, char Sep, template <class...> class C>
403
404template <class A, char Sep, template <class...> class C>
405template <class CONTAINER>
407 : AttributeContainerValue<A, Sep, C>(c.begin(), c.end())
408{
409}
410
411template <class A, char Sep, template <class...> class C>
412template <class ITER>
418
419template <class A, char Sep, template <class...> class C>
424
425template <class A, char Sep, template <class...> class C>
428{
430 c->m_container = m_container;
431 return c;
432}
433
434template <class A, char Sep, template <class...> class C>
435bool
438{
439 auto acchecker = DynamicCast<const AttributeContainerChecker>(checker);
440 if (!acchecker)
441 {
442 return false;
443 }
444
445 std::istringstream iss(value); // copies value
446 while (std::getline(iss, value, Sep))
447 {
448 auto avalue = acchecker->GetItemChecker()->CreateValidValue(StringValue(value));
449 if (!avalue)
450 {
451 return false;
452 }
453
454 auto attr = DynamicCast<A>(avalue);
455 if (!attr)
456 {
457 return false;
458 }
459
460 // TODO(jared): make insertion more generic?
461 m_container.push_back(attr);
462 }
463 return true;
464}
465
466template <class A, char Sep, template <class...> class C>
467std::string
469{
470 std::ostringstream oss;
471 bool first = true;
472 for (auto attr : *this)
473 {
474 if (!first)
475 {
476 oss << Sep;
477 }
478 oss << attr->SerializeToString(checker);
479 first = false;
480 }
481 return oss.str();
482}
483
484template <class A, char Sep, template <class...> class C>
487{
488 result_type c;
489 for (const value_type& a : *this)
490 {
491 c.insert(c.end(), a->Get());
492 }
493 return c;
494}
495
496template <class A, char Sep, template <class...> class C>
497template <typename T>
498bool
500{
501 result_type src = Get();
502 value.clear();
503 std::copy(src.begin(), src.end(), std::inserter(value, value.end()));
504 return true;
505}
506
507template <class A, char Sep, template <class...> class C>
508template <class T>
509void
511{
512 m_container.clear();
513 CopyFrom(c.begin(), c.end());
514}
515
516template <class A, char Sep, template <class...> class C>
519{
520 return size();
521}
522
523template <class A, char Sep, template <class...> class C>
526{
527 return begin();
528}
529
530template <class A, char Sep, template <class...> class C>
533{
534 return end();
535}
536
537template <class A, char Sep, template <class...> class C>
540{
541 return m_container.size();
542}
543
544template <class A, char Sep, template <class...> class C>
547{
548 return m_container.begin();
549}
550
551template <class A, char Sep, template <class...> class C>
554{
555 return m_container.end();
556}
557
558template <class A, char Sep, template <class...> class C>
561{
562 return m_container.cbegin();
563}
564
565template <class A, char Sep, template <class...> class C>
568{
569 return m_container.cend();
570}
571
572template <class A, char Sep, template <class...> class C>
573template <class ITER>
574void
575AttributeContainerValue<A, Sep, C>::CopyFrom(const ITER begin, const ITER end)
576{
577 for (ITER iter = begin; iter != end; ++iter)
578 {
579 m_container.push_back(Create<A>(*iter));
580 }
581}
582
583template <typename A, char Sep, template <typename...> class C, typename T1>
589
590template <typename A, char Sep, template <typename...> class C, typename T1, typename T2>
591Ptr<const AttributeAccessor>
596
597} // namespace ns3
598
599#endif // ATTRIBUTE_CONTAINER_H
Attribute helper (ATTRIBUTE_ )macros definition.
Represent the type of an attribute.
Definition attribute.h:157
AttributeChecker implementation for AttributeContainerValue.
virtual Ptr< const AttributeChecker > GetItemChecker() const =0
Get the item checker.
virtual void SetItemChecker(Ptr< const AttributeChecker > itemchecker)=0
Set the item checker.
A container for one type of attribute.
AttributeContainerValue::const_iterator Iterator
NS3 style iterator type.
container_type::size_type size_type
Size type for container.
container_type::iterator iterator
stl-style Non-const iterator type.
void CopyFrom(const ITER begin, const ITER end)
Copy items from begin to end.
std::list< value_type > container_type
Internal container type.
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
Iterator End()
NS3-style ending of container.
size_type GetN() const
NS3-style Number of items.
iterator end()
STL-style end of container.
container_type::const_iterator const_iterator
stl-style Const iterator type.
Ptr< A > value_type
Type actually stored within the container.
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
C< item_type > result_type
Type of container returned.
container_type m_container
Internal container.
AttributeContainerValue()
Default constructor.
result_type Get() const
Return a container of items.
A attribute_type
AttributeValue (element) type.
void Set(const T &c)
Copy items from container c.
Iterator Begin()
NS3-style beginning of container.
Ptr< AttributeValue > Copy() const override
std::invoke_result_t< decltype(&A::Get), A > item_type
Item type of container returned by Get.
size_type size() const
STL-style number of items in container.
iterator begin()
STL-style beginning of container.
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
~AttributeContainerValue() override
Destructor.
Hold a value for an Attribute.
Definition attribute.h:59
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
Ptr< const AttributeChecker > GetItemChecker() const override
Get the item checker.
Ptr< const AttributeChecker > m_itemchecker
The AttributeChecker.
void SetItemChecker(Ptr< const AttributeChecker > itemchecker) override
Set the item checker.
Ptr< AttributeChecker > MakeAttributeContainerChecker()
Make uninitialized AttributeContainerChecker using explicit types.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< const AttributeAccessor > MakeAccessorHelper(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< AttributeChecker > MakeSimpleAttributeChecker(std::string name, std::string underlying)
A simple string-based attribute checker.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
ns3::StringValue attribute value declarations.