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 * \return This object with items copied.
184 */
185 template <class ITER>
186 inline Ptr<AttributeContainerValue<A, Sep, C>> CopyFrom(const ITER begin, const ITER end);
187
188 container_type m_container; //!< Internal container
189};
190
191/*!
192 * \ingroup attribute_AttributeContainer
193 *
194 * \class ns3::AttributeContainerChecker "attribute-container.h"
195 * AttributeChecker implementation for AttributeContainerValue.
196 * \see AttributeChecker
197 */
199{
200 public:
201 /**
202 * Set the item checker
203 * \param itemchecker The item checker
204 */
205 virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
206 /**
207 * Get the item checker
208 * \return The item checker
209 */
211};
212
213/**
214 * \ingroup attribute_AttributeContainer
215 *
216 * Make AttributeContainerChecker from AttributeContainerValue.
217 * @tparam A \deduced AttributeValue type in container.
218 * @tparam Sep \deduced Character separator between elements for parsing.
219 * @tparam C \deduced Container type returned by Get.
220 * \param[in] value AttributeContainerValue from which to deduce types.
221 * \return AttributeContainerChecker for value.
222 */
223template <class A, char Sep, template <class...> class C>
226
227/**
228 * \ingroup attribute_AttributeContainer
229 *
230 * Make AttributeContainerChecker using explicit types, initialize item checker.
231 * @tparam A AttributeValue type in container.
232 * @tparam Sep Character separator between elements for parsing.
233 * @tparam C Container type returned by Get.
234 * \param[in] itemchecker AttributeChecker used for each item in the container.
235 * \return AttributeContainerChecker.
236 */
237template <class A, char Sep = ',', template <class...> class C = std::list>
239
240/**
241 * \ingroup attribute_AttributeContainer
242 *
243 * Make uninitialized AttributeContainerChecker using explicit types.
244 * @tparam A AttributeValue type in container.
245 * @tparam Sep Character separator between elements for parsing.
246 * @tparam C Container type returned by Get.
247 * \return AttributeContainerChecker.
248 */
249template <class A, char Sep = ',', template <class...> class C = std::list>
251
252/**
253 * \ingroup attribute_AttributeContainer
254 *
255 * Make AttributeContainerAccessor using explicit types.
256 * @tparam A AttributeValue type in container.
257 * @tparam Sep Character separator between elements for parsing.
258 * @tparam C Container type returned by Get.
259 * \tparam T1 \deduced The type of the class data member,
260 * or the type of the class get functor or set method.
261 * \param [in] a1 The address of the data member,
262 * or the get or set method.
263 * \return AttributeContainerAccessor.
264 */
265template <typename A, char Sep = ',', template <typename...> class C = std::list, typename T1>
267
268/**
269 * \ingroup attribute_AttributeContainer
270 *
271 * Make AttributeContainerAccessor using explicit types.
272 * @tparam A AttributeValue type in container.
273 * @tparam Sep Character separator between elements for parsing.
274 * @tparam C Container type returned by Get.
275 * \tparam T1 \deduced The type of the class data member,
276 * or the type of the class get functor or set method.
277 *
278 * \tparam T2 \deduced The type of the getter class functor method.
279 * \param [in] a2 The address of the class method to set the attribute.
280 * \param [in] a1 The address of the data member,
281 * or the get or set method.
282 * \return AttributeContainerAccessor.
283 */
284template <typename A,
285 char Sep = ',',
286 template <typename...> class C = std::list,
287 typename T1,
288 typename T2>
290
291} // namespace ns3
292
293/*****************************************************************************
294 * Implementation below
295 *****************************************************************************/
296
297namespace ns3
298{
299
300namespace internal
301{
302
303/**
304 * \ingroup attribute_AttributeContainer
305 *
306 * \internal
307 *
308 * Templated AttributeContainerChecker class that is instantiated
309 * in MakeAttributeContainerChecker. The non-templated base ns3::AttributeContainerChecker
310 * is returned from that function. This is the same pattern as ObjectPtrContainer.
311 */
312template <class A, char Sep, template <class...> class C>
314{
315 public:
317 /**
318 * Explicit constructor
319 * \param itemchecker The AttributeChecker.
320 */
322 void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
324
325 private:
327};
328
329template <class A, char Sep, template <class...> class C>
334
335template <class A, char Sep, template <class...> class C>
337 Ptr<const AttributeChecker> itemchecker)
338 : m_itemchecker(itemchecker)
339{
340}
341
342template <class A, char Sep, template <class...> class C>
343void
345{
346 m_itemchecker = itemchecker;
347}
348
349template <class A, char Sep, template <class...> class C>
352{
353 return m_itemchecker;
354}
355
356} // namespace internal
357
358template <class A, char Sep, template <class...> class C>
364
365template <class A, char Sep, template <class...> class C>
366Ptr<const AttributeChecker>
368{
370 auto acchecker = DynamicCast<AttributeContainerChecker>(checker);
371 acchecker->SetItemChecker(itemchecker);
372 return checker;
373}
374
375template <class A, char Sep, template <class...> class C>
376Ptr<AttributeChecker>
378{
379 std::string containerType;
380 std::string underlyingType;
382 {
383 std::ostringstream oss;
384 oss << "ns3::AttributeContainerValue<" << typeid(typename T::attribute_type).name() << ", "
385 << typeid(typename T::container_type).name() << ">";
386 containerType = oss.str();
387 }
388
389 {
390 std::ostringstream oss;
391 oss << "ns3::Ptr<" << typeid(typename T::attribute_type).name() << ">";
392 underlyingType = oss.str();
393 }
394
396 containerType,
397 underlyingType);
398}
399
400template <class A, char Sep, template <class...> class C>
404
405template <class A, char Sep, template <class...> class C>
406template <class CONTAINER>
408 : AttributeContainerValue<A, Sep, C>(c.begin(), c.end())
409{
410}
411
412template <class A, char Sep, template <class...> class C>
413template <class ITER>
419
420template <class A, char Sep, template <class...> class C>
425
426template <class A, char Sep, template <class...> class C>
429{
431 c->m_container = m_container;
432 return c;
433}
434
435template <class A, char Sep, template <class...> class C>
436bool
439{
440 auto acchecker = DynamicCast<const AttributeContainerChecker>(checker);
441 if (!acchecker)
442 {
443 return false;
444 }
445
446 std::istringstream iss(value); // copies value
447 while (std::getline(iss, value, Sep))
448 {
449 auto avalue = acchecker->GetItemChecker()->CreateValidValue(StringValue(value));
450 if (!avalue)
451 {
452 return false;
453 }
454
455 auto attr = DynamicCast<A>(avalue);
456 if (!attr)
457 {
458 return false;
459 }
460
461 // TODO(jared): make insertion more generic?
462 m_container.push_back(attr);
463 }
464 return true;
465}
466
467template <class A, char Sep, template <class...> class C>
468std::string
470{
471 std::ostringstream oss;
472 bool first = true;
473 for (auto attr : *this)
474 {
475 if (!first)
476 {
477 oss << Sep;
478 }
479 oss << attr->SerializeToString(checker);
480 first = false;
481 }
482 return oss.str();
483}
484
485template <class A, char Sep, template <class...> class C>
488{
489 result_type c;
490 for (const value_type& a : *this)
491 {
492 c.insert(c.end(), a->Get());
493 }
494 return c;
495}
496
497template <class A, char Sep, template <class...> class C>
498template <typename T>
499bool
501{
502 result_type src = Get();
503 value.clear();
504 std::copy(src.begin(), src.end(), std::inserter(value, value.end()));
505 return true;
506}
507
508template <class A, char Sep, template <class...> class C>
509template <class T>
510void
512{
513 m_container.clear();
514 CopyFrom(c.begin(), c.end());
515}
516
517template <class A, char Sep, template <class...> class C>
520{
521 return size();
522}
523
524template <class A, char Sep, template <class...> class C>
527{
528 return begin();
529}
530
531template <class A, char Sep, template <class...> class C>
534{
535 return end();
536}
537
538template <class A, char Sep, template <class...> class C>
541{
542 return m_container.size();
543}
544
545template <class A, char Sep, template <class...> class C>
548{
549 return m_container.begin();
550}
551
552template <class A, char Sep, template <class...> class C>
555{
556 return m_container.end();
557}
558
559template <class A, char Sep, template <class...> class C>
562{
563 return m_container.cbegin();
564}
565
566template <class A, char Sep, template <class...> class C>
569{
570 return m_container.cend();
571}
572
573template <class A, char Sep, template <class...> class C>
574template <class ITER>
576AttributeContainerValue<A, Sep, C>::CopyFrom(const ITER begin, const ITER end)
577{
578 for (ITER iter = begin; iter != end; ++iter)
579 {
580 m_container.push_back(Create<A>(*iter));
581 }
582 return this;
583}
584
585template <typename A, char Sep, template <typename...> class C, typename T1>
591
592template <typename A, char Sep, template <typename...> class C, typename T1, typename T2>
593Ptr<const AttributeAccessor>
598
599} // namespace ns3
600
601#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.
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.
Ptr< AttributeContainerValue< A, Sep, C > > CopyFrom(const ITER begin, const ITER end)
Copy items from begin to end.
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.