A Discrete-Event Network Simulator
API
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 <ns3/attribute-helper.h>
24#include <ns3/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
37class AttributeChecker;
38
39// A = attribute value type, C = container type to return
50template <class A, template <class...> class C = std::list>
52{
53 public:
55 typedef A attribute_type;
59 typedef std::list<value_type> container_type;
61 typedef typename container_type::const_iterator const_iterator;
63 typedef typename container_type::iterator iterator;
65 typedef typename container_type::size_type size_type;
68
69 // use underlying AttributeValue to get return element type
71 typedef typename std::invoke_result_t<decltype(&A::Get), A> item_type;
73 typedef C<item_type> result_type;
74
79 AttributeContainerValue(char sep = ',');
80
86 template <class CONTAINER>
87 AttributeContainerValue(const CONTAINER& c);
88
95 template <class ITER>
96 AttributeContainerValue(const ITER begin, const ITER end);
97
99 ~AttributeContainerValue() override;
100
101 // Inherited
102 Ptr<AttributeValue> Copy() const override;
103 bool DeserializeFromString(std::string value, Ptr<const AttributeChecker> checker) override;
104 std::string SerializeToString(Ptr<const AttributeChecker> checker) const override;
105
106 // defacto pure virtuals to integrate with built-in accessor code
111 result_type Get() const;
120 template <class T>
121 void Set(const T& c);
130 template <typename T>
131 bool GetAccessor(T& value) const;
132
133 // NS3 interface
138 size_type GetN() const;
143 Iterator Begin();
148 Iterator End();
149
150 // STL-interface
155 size_type size() const;
160 iterator begin();
165 iterator end();
170 const_iterator begin() const;
175 const_iterator end() const;
176
177 private:
188 template <class ITER>
189 Ptr<AttributeContainerValue<A, C>> CopyFrom(const ITER begin, const ITER end);
190
191 char m_sep;
193};
194
196{
197 public:
202 virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
208};
209
217template <class A, template <class...> class C>
219
227template <class A, template <class...> class C = std::list>
229
236template <class A, template <class...> class C = std::list>
238
249template <typename A, template <typename...> class C = std::list, typename T1>
251
265template <typename A, template <typename...> class C = std::list, typename T1, typename T2>
267
268} // namespace ns3
269
270/*****************************************************************************
271 * Implementation below
272 *****************************************************************************/
273
274namespace ns3
275{
276
277namespace internal
278{
279
286template <class A, template <class...> class C>
288{
289 public:
296 void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
298
299 private:
301};
302
303template <class A, template <class...> class C>
305 : m_itemchecker(nullptr)
306{
307}
308
309template <class A, template <class...> class C>
311 : m_itemchecker(itemchecker)
312{
313}
314
315template <class A, template <class...> class C>
316void
318{
319 m_itemchecker = itemchecker;
320}
321
322template <class A, template <class...> class C>
325{
326 return m_itemchecker;
327}
328
329} // namespace internal
330
331template <class A, template <class...> class C>
334{
335 return MakeAttributeContainerChecker<A, C>();
336}
337
338template <class A, template <class...> class C>
339Ptr<const AttributeChecker>
341{
342 auto checker = MakeAttributeContainerChecker<A, C>();
343 auto acchecker = DynamicCast<AttributeContainerChecker>(checker);
344 acchecker->SetItemChecker(itemchecker);
345 return checker;
346}
347
348template <class A, template <class...> class C>
349Ptr<AttributeChecker>
351{
352 std::string containerType;
353 std::string underlyingType;
355 {
356 std::ostringstream oss;
357 oss << "ns3::AttributeContainerValue<" << typeid(typename T::attribute_type).name() << ", "
358 << typeid(typename T::container_type).name() << ">";
359 containerType = oss.str();
360 }
361
362 {
363 std::ostringstream oss;
364 oss << "ns3::Ptr<" << typeid(typename T::attribute_type).name() << ">";
365 underlyingType = oss.str();
366 }
367
368 return MakeSimpleAttributeChecker<T, internal::AttributeContainerChecker<A, C>>(containerType,
369 underlyingType);
370}
371
372template <class A, template <class...> class C>
374 : m_sep(sep)
375{
376}
377
378template <class A, template <class...> class C>
379template <class CONTAINER>
381 : AttributeContainerValue<A, C>(c.begin(), c.end())
382{
383}
384
385template <class A, template <class...> class C>
386template <class ITER>
389{
391}
392
393template <class A, template <class...> class C>
395{
396 m_container.clear();
397}
398
399template <class A, template <class...> class C>
402{
403 auto c = Create<AttributeContainerValue<A, C>>();
404 c->m_sep = m_sep;
405 c->m_container = m_container;
406 return c;
407}
408
409template <class A, template <class...> class C>
410bool
413{
414 auto acchecker = DynamicCast<const AttributeContainerChecker>(checker);
415 if (!acchecker)
416 {
417 return false;
418 }
419
420 std::istringstream iss(value); // copies value
421 while (std::getline(iss, value, m_sep))
422 {
423 auto avalue = acchecker->GetItemChecker()->CreateValidValue(StringValue(value));
424 if (!avalue)
425 {
426 return false;
427 }
428
429 auto attr = DynamicCast<A>(avalue);
430 if (!attr)
431 {
432 return false;
433 }
434
435 // TODO(jared): make insertion more generic?
436 m_container.push_back(attr);
437 }
438 return true;
439}
440
441template <class A, template <class...> class C>
442std::string
444{
445 std::ostringstream oss;
446 bool first = true;
447 for (auto attr : *this)
448 {
449 if (!first)
450 {
451 oss << m_sep;
452 }
453 oss << attr->SerializeToString(checker);
454 first = false;
455 }
456 return oss.str();
457}
458
459template <class A, template <class...> class C>
462{
463 result_type c;
464 for (const value_type& a : *this)
465 {
466 c.insert(c.end(), a->Get());
467 }
468 return c;
469}
470
471template <class A, template <class...> class C>
472template <typename T>
473bool
475{
476 result_type src = Get();
477 value.clear();
478 std::copy(src.begin(), src.end(), std::inserter(value, value.end()));
479 return true;
480}
481
482template <class A, template <class...> class C>
483template <class T>
484void
486{
487 m_container.clear();
488 CopyFrom(c.begin(), c.end());
489}
490
491template <class A, template <class...> class C>
494{
495 return size();
496}
497
498template <class A, template <class...> class C>
501{
502 return begin();
503}
504
505template <class A, template <class...> class C>
508{
509 return end();
510}
511
512template <class A, template <class...> class C>
515{
516 return m_container.size();
517}
518
519template <class A, template <class...> class C>
522{
523 return m_container.begin();
524}
525
526template <class A, template <class...> class C>
529{
530 return m_container.end();
531}
532
533template <class A, template <class...> class C>
536{
537 return m_container.cbegin();
538}
539
540template <class A, template <class...> class C>
543{
544 return m_container.cend();
545}
546
547template <class A, template <class...> class C>
548template <class ITER>
550AttributeContainerValue<A, C>::CopyFrom(const ITER begin, const ITER end)
551{
552 for (ITER iter = begin; iter != end; ++iter)
553 {
554 m_container.push_back(Create<A>(*iter));
555 }
556 return this;
557}
558
559template <typename A, template <typename...> class C, typename T1>
562{
563 return MakeAccessorHelper<AttributeContainerValue<A, C>>(a1);
564}
565
566template <typename A, template <typename...> class C, typename T1, typename T2>
567Ptr<const AttributeAccessor>
569{
570 return MakeAccessorHelper<AttributeContainerValue<A, C>>(a1, a2);
571}
572
573} // namespace ns3
574
575#endif // ATTRIBUTE_CONTAINER_H
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.
result_type Get() const
Return a container of items.
Ptr< A > value_type
Type actually stored within the container.
void Set(const T &c)
Copy items from container c.
container_type::size_type size_type
Size type for container.
std::invoke_result_t< decltype(&A::Get), A > item_type
Item type of container returned by Get.
std::list< value_type > container_type
Internal container type.
container_type m_container
Internal container.
container_type::iterator iterator
stl-style Non-const iterator type.
~AttributeContainerValue() override
Destructor.
Iterator Begin()
NS3-style beginning of container.
iterator end()
STL-style end of container.
A attribute_type
AttributeValue (element) type.
std::string SerializeToString(Ptr< const AttributeChecker > checker) const override
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker) override
AttributeContainerValue(char sep=',')
Default constructor.
C< item_type > result_type
Type of container returned.
bool GetAccessor(T &value) const
Set the given variable to the values stored by this TupleValue object.
container_type::const_iterator const_iterator
stl-style Const iterator type.
Ptr< AttributeContainerValue< A, C > > CopyFrom(const ITER begin, const ITER end)
Copy items from begin to end.
size_type GetN() const
NS3-style Number of items.
iterator begin()
STL-style beginning of container.
AttributeContainerValue::const_iterator Iterator
NS3 style iterator type.
Ptr< AttributeValue > Copy() const override
Iterator End()
NS3-style ending of container.
size_type size() const
STL-style number of items in container.
Hold a value for an Attribute.
Definition: attribute.h:70
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Hold variables of type string.
Definition: string.h:42
Ptr< const AttributeChecker > m_itemchecker
The AttributeChecker.
void SetItemChecker(Ptr< const AttributeChecker > itemchecker) override
Set the item checker.
Ptr< const AttributeChecker > GetItemChecker() const override
Get the item checker.
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< AttributeChecker > MakeAttributeContainerChecker(const AttributeContainerValue< A, C > &value)
Make AttributeContainerChecker from AttributeContainerValue.
value
Definition: second.py:41
#define list