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::result_of<decltype(&A::Get)(A)>::type 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:
188  virtual void SetItemChecker (Ptr<const AttributeChecker> itemchecker) = 0;
189  virtual Ptr<const AttributeChecker> GetItemChecker (void) const = 0;
190 };
191 
199 template <class A, template <class...> class C>
202 
210 template <class A, template <class...> class C=std::list>
213 
220 template <class A, template <class...> class C=std::list>
222 
223 template <typename A, template <typename...> class C=std::list, typename T1>
225 
226 } // namespace ns3
227 
228 /*****************************************************************************
229  * Implementation below
230  *****************************************************************************/
231 
232 namespace ns3 {
233 
234 // This internal class defines templated AttributeContainerChecker class that is instantiated
235 // in MakeAttributeContainerChecker. The non-templated base ns3::AttributeContainerChecker
236 // is returned from that function. This is the same pattern as ObjectPtrContainer.
237 
238 namespace internal {
239 
240 template <class A, template <class...> class C>
242 {
243 public:
246  void SetItemChecker (Ptr<const AttributeChecker> itemchecker);
248 
249 private:
251 };
252 
253 template <class A, template <class...> class C>
255  : m_itemchecker (0)
256 {}
257 
258 template <class A, template <class...> class C>
260  : m_itemchecker (itemchecker)
261 {}
262 
263 template <class A, template <class...> class C>
264 void
266 {
267  m_itemchecker = itemchecker;
268 }
269 
270 template <class A, template <class...> class C>
273 {
274  return m_itemchecker;
275 }
276 
277 } // namespace internal
278 
279 template <class A, template <class...> class C>
282 {
283  return MakeAttributeContainerChecker <A, C> ();
284 }
285 
286 template <class A, template <class...> class C>
287 Ptr<const AttributeChecker>
289 {
290  auto checker = MakeAttributeContainerChecker <A, C> ();
291  auto acchecker = DynamicCast<AttributeContainerChecker> (checker);
292  acchecker->SetItemChecker (itemchecker);
293  return checker;
294 }
295 
296 template <class A, template <class...> class C>
297 Ptr<AttributeChecker>
299 {
300  std::string containerType;
301  std::string underlyingType;
303  {
304  std::ostringstream oss;
305  oss << "ns3::AttributeContainerValue<" << typeid (typename T::attribute_type).name ()
306  << ", " << typeid (typename T::container_type).name () << ">";
307  containerType = oss.str ();
308  }
309 
310  {
311  std::ostringstream oss;
312  oss << "ns3::Ptr<" << typeid (typename T::attribute_type).name () << ">";
313  underlyingType = oss.str ();
314  }
315 
316  return MakeSimpleAttributeChecker<T, internal::AttributeContainerChecker<A, C> > (containerType, underlyingType);
317 }
318 
319 template <class A, template <class...> class C>
321  : m_sep (sep)
322 {
323 
324 }
325 
326 template <class A, template <class...> class C>
327 template <class CONTAINER>
329  : AttributeContainerValue<A, C> (c.begin (), c.end ())
330 {
331 
332 }
333 
334 template <class A, template <class...> class C>
335 template <class ITER>
338 {
339  CopyFrom (begin, end);
340 }
341 
342 template <class A, template <class...> class C>
344 {
345  m_container.clear ();
346 }
347 
348 template <class A, template <class...> class C>
351 {
352  auto c = Create<AttributeContainerValue<A, C> > ();
353  c->m_sep = m_sep;
354  c->m_container = m_container;
355  return c;
356 }
357 
358 template <class A, template <class...> class C>
359 bool
361 {
362  auto acchecker = DynamicCast<const AttributeContainerChecker> (checker);
363  if (!acchecker) return false;
364 
365  std::istringstream iss (value); // copies value
366  while (std::getline (iss, value, m_sep))
367  {
368  auto avalue = acchecker->GetItemChecker ()->CreateValidValue (StringValue (value));
369  if (!avalue) return false;
370 
371  auto attr = DynamicCast <A> (avalue);
372  if (!attr) return false;
373 
374  // TODO(jared): make insertion more generic?
375  m_container.push_back (attr);
376  }
377  return true;
378 }
379 
380 template <class A, template <class...> class C>
381 std::string
383 {
384  std::ostringstream oss;
385  bool first = true;
386  for (auto attr: *this)
387  {
388  if (!first) oss << m_sep;
389  oss << attr->SerializeToString (checker);
390  first = false;
391  }
392  return oss.str ();
393 }
394 
395 template <class A, template <class...> class C>
398 {
399  result_type c;
400  for (const value_type& a: *this)
401  c.insert (c.end (), a->Get ());
402  return c;
403 }
404 
405 template <class A, template <class...> class C>
406 template <class T>
407 void
409 {
410  m_container.clear ();
411  CopyFrom (c.begin (), c.end ());
412 }
413 
414 template <class A, template <class...> class C>
417 {
418  return size ();
419 }
420 
421 template <class A, template <class...> class C>
424 {
425  return begin ();
426 }
427 
428 template <class A, template <class...> class C>
431 {
432  return end ();
433 }
434 
435 template <class A, template <class...> class C>
438 {
439  return m_container.size ();
440 }
441 
442 template <class A, template <class...> class C>
445 {
446  return m_container.begin ();
447 }
448 
449 template <class A, template <class...> class C>
452 {
453  return m_container.end ();
454 }
455 
456 template <class A, template <class...> class C>
459 {
460  return m_container.cbegin ();
461 }
462 
463 template <class A, template <class...> class C>
466 {
467  return m_container.cend ();
468 }
469 
470 template <class A, template <class...> class C>
471 template <class ITER>
473 AttributeContainerValue<A, C>::CopyFrom (const ITER begin, const ITER end)
474 {
475  for (ITER iter = begin; iter != end; ++iter)
476  {
477  m_container.push_back (Create<A> (*iter));
478  }
479  return this;
480 }
481 
482 template <typename A, template <typename...> class C, typename T1>
484 {
485  return MakeAccessorHelper<AttributeContainerValue<A, C> > (a1);
486 }
487 
488 } // namespace ns3
489 
490 #endif // ATTRIBUTE_CONTAINER_H
Represent the type of an attribute.
Definition: attribute.h:166
Iterator Begin(void)
NS3-style beginning of container.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
result_type Get(void) const
Return a container of items.
container_type::const_iterator const_iterator
stl-style Const iterator type.
Hold variables of type string.
Definition: string.h:41
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Hold a value for an Attribute.
Definition: attribute.h:68
AttributeChecker implementation for AttributeContainerValue.
bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker)
size_type GetN(void) const
NS3-style Number of items.
void SetItemChecker(Ptr< const AttributeChecker > itemchecker)
container_type::iterator iterator
stl-style Non-const iterator type.
Ptr< const AttributeChecker > m_itemchecker
container_type::size_type size_type
Size type for container.
size_type size(void) const
STL-style number of items in container.
iterator begin(void)
STL-style beginning of container.
A attribute_type
AttributeValue (element) type.
AttributeContainerValue(char sep=',')
Default constructor.
A container for one type of attribute.
void Set(const T &c)
Copy items from container c.
container_type m_container
Internal container.
#define list
virtual Ptr< const AttributeChecker > GetItemChecker(void) const =0
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void SetItemChecker(Ptr< const AttributeChecker > itemchecker)=0
Ptr< AttributeChecker > MakeAttributeContainerChecker(const AttributeContainerValue< A, C > &value)
Make AttributeContainerChecker from AttributeContainerValue.
Iterator End(void)
NS3-style ending of container.
std::string SerializeToString(Ptr< const AttributeChecker > checker) const
Ptr< AttributeValue > Copy(void) const
std::result_of< decltype(&A::Get)(A)>::type item_type
Item type of container returned by Get.
Ptr< const AttributeChecker > GetItemChecker(void) const
C< item_type > result_type
Type of container returned.
iterator end(void)
STL-style end of container.
Ptr< AttributeContainerValue< A, C > > CopyFrom(const ITER begin, const ITER end)
Copy items from begin to end.
Definition: first.py:1
std::list< value_type > container_type
Internal container type.
AttributeContainerValue::const_iterator Iterator
NS3 style iterator type.
Ptr< A > value_type
Type actually stored within the container.