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 "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 
34 namespace ns3
35 {
36 
37 class AttributeChecker;
38 
39 // A = attribute value type, C = container type to return
51 template <class A, char Sep = ',', template <class...> class C = std::list>
53 {
54  public:
56  typedef A attribute_type;
58  typedef Ptr<A> value_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;
68  typedef typename AttributeContainerValue::const_iterator Iterator; // NS3 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>
189  Ptr<AttributeContainerValue<A, Sep, C>> CopyFrom(const ITER begin, const ITER end);
190 
192 };
193 
195 {
196  public:
201  virtual void SetItemChecker(Ptr<const AttributeChecker> itemchecker) = 0;
207 };
208 
217 template <class A, char Sep, template <class...> class C>
220 
229 template <class A, char Sep = ',', template <class...> class C = std::list>
231 
239 template <class A, char Sep = ',', template <class...> class C = std::list>
241 
253 template <typename A, char Sep = ',', template <typename...> class C = std::list, typename T1>
255 
270 template <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 
283 namespace ns3
284 {
285 
286 namespace internal
287 {
288 
295 template <class A, char Sep, template <class...> class C>
297 {
298  public:
305  void SetItemChecker(Ptr<const AttributeChecker> itemchecker) override;
307 
308  private:
310 };
311 
312 template <class A, char Sep, template <class...> class C>
314  : m_itemchecker(nullptr)
315 {
316 }
317 
318 template <class A, char Sep, template <class...> class C>
320  Ptr<const AttributeChecker> itemchecker)
321  : m_itemchecker(itemchecker)
322 {
323 }
324 
325 template <class A, char Sep, template <class...> class C>
326 void
328 {
329  m_itemchecker = itemchecker;
330 }
331 
332 template <class A, char Sep, template <class...> class C>
335 {
336  return m_itemchecker;
337 }
338 
339 } // namespace internal
340 
341 template <class A, char Sep, template <class...> class C>
344 {
345  return MakeAttributeContainerChecker<A, Sep, C>();
346 }
347 
348 template <class A, char Sep, template <class...> class C>
349 Ptr<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 
358 template <class A, char Sep, template <class...> class C>
359 Ptr<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 
383 template <class A, char Sep, template <class...> class C>
385 {
386 }
387 
388 template <class A, char Sep, template <class...> class C>
389 template <class CONTAINER>
391  : AttributeContainerValue<A, Sep, C>(c.begin(), c.end())
392 {
393 }
394 
395 template <class A, char Sep, template <class...> class C>
396 template <class ITER>
399 {
400  CopyFrom(begin, end);
401 }
402 
403 template <class A, char Sep, template <class...> class C>
405 {
406  m_container.clear();
407 }
408 
409 template <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 
418 template <class A, char Sep, template <class...> class C>
419 bool
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 
450 template <class A, char Sep, template <class...> class C>
451 std::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 
468 template <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 
480 template <class A, char Sep, template <class...> class C>
481 template <typename T>
482 bool
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 
491 template <class A, char Sep, template <class...> class C>
492 template <class T>
493 void
495 {
496  m_container.clear();
497  CopyFrom(c.begin(), c.end());
498 }
499 
500 template <class A, char Sep, template <class...> class C>
503 {
504  return size();
505 }
506 
507 template <class A, char Sep, template <class...> class C>
510 {
511  return begin();
512 }
513 
514 template <class A, char Sep, template <class...> class C>
517 {
518  return end();
519 }
520 
521 template <class A, char Sep, template <class...> class C>
524 {
525  return m_container.size();
526 }
527 
528 template <class A, char Sep, template <class...> class C>
531 {
532  return m_container.begin();
533 }
534 
535 template <class A, char Sep, template <class...> class C>
538 {
539  return m_container.end();
540 }
541 
542 template <class A, char Sep, template <class...> class C>
545 {
546  return m_container.cbegin();
547 }
548 
549 template <class A, char Sep, template <class...> class C>
552 {
553  return m_container.cend();
554 }
555 
556 template <class A, char Sep, template <class...> class C>
557 template <class ITER>
559 AttributeContainerValue<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 
568 template <typename A, char Sep, template <typename...> class C, typename T1>
571 {
572  return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1);
573 }
574 
575 template <typename A, char Sep, template <typename...> class C, typename T1, typename T2>
576 Ptr<const AttributeAccessor>
578 {
579  return MakeAccessorHelper<AttributeContainerValue<A, Sep, C>>(a1, a2);
580 }
581 
582 } // namespace ns3
583 
584 #endif // ATTRIBUTE_CONTAINER_H
Attribute helper (ATTRIBUTE_ )macros definition.
Represent the type of an attribute.
Definition: attribute.h:168
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.
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< AttributeChecker > MakeAttributeContainerChecker(const AttributeContainerValue< A, Sep, C > &value)
Make AttributeContainerChecker from AttributeContainerValue.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
#define list
ns3::StringValue attribute value declarations.