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
35namespace ns3 {
36
37class AttributeChecker;
38
39// A = attribute value type, C = container type to return
50template <class A, template<class...> class C=std::list>
52{
53public:
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
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
167private:
178 template <class ITER>
179 Ptr<AttributeContainerValue<A, C> > CopyFrom (const ITER begin, const ITER end);
180
181 char m_sep;
183};
184
186{
187public:
192 virtual void SetItemChecker (Ptr<const AttributeChecker> itemchecker) = 0;
198};
199
207template <class A, template <class...> class C>
210
218template <class A, template <class...> class C=std::list>
221
228template <class A, template <class...> class C=std::list>
230
238template <typename A, template <typename...> class C=std::list, typename T1>
240
241} // namespace ns3
242
243/*****************************************************************************
244 * Implementation below
245 *****************************************************************************/
246
247namespace ns3 {
248
249namespace internal {
250
257template <class A, template <class...> class C>
259{
260public:
269
270private:
272};
273
274template <class A, template <class...> class C>
276 : m_itemchecker (0)
277{}
278
279template <class A, template <class...> class C>
281 : m_itemchecker (itemchecker)
282{}
283
284template <class A, template <class...> class C>
285void
287{
288 m_itemchecker = itemchecker;
289}
290
291template <class A, template <class...> class C>
294{
295 return m_itemchecker;
296}
297
298} // namespace internal
299
300template <class A, template <class...> class C>
303{
304 return MakeAttributeContainerChecker <A, C> ();
305}
306
307template <class A, template <class...> class C>
308Ptr<const AttributeChecker>
310{
311 auto checker = MakeAttributeContainerChecker <A, C> ();
312 auto acchecker = DynamicCast<AttributeContainerChecker> (checker);
313 acchecker->SetItemChecker (itemchecker);
314 return checker;
315}
316
317template <class A, template <class...> class C>
318Ptr<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
340template <class A, template <class...> class C>
342 : m_sep (sep)
343{
344
345}
346
347template <class A, template <class...> class C>
348template <class CONTAINER>
350 : AttributeContainerValue<A, C> (c.begin (), c.end ())
351{
352
353}
354
355template <class A, template <class...> class C>
356template <class ITER>
359{
360 CopyFrom (begin, end);
361}
362
363template <class A, template <class...> class C>
365{
366 m_container.clear ();
367}
368
369template <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
379template <class A, template <class...> class C>
380bool
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
401template <class A, template <class...> class C>
402std::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
416template <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
426template <class A, template <class...> class C>
427template <class T>
428void
430{
431 m_container.clear ();
432 CopyFrom (c.begin (), c.end ());
433}
434
435template <class A, template <class...> class C>
438{
439 return size ();
440}
441
442template <class A, template <class...> class C>
445{
446 return begin ();
447}
448
449template <class A, template <class...> class C>
452{
453 return end ();
454}
455
456template <class A, template <class...> class C>
459{
460 return m_container.size ();
461}
462
463template <class A, template <class...> class C>
466{
467 return m_container.begin ();
468}
469
470template <class A, template <class...> class C>
473{
474 return m_container.end ();
475}
476
477template <class A, template <class...> class C>
480{
481 return m_container.cbegin ();
482}
483
484template <class A, template <class...> class C>
487{
488 return m_container.cend ();
489}
490
491template <class A, template <class...> class C>
492template <class ITER>
494AttributeContainerValue<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
503template <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