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 <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
51template <class A, char Sep = ',', template <class...> class C = std::list>
53{
54 public:
56 typedef A attribute_type;
60 typedef std::list<value_type> container_type;
62 typedef typename container_type::const_iterator const_iterator;
64 typedef typename container_type::iterator iterator;
66 typedef typename container_type::size_type size_type;
69
70 // use underlying AttributeValue to get return element type
72 typedef typename std::invoke_result_t<decltype(&A::Get), A> item_type;
74 typedef C<item_type> result_type;
75
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>
190
192};
193
195{
196 public:
201 virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
207};
208
217template <class A, char Sep, template <class...> class C>
220
229template <class A, char Sep = ',', template <class...> class C = std::list>
231
239template <class A, char Sep = ',', template <class...> class C = std::list>
241
253template <typename A, char Sep = ',', template <typename...> class C = std::list, typename T1>
255
270template <typename A,
271 char Sep = ',',
272 template <typename...> class C = std::list,
273 typename T1,
274 typename T2>
276
277} // namespace ns3
278
279/*****************************************************************************
280 * Implementation below
281 *****************************************************************************/
282
283namespace ns3
284{
285
286namespace internal
287{
288
295template <class A, char Sep, template <class...> class C>
297{
298 public:
305 void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
307
308 private:
310};
311
312template <class A, char Sep, template <class...> class C>
314 : m_itemchecker(nullptr)
315{
316}
317
318template <class A, char Sep, template <class...> class C>
320 Ptr<const AttributeChecker> itemchecker)
321 : m_itemchecker(itemchecker)
322{
323}
324
325template <class A, char Sep, template <class...> class C>
326void
328{
329 m_itemchecker = itemchecker;
330}
331
332template <class A, char Sep, template <class...> class C>
335{
336 return m_itemchecker;
337}
338
339} // namespace internal
340
341template <class A, char Sep, template <class...> class C>
344{
345 return MakeAttributeContainerChecker<A, Sep, C>();
346}
347
348template <class A, char Sep, template <class...> class C>
349Ptr<const AttributeChecker>
351{
352 auto checker = MakeAttributeContainerChecker<A, Sep, C>();
353 auto acchecker = DynamicCast<AttributeContainerChecker>(checker);
354 acchecker->SetItemChecker(itemchecker);
355 return checker;
356}
357
358template <class A, char Sep, template <class...> class C>
359Ptr<AttributeChecker>
361{
362 std::string containerType;
363 std::string underlyingType;
365 {
366 std::ostringstream oss;
367 oss << "ns3::AttributeContainerValue<" << typeid(typename T::attribute_type).name() << ", "
368 << typeid(typename T::container_type).name() << ">";
369 containerType = oss.str();
370 }
371
372 {
373 std::ostringstream oss;
374 oss << "ns3::Ptr<" << typeid(typename T::attribute_type).name() << ">";
375 underlyingType = oss.str();
376 }
377
378 return MakeSimpleAttributeChecker<T, internal::AttributeContainerChecker<A, Sep, C>>(
379 containerType,
380 underlyingType);
381}
382
383template <class A, char Sep, template <class...> class C>
385{
386}
387
388template <class A, char Sep, template <class...> class C>
389template <class CONTAINER>
391 : AttributeContainerValue<A, Sep, C>(c.begin(), c.end())
392{
393}
394
395template <class A, char Sep, template <class...> class C>
396template <class ITER>
399{
401}
402
403template <class A, char Sep, template <class...> class C>
405{
406 m_container.clear();
407}
408
409template <class A, char Sep, template <class...> class C>
412{
413 auto c = Create<AttributeContainerValue<A, Sep, C>>();
414 c->m_container = m_container;
415 return c;
416}
417
418template <class A, char Sep, template <class...> class C>
419bool
422{
423 auto acchecker = DynamicCast<const AttributeContainerChecker>(checker);
424 if (!acchecker)
425 {
426 return false;
427 }
428
429 std::istringstream iss(value); // copies value
430 while (std::getline(iss, value, Sep))
431 {
432 auto avalue = acchecker->GetItemChecker()->CreateValidValue(StringValue(value));
433 if (!avalue)
434 {
435 return false;
436 }
437
438 auto attr = DynamicCast<A>(avalue);
439 if (!attr)
440 {
441 return false;
442 }
443
444 // TODO(jared): make insertion more generic?
445 m_container.push_back(attr);
446 }
447 return true;
448}
449
450template <class A, char Sep, template <class...> class C>
451std::string
453{
454 std::ostringstream oss;
455 bool first = true;
456 for (auto attr : *this)
457 {
458 if (!first)
459 {
460 oss << Sep;
461 }
462 oss << attr->SerializeToString(checker);
463 first = false;
464 }
465 return oss.str();
466}
467
468template <class A, char Sep, template <class...> class C>
471{
472 result_type c;
473 for (const value_type& a : *this)
474 {
475 c.insert(c.end(), a->Get());
476 }
477 return c;
478}
479
480template <class A, char Sep, template <class...> class C>
481template <typename T>
482bool
484{
485 result_type src = Get();
486 value.clear();
487 std::copy(src.begin(), src.end(), std::inserter(value, value.end()));
488 return true;
489}
490
491template <class A, char Sep, template <class...> class C>
492template <class T>
493void
495{
496 m_container.clear();
497 CopyFrom(c.begin(), c.end());
498}
499
500template <class A, char Sep, template <class...> class C>
503{
504 return size();
505}
506
507template <class A, char Sep, template <class...> class C>
510{
511 return begin();
512}
513
514template <class A, char Sep, template <class...> class C>
517{
518 return end();
519}
520
521template <class A, char Sep, template <class...> class C>
524{
525 return m_container.size();
526}
527
528template <class A, char Sep, template <class...> class C>
531{
532 return m_container.begin();
533}
534
535template <class A, char Sep, template <class...> class C>
538{
539 return m_container.end();
540}
541
542template <class A, char Sep, template <class...> class C>
545{
546 return m_container.cbegin();
547}
548
549template <class A, char Sep, template <class...> class C>
552{
553 return m_container.cend();
554}
555
556template <class A, char Sep, template <class...> class C>
557template <class ITER>
559AttributeContainerValue<A, Sep, C>::CopyFrom(const ITER begin, const ITER end)
560{
561 for (ITER iter = begin; iter != end; ++iter)
562 {
563 m_container.push_back(Create<A>(*iter));
564 }
565 return this;
566}
567
568template <typename A, char Sep, template <typename...> class C, typename T1>
571{
572 return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1);
573}
574
575template <typename A, char Sep, template <typename...> class C, typename T1, typename T2>
576Ptr<const AttributeAccessor>
578{
579 return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1, a2);
580}
581
582} // namespace ns3
583
584#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.
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:78
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.
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< AttributeChecker > MakeAttributeContainerChecker()
Make uninitialized AttributeContainerChecker using explicit types.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.