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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Jared Dulmage <jared.dulmage@caliola.com>
18 */
19
20#ifndef ATTRIBUTE_CONTAINER_H
21#define ATTRIBUTE_CONTAINER_H
22
23#include "attribute-helper.h"
24#include "string.h"
25
26#include <algorithm>
27#include <iterator>
28#include <list>
29#include <sstream>
30#include <type_traits>
31#include <typeinfo>
32#include <utility>
33
34namespace ns3
35{
36
37/*!
38 * \ingroup attributes
39 * \addtogroup attribute_AttributeContainer AttributeContainer Attribute
40 * AttributeValue implementation for AttributeContainer
41 */
42
43class AttributeChecker;
44
45// A = attribute value type, C = container type to return
46/**
47 * \ingroup attribute_AttributeContainer
48 *
49 * A container for one type of attribute.
50 *
51 * The container uses \p A to parse items into elements.
52 * Internally the container is always a list but an instance
53 * can return the items in a container specified by \p C.
54 *
55 * @tparam A AttributeValue type to be contained.
56 * @tparam Sep Character separator between elements for parsing.
57 * @tparam C Possibly templated container class returned by Get.
58 */
59template <class A, char Sep = ',', template <class...> class C = std::list>
61{
62 public:
63 /** AttributeValue (element) type. */
64 typedef A attribute_type;
65 /** Type actually stored within the container. */
67 /** Internal container type. */
68 typedef std::list<value_type> container_type;
69 /** stl-style Const iterator type. */
70 typedef typename container_type::const_iterator const_iterator;
71 /** stl-style Non-const iterator type. */
72 typedef typename container_type::iterator iterator;
73 /** Size type for container. */
74 typedef typename container_type::size_type size_type;
75 /** NS3 style iterator type. */
77
78 // use underlying AttributeValue to get return element type
79 /** Item type of container returned by Get. */
80 typedef typename std::invoke_result_t<decltype(&A::Get), A> item_type;
81 /** Type of container returned. */
82 typedef C<item_type> result_type;
83
84 /**
85 * Default constructor.
86 */
88
89 /**
90 * Construct from another container.
91 * @tparam CONTAINER \deduced type of container passed for initialization.
92 * \param c Instance of CONTAINER with which to initialize AttributeContainerValue.
93 */
94 template <class CONTAINER>
95 AttributeContainerValue(const CONTAINER& c);
96
97 /**
98 * Construct from iterators.
99 * @tparam ITER \deduced type of iterator.
100 * \param[in] begin Iterator that points to first initialization item.
101 * \param[in] end Iterator that points ones past last initialization item.
102 */
103 template <class ITER>
104 AttributeContainerValue(const ITER begin, const ITER end);
105
106 /** Destructor. */
107 ~AttributeContainerValue() override;
108
109 // Inherited
110 Ptr<AttributeValue> Copy() const override;
111 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
112 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
113
114 // defacto pure virtuals to integrate with built-in accessor code
115 /**
116 * Return a container of items.
117 * \return Container of items.
118 */
119 result_type Get() const;
120 /**
121 * Copy items from container c.
122 *
123 * This method assumes \p c has stl-style begin and end methods.
124 * The AttributeContainerValue value is cleared before copying from \p c.
125 * @tparam T type of container.
126 * \param c Container from which to copy items.
127 */
128 template <class T>
129 void Set(const T& c);
130 /**
131 * Set the given variable to the values stored by this TupleValue object.
132 *
133 * \tparam T \deduced the type of the given variable (normally, the argument type
134 * of a set method or the type of a data member)
135 * \param value the given variable
136 * \return true if the given variable was set
137 */
138 template <typename T>
139 bool GetAccessor(T& value) const;
140
141 // NS3 interface
142 /**
143 * NS3-style Number of items.
144 * \return Number of items in container.
145 */
146 size_type GetN() const;
147 /**
148 * NS3-style beginning of container.
149 * \return Iterator pointing to first time in container.
150 */
151 Iterator Begin();
152 /**
153 * NS3-style ending of container.
154 * \return Iterator pointing one past last item of container.
155 */
156 Iterator End();
157
158 // STL-interface
159 /**
160 * STL-style number of items in container
161 * \return number of items in container.
162 */
163 size_type size() const;
164 /**
165 * STL-style beginning of container.
166 * \return Iterator pointing to first item in container.
167 */
168 iterator begin();
169 /**
170 * STL-style end of container.
171 * \return Iterator pointing to one past last item in container.
172 */
173 iterator end();
174 /**
175 * STL-style const beginning of container.
176 * \return Const iterator pointing to first item in container.
177 */
178 const_iterator begin() const;
179 /**
180 * STL-style const end of container.
181 * \return Const iterator pointing to one past last item in container.
182 */
183 const_iterator end() const;
184
185 private:
186 /**
187 * Copy items from \ref begin to \ref end.
188 *
189 * The internal container is cleared before values are copied
190 * using the push_back method.
191 * @tparam ITER \deduced iterator type
192 * \param[in] begin Points to first item to copy
193 * \param[in] end Points to one after last item to copy
194 * \return This object with items copied.
195 */
196 template <class ITER>
198
199 container_type m_container; //!< Internal container
200};
201
202/*!
203 * \ingroup attribute_AttributeContainer
204 *
205 * \class ns3::AttributeContainerChecker "attribute-container.h"
206 * AttributeChecker implementation for AttributeContainerValue.
207 * \see AttributeChecker
208 */
210{
211 public:
212 /**
213 * Set the item checker
214 * \param itemchecker The item checker
215 */
216 virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
217 /**
218 * Get the item checker
219 * \return The item checker
220 */
222};
223
224/**
225 * \ingroup attribute_AttributeContainer
226 *
227 * Make AttributeContainerChecker from AttributeContainerValue.
228 * @tparam A \deduced AttributeValue type in container.
229 * @tparam Sep \deduced Character separator between elements for parsing.
230 * @tparam C \deduced Container type returned by Get.
231 * \param[in] value AttributeContainerValue from which to deduce types.
232 * \return AttributeContainerChecker for value.
233 */
234template <class A, char Sep, template <class...> class C>
237
238/**
239 * \ingroup attribute_AttributeContainer
240 *
241 * Make AttributeContainerChecker using explicit types, initialize item checker.
242 * @tparam A AttributeValue type in container.
243 * @tparam Sep Character separator between elements for parsing.
244 * @tparam C Container type returned by Get.
245 * \param[in] itemchecker AttributeChecker used for each item in the container.
246 * \return AttributeContainerChecker.
247 */
248template <class A, char Sep = ',', template <class...> class C = std::list>
250
251/**
252 * \ingroup attribute_AttributeContainer
253 *
254 * Make uninitialized AttributeContainerChecker 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 * \return AttributeContainerChecker.
259 */
260template <class A, char Sep = ',', template <class...> class C = std::list>
262
263/**
264 * \ingroup attribute_AttributeContainer
265 *
266 * Make AttributeContainerAccessor using explicit types.
267 * @tparam A AttributeValue type in container.
268 * @tparam Sep Character separator between elements for parsing.
269 * @tparam C Container type returned by Get.
270 * \tparam T1 \deduced The type of the class data member,
271 * or the type of the class get functor or set method.
272 * \param [in] a1 The address of the data member,
273 * or the get or set method.
274 * \return AttributeContainerAccessor.
275 */
276template <typename A, char Sep = ',', template <typename...> class C = std::list, typename T1>
278
279/**
280 * \ingroup attribute_AttributeContainer
281 *
282 * Make AttributeContainerAccessor using explicit types.
283 * @tparam A AttributeValue type in container.
284 * @tparam Sep Character separator between elements for parsing.
285 * @tparam C Container type returned by Get.
286 * \tparam T1 \deduced The type of the class data member,
287 * or the type of the class get functor or set method.
288 *
289 * \tparam T2 \deduced The type of the getter class functor method.
290 * \param [in] a2 The address of the class method to set the attribute.
291 * \param [in] a1 The address of the data member,
292 * or the get or set method.
293 * \return AttributeContainerAccessor.
294 */
295template <typename A,
296 char Sep = ',',
297 template <typename...> class C = std::list,
298 typename T1,
299 typename T2>
301
302} // namespace ns3
303
304/*****************************************************************************
305 * Implementation below
306 *****************************************************************************/
307
308namespace ns3
309{
310
311namespace internal
312{
313
314/**
315 * \ingroup attribute_AttributeContainer
316 *
317 * \internal
318 *
319 * Templated AttributeContainerChecker class that is instantiated
320 * in MakeAttributeContainerChecker. The non-templated base ns3::AttributeContainerChecker
321 * is returned from that function. This is the same pattern as ObjectPtrContainer.
322 */
323template <class A, char Sep, template <class...> class C>
325{
326 public:
328 /**
329 * Explicit constructor
330 * \param itemchecker The AttributeChecker.
331 */
333 void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
335
336 private:
338};
339
340template <class A, char Sep, template <class...> class C>
342 : m_itemchecker(nullptr)
343{
344}
345
346template <class A, char Sep, template <class...> class C>
348 Ptr<const AttributeChecker> itemchecker)
349 : m_itemchecker(itemchecker)
350{
351}
352
353template <class A, char Sep, template <class...> class C>
354void
356{
357 m_itemchecker = itemchecker;
358}
359
360template <class A, char Sep, template <class...> class C>
363{
364 return m_itemchecker;
365}
366
367} // namespace internal
368
369template <class A, char Sep, template <class...> class C>
372{
373 return MakeAttributeContainerChecker<A, Sep, C>();
374}
375
376template <class A, char Sep, template <class...> class C>
377Ptr<const AttributeChecker>
379{
380 auto checker = MakeAttributeContainerChecker<A, Sep, C>();
381 auto acchecker = DynamicCast<AttributeContainerChecker>(checker);
382 acchecker->SetItemChecker(itemchecker);
383 return checker;
384}
385
386template <class A, char Sep, template <class...> class C>
387Ptr<AttributeChecker>
389{
390 std::string containerType;
391 std::string underlyingType;
393 {
394 std::ostringstream oss;
395 oss << "ns3::AttributeContainerValue<" << typeid(typename T::attribute_type).name() << ", "
396 << typeid(typename T::container_type).name() << ">";
397 containerType = oss.str();
398 }
399
400 {
401 std::ostringstream oss;
402 oss << "ns3::Ptr<" << typeid(typename T::attribute_type).name() << ">";
403 underlyingType = oss.str();
404 }
405
406 return MakeSimpleAttributeChecker<T, internal::AttributeContainerChecker<A, Sep, C>>(
407 containerType,
408 underlyingType);
409}
410
411template <class A, char Sep, template <class...> class C>
413{
414}
415
416template <class A, char Sep, template <class...> class C>
417template <class CONTAINER>
419 : AttributeContainerValue<A, Sep, C>(c.begin(), c.end())
420{
421}
422
423template <class A, char Sep, template <class...> class C>
424template <class ITER>
427{
429}
430
431template <class A, char Sep, template <class...> class C>
433{
434 m_container.clear();
435}
436
437template <class A, char Sep, template <class...> class C>
440{
441 auto c = Create<AttributeContainerValue<A, Sep, C>>();
442 c->m_container = m_container;
443 return c;
444}
445
446template <class A, char Sep, template <class...> class C>
447bool
450{
451 auto acchecker = DynamicCast<const AttributeContainerChecker>(checker);
452 if (!acchecker)
453 {
454 return false;
455 }
456
457 std::istringstream iss(value); // copies value
458 while (std::getline(iss, value, Sep))
459 {
460 auto avalue = acchecker->GetItemChecker()->CreateValidValue(StringValue(value));
461 if (!avalue)
462 {
463 return false;
464 }
465
466 auto attr = DynamicCast<A>(avalue);
467 if (!attr)
468 {
469 return false;
470 }
471
472 // TODO(jared): make insertion more generic?
473 m_container.push_back(attr);
474 }
475 return true;
476}
477
478template <class A, char Sep, template <class...> class C>
479std::string
481{
482 std::ostringstream oss;
483 bool first = true;
484 for (auto attr : *this)
485 {
486 if (!first)
487 {
488 oss << Sep;
489 }
490 oss << attr->SerializeToString(checker);
491 first = false;
492 }
493 return oss.str();
494}
495
496template <class A, char Sep, template <class...> class C>
499{
500 result_type c;
501 for (const value_type& a : *this)
502 {
503 c.insert(c.end(), a->Get());
504 }
505 return c;
506}
507
508template <class A, char Sep, template <class...> class C>
509template <typename T>
510bool
512{
513 result_type src = Get();
514 value.clear();
515 std::copy(src.begin(), src.end(), std::inserter(value, value.end()));
516 return true;
517}
518
519template <class A, char Sep, template <class...> class C>
520template <class T>
521void
523{
524 m_container.clear();
525 CopyFrom(c.begin(), c.end());
526}
527
528template <class A, char Sep, template <class...> class C>
531{
532 return size();
533}
534
535template <class A, char Sep, template <class...> class C>
538{
539 return begin();
540}
541
542template <class A, char Sep, template <class...> class C>
545{
546 return end();
547}
548
549template <class A, char Sep, template <class...> class C>
552{
553 return m_container.size();
554}
555
556template <class A, char Sep, template <class...> class C>
559{
560 return m_container.begin();
561}
562
563template <class A, char Sep, template <class...> class C>
566{
567 return m_container.end();
568}
569
570template <class A, char Sep, template <class...> class C>
573{
574 return m_container.cbegin();
575}
576
577template <class A, char Sep, template <class...> class C>
580{
581 return m_container.cend();
582}
583
584template <class A, char Sep, template <class...> class C>
585template <class ITER>
587AttributeContainerValue<A, Sep, C>::CopyFrom(const ITER begin, const ITER end)
588{
589 for (ITER iter = begin; iter != end; ++iter)
590 {
591 m_container.push_back(Create<A>(*iter));
592 }
593 return this;
594}
595
596template <typename A, char Sep, template <typename...> class C, typename T1>
599{
600 return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1);
601}
602
603template <typename A, char Sep, template <typename...> class C, typename T1, typename T2>
604Ptr<const AttributeAccessor>
606{
607 return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1, a2);
608}
609
610} // namespace ns3
611
612#endif // ATTRIBUTE_CONTAINER_H
Attribute helper (ATTRIBUTE_ )macros definition.
Represent the type of an attribute.
Definition: attribute.h:168
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:70
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
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.
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::StringValue attribute value declarations.