A Discrete-Event Network Simulator
API
attribute-container.h
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018 Caliola Engineering, LLC.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Jared Dulmage <jared.dulmage@caliola.com>
19  */
20 
21 #ifndef ATTRIBUTE_CONTAINER_H
22 #define ATTRIBUTE_CONTAINER_H
23 
24 #include <ns3/attribute-helper.h>
25 #include <ns3/string.h>
26 
27 #include <list>
28 #include <algorithm>
29 #include <iterator>
30 #include <sstream>
31 #include <typeinfo>
32 #include <type_traits>
33 #include <utility>
34 
35 namespace ns3 {
36 
37 class AttributeChecker;
38 
39 // A = attribute value type, C = container type to return
50 template <class A, template<class...> class C=std::list>
52 {
53 public:
55  typedef A attribute_type;
57  typedef Ptr<A> value_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;
67  typedef typename AttributeContainerValue::const_iterator Iterator; // NS3 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 
100 
101  // Inherited
102  Ptr<AttributeValue> Copy (void) const;
103  bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
104  std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
105 
106  // defacto pure virtuals to integrate with built-in accessor code
111  result_type Get (void) const;
120  template <class T>
121  void Set (const T &c);
122 
123  // NS3 interface
128  size_type GetN (void) const;
133  Iterator Begin (void);
138  Iterator End (void);
139 
140  // STL-interface
145  size_type size (void) const;
150  iterator begin (void);
155  iterator end (void);
160  const_iterator begin (void) const;
165  const_iterator end (void) const;
166 
167 private:
178  template <class ITER>
179  Ptr<AttributeContainerValue<A, C> > CopyFrom (const ITER begin, const ITER end);
180 
181  char m_sep;
183 };
184 
186 {
187 public:
192  virtual void SetItemChecker (Ptr<const AttributeChecker> itemchecker) = 0;
197  virtual Ptr<const AttributeChecker> GetItemChecker (void) const = 0;
198 };
199 
207 template <class A, template <class...> class C>
210 
218 template <class A, template <class...> class C=std::list>
221 
228 template <class A, template <class...> class C=std::list>
230 
238 template <typename A, template <typename...> class C=std::list, typename T1>
240 
241 } // namespace ns3
242 
243 /*****************************************************************************
244  * Implementation below
245  *****************************************************************************/
246 
247 namespace ns3 {
248 
249 namespace internal {
250 
257 template <class A, template <class...> class C>
259 {
260 public:
267  void SetItemChecker (Ptr<const AttributeChecker> itemchecker);
269 
270 private:
272 };
273 
274 template <class A, template <class...> class C>
276  : m_itemchecker (0)
277 {}
278 
279 template <class A, template <class...> class C>
281  : m_itemchecker (itemchecker)
282 {}
283 
284 template <class A, template <class...> class C>
285 void
287 {
288  m_itemchecker = itemchecker;
289 }
290 
291 template <class A, template <class...> class C>
294 {
295  return m_itemchecker;
296 }
297 
298 } // namespace internal
299 
300 template <class A, template <class...> class C>
303 {
304  return MakeAttributeContainerChecker <A, C> ();
305 }
306 
307 template <class A, template <class...> class C>
308 Ptr<const AttributeChecker>
310 {
311  auto checker = MakeAttributeContainerChecker <A, C> ();
312  auto acchecker = DynamicCast<AttributeContainerChecker> (checker);
313  acchecker->SetItemChecker (itemchecker);
314  return checker;
315 }
316 
317 template <class A, template <class...> class C>
318 Ptr<AttributeChecker>
320 {
321  std::string containerType;
322  std::string underlyingType;
324  {
325  std::ostringstream oss;
326  oss << "ns3::AttributeContainerValue<" << typeid (typename T::attribute_type).name ()
327  << ", " << typeid (typename T::container_type).name () << ">";
328  containerType = oss.str ();
329  }
330 
331  {
332  std::ostringstream oss;
333  oss << "ns3::Ptr<" << typeid (typename T::attribute_type).name () << ">";
334  underlyingType = oss.str ();
335  }
336 
337  return MakeSimpleAttributeChecker<T, internal::AttributeContainerChecker<A, C> > (containerType, underlyingType);
338 }
339 
340 template <class A, template <class...> class C>
342  : m_sep (sep)
343 {
344 
345 }
346 
347 template <class A, template <class...> class C>
348 template <class CONTAINER>
350  : AttributeContainerValue<A, C> (c.begin (), c.end ())
351 {
352 
353 }
354 
355 template <class A, template <class...> class C>
356 template <class ITER>
359 {
360  CopyFrom (begin, end);
361 }
362 
363 template <class A, template <class...> class C>
365 {
366  m_container.clear ();
367 }
368 
369 template <class A, template <class...> class C>
372 {
373  auto c = Create<AttributeContainerValue<A, C> > ();
374  c->m_sep = m_sep;
375  c->m_container = m_container;
376  return c;
377 }
378 
379 template <class A, template <class...> class C>
380 bool
382 {
383  auto acchecker = DynamicCast<const AttributeContainerChecker> (checker);
384  if (!acchecker) return false;
385 
386  std::istringstream iss (value); // copies value
387  while (std::getline (iss, value, m_sep))
388  {
389  auto avalue = acchecker->GetItemChecker ()->CreateValidValue (StringValue (value));
390  if (!avalue) return false;
391 
392  auto attr = DynamicCast <A> (avalue);
393  if (!attr) return false;
394 
395  // TODO(jared): make insertion more generic?
396  m_container.push_back (attr);
397  }
398  return true;
399 }
400 
401 template <class A, template <class...> class C>
402 std::string
404 {
405  std::ostringstream oss;
406  bool first = true;
407  for (auto attr: *this)
408  {
409  if (!first) oss << m_sep;
410  oss << attr->SerializeToString (checker);
411  first = false;
412  }
413  return oss.str ();
414 }
415 
416 template <class A, template <class...> class C>
419 {
420  result_type c;
421  for (const value_type& a: *this)
422  c.insert (c.end (), a->Get ());
423  return c;
424 }
425 
426 template <class A, template <class...> class C>
427 template <class T>
428 void
430 {
431  m_container.clear ();
432  CopyFrom (c.begin (), c.end ());
433 }
434 
435 template <class A, template <class...> class C>
438 {
439  return size ();
440 }
441 
442 template <class A, template <class...> class C>
445 {
446  return begin ();
447 }
448 
449 template <class A, template <class...> class C>
452 {
453  return end ();
454 }
455 
456 template <class A, template <class...> class C>
459 {
460  return m_container.size ();
461 }
462 
463 template <class A, template <class...> class C>
466 {
467  return m_container.begin ();
468 }
469 
470 template <class A, template <class...> class C>
473 {
474  return m_container.end ();
475 }
476 
477 template <class A, template <class...> class C>
480 {
481  return m_container.cbegin ();
482 }
483 
484 template <class A, template <class...> class C>
487 {
488  return m_container.cend ();
489 }
490 
491 template <class A, template <class...> class C>
492 template <class ITER>
494 AttributeContainerValue<A, C>::CopyFrom (const ITER begin, const ITER end)
495 {
496  for (ITER iter = begin; iter != end; ++iter)
497  {
498  m_container.push_back (Create<A> (*iter));
499  }
500  return this;
501 }
502 
503 template <typename A, template <typename...> class C, typename T1>
505 {
506  return MakeAccessorHelper<AttributeContainerValue<A, C> > (a1);
507 }
508 
509 } // namespace ns3
510 
511 #endif // ATTRIBUTE_CONTAINER_H
Represent the type of an attribute.
Definition: attribute.h:167
AttributeChecker implementation for AttributeContainerValue.
virtual Ptr< const AttributeChecker > GetItemChecker(void) 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.
std::string SerializeToString(Ptr< const AttributeChecker > checker) const
Ptr< A > value_type
Type actually stored within the container.
void Set(const T &c)
Copy items from container c.
result_type Get(void) const
Return a container of items.
Iterator End(void)
NS3-style ending of container.
Ptr< AttributeValue > Copy(void) const
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.
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker)
container_type m_container
Internal container.
size_type GetN(void) const
NS3-style Number of items.
container_type::iterator iterator
stl-style Non-const iterator type.
size_type size(void) const
STL-style number of items in container.
iterator end(void)
STL-style end of container.
A attribute_type
AttributeValue (element) type.
Iterator Begin(void)
NS3-style beginning of container.
AttributeContainerValue(char sep=',')
Default constructor.
C< item_type > result_type
Type of container returned.
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.
iterator begin(void)
STL-style beginning of container.
AttributeContainerValue::const_iterator Iterator
NS3 style iterator type.
Hold a value for an Attribute.
Definition: attribute.h:69
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Hold variables of type string.
Definition: string.h:41
Ptr< const AttributeChecker > m_itemchecker
The AttributeChecker.
Ptr< const AttributeChecker > GetItemChecker(void) const
Get the item checker.
void SetItemChecker(Ptr< const AttributeChecker > itemchecker)
Set 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.
#define list